A cross-platform design system for the World ecosystem.
Source layers are explicit in token paths – token definitions use primitive.color.* and semantic.color.* roots, so layer identity lives in the token schema instead of the folder structure.
Primitive and semantic colors are exported – Primitive values remain public, and light/dark semantic layers now build as separate themed outputs.
Platform outputs are standalone – no dependency on app-specific types. Android gets Compose Color objects; iOS gets raw hex String constants; Web gets CSS custom properties and JSON files. The consuming app bridges these to its own types.
graph TD
A[JSON Token Definitions] --> B[Style Dictionary]
B --> C[Custom Formats]
C -->|Gradle templates| D[Android]
C -->|SPM templates| E[iOS]
C -->|npm templates| F[Web]
npm ci
npm run buildGenerated files appear in build/:
| Platform | Path | Contents |
|---|---|---|
| Android | build/android/ |
Kotlin objects with Compose Color values, build.gradle.kts for Maven publishing |
| iOS | build/ios/ |
Standalone Swift enums with hex string constants, Package.swift for SPM |
| Web | build/web/ |
CSS custom properties, JSON token files, package.json for npm publishing |
Release versioning lives in the repo root VERSION file. npm run build stamps that value into the generated Android and Web package metadata.
| Path | Description |
|---|---|
src/tokens/color/primitive.json |
Primitive color tokens under primitive.color.* |
src/tokens/color/semantic.light.json |
Light semantic color tokens under semantic.color.* |
src/tokens/color/semantic.dark.json |
Dark semantic color tokens under semantic.color.* |
NucleusPrimitiveColors– Primitive colors asColorobjectsNucleusSemanticColorsLight– Light semantic colors asColorobjectsNucleusSemanticColorsDark– Dark semantic colors asColorobjects
NucleusPrimitiveColors– Primitive colors as hexStringconstantsNucleusSemanticColorsLight– Light semantic colors as hexStringconstantsNucleusSemanticColorsDark– Dark semantic colors as hexStringconstants
nucleus-primitive-colors.css– Primitive colors as CSS custom properties (--nucleus-*)nucleus-primitive-colors.json– JSON token file for programmatic usenucleus-semantic-colors-light.css/nucleus-semantic-colors-dark.css– Theme-specific semantic CSS custom propertiesnucleus-semantic-colors-light.json/nucleus-semantic-colors-dark.json– Theme-specific semantic JSON token files
examples/android/– Android demo app withlocalandpackageflavorsexamples/ios/– iOS demo app withLocalandPackageschemesexamples/web/– Next.js demo app withlocalandpackagetoken sources
Release automation is split across two workflows:
.github/workflows/prepare-release.ymlprepares release PRs.github/workflows/publish-release.ymltags and publishes merged release PRs
The prepare workflow supports two trigger modes:
- Push to
mainafter a merged PR with a release label (major,minor,patch) – the workflow derives the bump from the merged PR, creates arelease/v*branch, and opens a release PR - Manual dispatch – choose the bump type from the Actions UI to create the same release PR flow without a source PR label
- release PR creation –
prepare-release.ymldetermines the next version, updatesVERSION,package.json,package-lock.json, andCHANGELOG.md, then opens arelease/v*PR againstmain - release PR merge – Merging that PR back into
maintriggerspublish-release.yml - tag + build – The merged release commit is tagged as
v*, thennpm run buildruns and uploadsandroid-tokens,ios-tokens, andweb-tokens - publish-mvn – Publishes Android library to GitHub Packages
- publish-spm – Commits generated iOS files to the
generated/iosbranch, tags asv*-ios - publish-npm – Publishes Web package to GitHub Packages npm registry
The verification workflow lives in .github/workflows/verify.yml and runs format:check, lint, typecheck, and build on pushes to main and pull requests.
Add the GitHub Packages Maven repository to settings.gradle:
maven {
url = uri("https://maven.pkg.github.com/worldcoin/nucleus")
credentials {
username = System.getenv("GITHUB_USER")
password = System.getenv("GITHUB_TOKEN")
}
}Then add the dependency:
implementation "com.worldcoin:nucleus:<version>"Access primitive colors via NucleusPrimitiveColors.
Add the SPM dependency in your Package.swift:
.package(url: "https://github.com/worldcoin/nucleus.git", branch: "generated/ios")Or pin to a specific release tag (for example, vX.Y.Z-ios).
Then add Nucleus as a dependency on your target:
.target(
name: "YourTarget",
dependencies: [
.product(name: "Nucleus", package: "nucleus"),
]
)Access primitive colors as hex strings:
import Nucleus
let hex = NucleusPrimitiveColors.grey900 // "181818"Add a .npmrc to your project:
@worldcoin:registry=https://npm.pkg.github.com
Then install the package:
npm install @worldcoin/nucleusThe published package includes the generated CSS, JSON, and index.d.ts files from build/web.
CSS custom properties – import the stylesheet:
@import "@worldcoin/nucleus/nucleus-primitive-colors.css";Then use the variables:
.card {
color: var(--nucleus-grey-900);
border: 1px solid var(--nucleus-grey-200);
}JSON tokens – import directly for JS/TS usage:
import tokens from "@worldcoin/nucleus/nucleus-primitive-colors.json";- Edit the relevant JSON file in
src/tokens/ - Run
npm run buildto verify output - Open a PR with a release label (
patch,minor, ormajor) - On merge to
main, CI opens arelease/v*PR with the version and changelog updates - Merge that release PR to trigger tagging and publication