Contributing

When you finish this page you know which parts of Sorb™ you can clone and change, how the open-source packages fit together, and how to get a fix merged. You need Node 20 and pnpm.

What's open source

Sorb™ is split across several repositories. The packages you install and the demos you can copy are public on GitHub; the hosted service and Metatoy's internal tooling are not.

Public repoWhat it isnpm
sorb-coreShared contract: tiers, ResolvedToken, connector registry@sorb/core
sorb-seedPlaywright capture + token resolver, adapt codemods, sorb-seed CLI@sorb/seed
sorb-leafReact SDK: SorbProvider, PreviewBanner, hooks, target adapters@sorb/leaf
sorb-juiceLocal bridge server + sorb CLI (sorb dev, sorb handshake, …)@sorb/juice
sorb-canopyThe Figma plugin— (source + zip release; not on the Figma Community yet — see Install (beta))
sorb-storybookStorybook addon: Bound Tokens panel@sorb/storybook
sorb-tapRead-only MCP server for design tokens (a DTCG file, a Sorb project, or a running bridge)source only
sorb-demoJane's Jeans reference app (React + Bootstrap)
sorb-demo-kitThe Jane's Jeans brand kit: DTCG token tree, fixtures, imagery, component inventory
sorb-demo-{angular,mantine,mui,primevue,tailwind}The multi-stack demo storefronts built from the kit

Private, not open to outside contributions: sorb-cloud (the hosted service behind app.sorbcloud.com), this documentation site, Metatoy's end-to-end test suite, the try.sorbcloud.com tour, and the internal test fixtures. You can't clone them, and pull requests aren't accepted there. If something in the hosted product is wrong, use Support — it reaches the same people.

Workspace layout

The public repos are a polyrepo: each lives in its own git repository, and the packages that develop against each other's checkout sit side by side under one umbrella directory with a pnpm-workspace.yaml at its root. A minimal contributor checkout looks like this:

mkdir sorb && cd sorb
git clone https://github.com/metatoy/sorb-core
git clone https://github.com/metatoy/sorb-seed
git clone https://github.com/metatoy/sorb-leaf
git clone https://github.com/metatoy/sorb-juice
git clone https://github.com/metatoy/sorb-demo
printf "packages:\n  - 'sorb-*'\n" > pnpm-workspace.yaml
pnpm install

With the workspace file in place, sorb-demo resolves @sorb/leaf and @sorb/juice from the sibling checkouts instead of npm, the same way sorb-seed, sorb-leaf, and sorb-juice resolve @sorb/core. Repos that are not workspace members — the plugin, the Storybook addon, and each multi-stack demo — install and run on their own; their READMEs say how.

JavaScript only

Every public repo is JavaScript, not TypeScript — types are JSDoc typedefs in a src/types.js file, and builds use esbuild rather than a TypeScript compiler. A pull request that adds a .ts file or a typescript dependency to one of them will be asked to change.

Two more rules that apply everywhere: don't commit generated output (dist/, .sorb/, src/tokens/generated/), and don't add a per-package lockfile to a pnpm workspace member — the umbrella pnpm-lock.yaml is the only one.

Package manager per repo

RepoPackage manager
sorb-core, sorb-seed, sorb-leaf, sorb-juice, sorb-demopnpm, as workspace members (pnpm install from the umbrella root)
sorb-canopy, sorb-storybook, the multi-stack demo reposnpm, each with its own lockfile

Send a change

  1. Fork the repo you're changing and branch from main.
  2. Run that repo's tests before and after — node --test src/ in sorb-core, pnpm test in sorb-seed, npm test in sorb-leaf and sorb-juice. Other repos name their command in their README.
  3. Keep the public surface documented: if you add or change an export of @sorb/core, @sorb/seed, @sorb/leaf, or @sorb/juice, give it a JSDoc block — the package reference on this site is generated from those comments, and an undocumented export fails the docs build.
  4. Open a pull request with what changed and how you verified it. A maintainer reviews it; releases to npm are cut by Metatoy from a version tag with provenance, so you don't need to bump versions.

Bug reports and feature requests go in the issue tracker of the repo they belong to. For anything about the hosted product (accounts, billing, the dashboard), use Support instead — that code isn't public.

Maintainers: this documentation site

This section is for Metatoy maintainers. The docs site's repository is private.

The deployable app lives under www/, not the repo root:

cd sorb-www/www
npm install
npm run dev        # http://localhost:3000/docs

Docs pages are MDX files under app/docs/<route>/page.mdx. Follow the shape of an existing page — pageMetadata() for the frontmatter-equivalent, an <h1> naming the reader's task, a <p className="lead-line"> stating the outcome and prerequisites, then sections, then a ## Next list of links. Screenshots are never invented: use the Shot placeholder component (app/docs/Shot.jsx) until a real capture exists.

Regenerate the API reference

The package reference pages (/docs/packages/core|seed|leaf|juice) are built from generated partials, not hand-written prose. The generator reads sibling checkouts in the umbrella workspace — it needs sorb-core, sorb-seed, sorb-leaf, and sorb-juice checked out next to sorb-www (or pointed at via SORB_WORKSPACE, default ../.. from www/; SORB_REPO_<PKG> overrides a single repo path):

npm run gen:api      # regenerate app/docs/packages/_generated/*
npm run check:api    # fail if the committed output is stale, or any export
                      # is undocumented

Run npm run gen:api after any change to @sorb/core, @sorb/seed, @sorb/leaf, or @sorb/juice's public surface, and commit the regenerated files under app/docs/packages/_generated/ — they are committed output, not build artifacts, because the production Docker build only sees www/ and has no sibling checkouts to generate from.

Checks

Three of these run automatically, in order, as npm run build's prebuild step (check:no-ts && check:blocklist && check:api); the rest you run by hand at the point they're each useful:

CommandWhat it checksWhen
npm run check:no-tsno .ts/.tsx files or TypeScript deps under www/in prebuild
npm run check:blocklistno internal hosts, secrets, retired names, or private repos presented as cloneable in app/docs/**in prebuild
npm run check:apithe committed API reference matches the sibling source, and nothing is undocumentedin prebuild
npm run check:mdxevery app/docs/**/*.mdx file compiles (fast — no full next build)run it yourself while editing MDX, before committing
npm run check:linksevery internal link in the built site resolvesafter npm run build — it crawls the built .next/ output
npm run check:snippetsthe copy-paste commands in Getting started actually run, end to endbefore merging a change to the getting-started snippets

Next

  • Getting started — the reader-facing quickstart these docs teach.
  • Package reference — the generated surface of the four npm packages.
  • Demos — the storefronts you can fork to try a change end to end.

Works with Figma. Not affiliated with, or endorsed by, Figma. Figma is a trademark of Figma, Inc.