Skip to content

Installation

Clients consume Nockerl Design as versioned packages. They never copy values in by hand. Pin a version, upgrade deliberately, and a remodel in the framework reaches you on the next bump. All three platforms ship from one version line (currently 2.0.0): the web npm packages, the Android Maven artifacts, and the Swift package are published in lockstep from the same vX.Y.Z tag.

Platform Tokens Components Registry
Web @dizyx/nockerl-tokens @dizyx/nockerl-react GitHub Packages (npm)
Android com.dizyx.nockerl:design-tokens com.dizyx.nockerl:design-components GitHub Packages (Maven)
Swift NockerlDesign (tokens) NockerlDesign (views) Swift Package Manager (git tag)

The web build ships as two published npm packages on GitHub Packages (scope @dizyx): @dizyx/nockerl-tokens (the CSS custom properties) and @dizyx/nockerl-react (the React components). You need a one-line registry config and a GitHub token with read:packages before installing.

  1. Point the @dizyx scope at GitHub Packages. Add an .npmrc to your project (or ~/.npmrc):

    .npmrc
    @dizyx:registry=https://npm.pkg.github.com
    //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}

    GITHUB_TOKEN is read from the environment, a classic PAT (or fine-grained token) with read:packages. Never commit the token; keep it in the environment or a secret store. In CI, the Actions GITHUB_TOKEN already has packages: read.

  2. Install the packages with Bun (the Nockerl default runtime):

    Terminal window
    bun add @dizyx/nockerl-react @dizyx/nockerl-tokens

    react (>=19) is a peer dependency: the components use React 19 APIs (useId and friends) and read your app’s copy of React. Tokens-only consumers can install just @dizyx/nockerl-tokens.

  3. Import the CSS variables once, at your app’s style entry point:

    src/styles/global.css
    @import '@dizyx/nockerl-tokens/tokens.css';

    This defines the full token set as CSS custom properties (--color-*, --space-*, --radius-*, --font-*, --elevation-*, and the typography ramp) under :root (light) and .dark (dark).

  4. Load the brand fonts. The tokens name Outfit (--font-family-sans) and Space Mono (--font-family-mono), but a token file cannot ship a typeface. Load the fonts yourself once, or every surface silently falls back to system fonts. Self-host with Fontsource (no CDN runtime dependency; this docs site loads them the exact same way):

    Terminal window
    bun add @fontsource/outfit @fontsource/space-mono
    src/main.tsx (your app entry)
    import '@fontsource/outfit/300.css'; // Outfit (sans), thin-forward ramp
    import '@fontsource/outfit/400.css';
    import '@fontsource/outfit/500.css';
    import '@fontsource/space-mono/400.css'; // Space Mono for code / mono
    import '@fontsource/space-mono/700.css';

    Use @fontsource/outfit (family Outfit), not @fontsource-variable/outfit (which registers the family as Outfit Variable and would not match the token). Outfit ships weights 100 to 900. The Nockerl ramp is thin-forward (100 to 500), so import the weights you render. The Fontsource family names match the token names, so --font-family-sans / --font-family-mono resolve to the loaded faces with no further wiring.

  5. Use a component. Each component injects its own scoped <style>, so there is no stylesheet import and no bundler config beyond the tokens above:

    import '@dizyx/nockerl-tokens/tokens.css';
    import { NockerlButton, NockerlSurface } from '@dizyx/nockerl-react';
    export function Example() {
    return (
    <NockerlSurface level={2}>
    <NockerlButton text="Save" variant="primary" onClick={() => {}} />
    </NockerlSurface>
    );
    }
  6. Reference tokens, never raw values in your own chrome. Bind to the variables:

    .card {
    background: var(--color-card-surface1);
    border-radius: var(--radius-card); /* 16px */
    color: var(--color-on-card);
    box-shadow: 0 6px 18px -8px var(--color-shadow-tint);
    }

Dark is the brand default. Both themes live in the tokens; you activate one with a class or attribute on a high ancestor (usually <html>):

<html class="dark"> <!-- or: <html data-theme="dark"> -->

Light is the :root default; .dark and [data-theme='dark'] both override it, so use whichever your framework toggles. Nothing switches until one is set. Paint the page surface with the canvas token (otherwise you get components on default white):

body { background: var(--color-canvas); color: var(--color-on-canvas); }

To follow the OS preference, reflect it onto <html> once at startup:

const dark = matchMedia('(prefers-color-scheme: dark)');
const apply = => document.documentElement.classList.toggle('dark', dark.matches);
apply();
dark.addEventListener('change', apply);

The per-platform packages follow the same publish-and-consume contract from the same DTCG source. Both are available now at the same 2.0.0 version line: tokens and components.

Status: available. Two Maven artifacts on GitHub Packages: design-tokens (the NockerlTheme + palettes + typography + shapes, with the Outfit variable font bundled in) and design-components (the NockerlButton family). GitHub Packages Maven requires a read:packages PAT even to read, and Gradle cannot route through the the credential store proxy, so every consumer authenticates directly.

~/.gradle/gradle.properties (never commit a token)
gpr.user=<your-github-username>
gpr.key=<a-PAT-with-read:packages>
settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven {
name = "NockerlDesignGitHubPackages"
url = uri("https://maven.pkg.github.com/dizyx/nockerl-design")
credentials {
username = providers.gradleProperty("gpr.user").orNull ?: System.getenv("GITHUB_ACTOR")
password = providers.gradleProperty("gpr.key").orNull ?: System.getenv("GITHUB_TOKEN")
}
}
}
}
app/build.gradle.kts
dependencies {
implementation("com.dizyx.nockerl:design-tokens:2.0.0")
implementation("com.dizyx.nockerl:design-components:2.0.0")
}

Then wrap your app in NockerlTheme and use the components; the bundled Outfit font needs no wiring:

import com.dizyx.nockerl.design.tokens.NockerlTheme
import com.dizyx.nockerl.design.tokens.ThemeMode
import com.dizyx.nockerl.design.components.NockerlButton
setContent {
NockerlTheme(mode = ThemeMode.DEFAULT) {
NockerlButton(text = "Save", onClick = { save() })
}
}

NockerlTheme is Activity-safe (it no-ops the system-bar sync outside an Activity), so it works in @Preview and non-Activity hosts. See packages/compose/README.md for the full consumer guide.

Token and component releases follow semver with a CHANGELOG, and all platforms move on one version line. Patch and minor bumps are drop-in; a major bump signals a breaking rename or value change you should review. Pin a version, read the CHANGELOG, and upgrade on your own cadence. The framework never force-pushes a value into a client. Keep @dizyx/nockerl-react and @dizyx/nockerl-tokens on the same version (they ship in lockstep).