nalarx-ui

Versioning and drift

How items are versioned, how an app pins a release, and how the lockfile catches silent edits.

Item versions

Every item has its own semantic version in meta.version of its item.json, and its own CHANGELOG.md next to it. The registry build refuses an item whose changelog has no entry for its version.

ChangeBump
Fixes a bug without changing how the item is used or how it lookspatch
Adds a prop, a variant or a token; existing screens look the sameminor
Renames or removes anything, or changes how an existing screen looksmajor

Items stay below 1.0.0 until nalarx-frontend runs on them. Before 1.0.0, a breaking change bumps the minor version.

Changelog entries are written for the people who install the item: what changed on screen or in usage, in plain words.

Release tags

TagPoints atExample
v<semver>A release of the whole registry (public/r at that commit)v0.1.0
<item>@<semver>The commit that released that item versiontheme@0.1.0

The repo version in package.json is the registry release. Bump it whenever any item changes, tag the commit v<version>, and add an <item>@<version> tag for each item that changed.

Pinning a release

public/r is committed, so every tag is a complete snapshot of the registry. An app pins a release by putting the tag in its @nalarx URL:

components.json
{
  "registries": {
    "@nalarx": {
      "url": "https://raw.githubusercontent.com/<org>/nalarx-ui/v0.1.0/public/r/{name}.json",
      "headers": { "Authorization": "Bearer ${GITHUB_TOKEN}" }
    }
  }
}

Pin the whole namespace rather than single items. Items depend on each other as @nalarx/<item>, and the shadcn CLI resolves those through the same URL, so one pin keeps every dependency on the same release. The shadcn CLI can also install a single GitHub item at a ref (<org>/nalarx-ui/theme#theme@0.1.0), but its dependencies then follow the app's @nalarx URL, which is why the namespace pin is the default.

When a hosted registry exists, its deploy should also publish each release under /r/v<semver>/, so https://<host>/r/v0.1.0/{name}.json works without a GitHub token.

The lockfile

@nalarx/drift-check installs scripts/nalarx-ui-drift.ts. record writes nalarx-ui.lock.json:

nalarx-ui.lock.json
{
  "lockfileVersion": 1,
  "registry": "@nalarx",
  "items": {
    "base": {
      "version": "0.1.0",
      "files": {
        "src/components/ui/nx/lib/cn.ts": "sha256:…",
        "src/styles/nalarx-ui/nx.css": "sha256:…"
      }
    }
  },
  "overrides": {
    "src/components/ui/nx/lib/cn.ts": "Adds a local class order fix until nalarx-ui ships it (NAL-123)."
  }
}
  • record [item...] fetches each item from the @nalarx URL, follows its @nalarx/* dependencies, finds the installed files through components.json aliases and tsconfig paths, and stores the version and a sha256 of each file. With no names it re-records everything already in the lockfile.
  • check hashes every recorded file and exits 1 when one is missing or changed. Files under overrides are skipped, and each override must say why.
  • outdated prints each recorded item with the registry's current version.

Fingerprints ignore line endings (CRLF and LF hash the same). Run the formatter before record.

Updating an item

bunx shadcn@latest add @nalarx/base --overwrite
bun scripts/nalarx-ui-drift.ts record base

Read the item's changelog first, then review the diff like any other change.

On this page