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.2.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 |
npm (public) |
| 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 public npm packages (scope @dizyx):
@dizyx/nockerl-tokens (the CSS custom properties) and @dizyx/nockerl-react (the React
components). There is no registry configuration and no token: install them like any other
dependency.
Both are published from CI by trusted
publishing, so every release carries a
provenance attestation linking it back to the commit and workflow that built it. You can
check one yourself with npm audit signatures after installing.
-
Install the packages with Bun (the Nockerl default runtime):
Terminal window bun add @dizyx/nockerl-react @dizyx/nockerl-tokensreact(>=19) is a peer dependency: the components use React 19 APIs (useIdand friends) and read your app’s copy of React. Tokens-only consumers can install just@dizyx/nockerl-tokens. -
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). -
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-monosrc/main.tsx (your app entry) import '@fontsource/outfit/300.css'; // Outfit (sans), thin-forward rampimport '@fontsource/outfit/400.css';import '@fontsource/outfit/500.css';import '@fontsource/space-mono/400.css'; // Space Mono for code / monoimport '@fontsource/space-mono/700.css';Use
@fontsource/outfit(familyOutfit), not@fontsource-variable/outfit(which registers the family asOutfit Variableand 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-monoresolve to the loaded faces with no further wiring. -
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>);} -
Reference tokens, never raw values in your own chrome. Bind to the variables, including the depth recipe: a neutral drop shadow plus the inset top catch-light, never a glow.
.card {background: var(--color-card-surface1);border-radius: var(--radius-card); /* 16px */color: var(--color-on-card);box-shadow:/* neutral drop shadow, standard card rung: the rung token is the y offset,the blur is a constant 0, so the shadow is crisp rather than a halo */0 var(--elevation-level2) var(--elevation-blur) 0color-mix(in srgb, var(--color-shadow-tint) calc(var(--elevation-shadow-tint-alpha-level2) * 100%), transparent),/* top catch-light, lit from above */inset 0 var(--space-px) 0 var(--color-surface-highlight);}Swap the
--elevation-level*and matching alpha token for a different rung; the other three are listed in Elevation & depth.
This documentation site is itself themed by the same tokens. It vendors a build snapshot of
tokens.css at src/styles/tokens.css (regenerated by
bun run build) rather than resolving the package over the registry, a
convenience for the docs repo. A product consumer instead pulls the published package with
@import “@dizyx/nockerl-tokens/tokens.css” and tracks it like any other
dependency.
Theming & dark mode
Section titled “Theming & dark mode”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);Android & Swift
Section titled “Android & Swift”The per-platform packages follow the same publish-and-consume contract from the same DTCG
source. Both are available now at the same 2.2.0 version line: tokens and
components.
Upgrading
Section titled “Upgrading”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).