Patternmode is the catalog monorepo for Howells UI tools.
For “use Patternmode style”, start with the style guide: the canonical typography, colour roles, spacing, and application recipes.
@patternmode/stacksheetlives inpackages/stacksheet.@patternmode/apertolives inpackages/aperto.@patternmode/decklives inpackages/deck.@patternmode/systemlives inpackages/system.@patternmode/swatchlives inpackages/swatch.@patternmode/scrollframelives inpackages/scrollframe.apps/webis the minimal catalog site.packages/site-uiandpackages/motionare private workspace packages.
The old Patternmode UI system, Storybook, playground, transition package, and longform docs were intentionally retired during the catalog migration.
Components are npm packages. Install the ones a repo needs and pin them once in the workspace catalog, so fixes arrive as upgrades:
pnpm add @patternmode/stacksheet @patternmode/swatch @howells/motionThe theme is different: it ships through a self-hosted
shadcn registry at
https://patternmode.com/r/{name}.json, because it has to land in the app's own
globals.css and font setup.
npx shadcn add https://patternmode.com/r/theme.jsonThe registry also serves every component as vendored source, for the rare repo that needs
to edit one. Add the namespace once to components.json
({ "registries": { "@patternmode": "https://patternmode.com/r/{name}.json" } }) and
npx shadcn add @patternmode/swatch. A vendored copy no longer receives fixes.
Component CSS reads the standard shadcn theme variable vocabulary (--foreground,
--muted-foreground, --ring, …) with each package's original hex values as fallbacks, so
installed components pick up any shadcn-compatible theme automatically. See
docs/library-contract.md for the vendoring pipeline, the token
contract, and the dependency conventions.
Releases are published from this machine. There are no GitHub Actions in this repo and nothing runs in CI, so every check, build, release and deploy happens locally.
pnpm changesetto describe the change.pnpm version-packagesto apply the bumps and write the changelogs.- Review and commit.
pnpm typecheck && pnpm lint && pnpm build && pnpm test- the full gate.pnpm release(add--dry-runto pack and verify without publishing).node scripts/verify-release.mjsto read every published package back.
scripts/release.mjs sorts the workspace into dependency order, skips whatever
the registry already has, packs each package with pnpm and hands the tarball to
npm. Re-running after a partial failure is safe, which matters because
unpublishing is unavailable after 72 hours.
The npm session has to be able to write. The script passes no credential; npm
uses the logged-in user or an NPM_TOKEN in the environment
(NPM_CONFIG_USERCONFIG=<npmrc with the token> pnpm release). Note the trap it
cost an evening: the account is on auth-and-writes, so a classic Publish
token authenticates and then refuses to write. It has to be a classic
Automation token or a granular access token, and npm whoami succeeding
proves nothing about whether a token can publish. An interactive npm login
session works but will ask for a one-time password per publish.
pnpm packs and npm publishes, deliberately. Ten of these packages depend on
another through the workspace:* protocol, and only pnpm rewrites that to a real
version when it packs - npm pack ships the literal string and the release is
uninstallable. Each half does the thing it can do.
scripts/verify-release.mjs reads every published package back off the registry,
because a leaked workspace: range publishes without error and only fails for
the first stranger who installs it.
Trusted Publishing is retired along with the workflow. If a package on npmjs.com still has a trusted publisher configured and set to required, a token publish is rejected; clear that setting on the package before releasing.