This monorepo publishes three packages independently with Changesets:
shadcn— the CLI and tooling.@shadcn/react— headless React primitives.@shadcn/helpers— small helpers for developing apps.
They version on their own lines. A change to one never bumps the other unless a changeset says so.
Every change that should publish needs a changeset. Run:
pnpm changesetSelect the affected package(s) and bump level. One PR can carry separate changesets for each package at different levels. A PR with no changeset publishes nothing.
Stable releases are automated by .github/workflows/release.yml (the release job, on push to main):
- Merged changesets accumulate on
main. - The Changesets action opens/updates a "Version Packages" PR that bumps versions and writes changelogs.
- Merging that PR triggers
changeset publish, which builds all packages (pnpm build:packages) and publishes any whose version is ahead of npm — each to thelatesttag.
pnpm build:packages (turbo run build --filter=./packages/*) builds every package under packages/ but never apps/v4.
Add the release: beta or release: rc label to a PR. The prerelease job in release.yml:
- Verifies the branch has changesets (a label on the version PR is a no-op, since it consumed them).
- Runs
changeset version --snapshot <channel>— stamps a unique0.0.0-<channel>-<timestamp>on each changeset'd package. - Builds and runs
changeset publish --tag <channel> --no-git-tag. - Uploads the published package list;
prerelease-comment.ymlposts apnpm dlxinstall line per package and removes the label.
The label selects the dist-tag/channel; the changesets on the branch select which packages publish. Snapshots are timestamped, so they never touch latest and never collide.
# Install a snapshot from the PR comment, e.g.:
pnpm dlx @shadcn/react@0.0.0-beta-20260624120000For a baking release line (e.g. 1.0.0-rc.0, -rc.1, …) rather than throwaway snapshots, use Changesets pre mode:
pnpm changeset pre enter rc # writes .changeset/pre.json
# ...normal changeset + Version PR cycle now produces -rc.N versions on the rc tag...
pnpm changeset pre exit # back to stable; next Version PR ships X.Y.Z on latestpnpm-workspace.yamlsetsminimumReleaseAge: 2880(48h), so freshly published stable/beta versions take time to resolve in normal installs. Usepnpm dlx <pkg>@<exact-snapshot-version>to test immediately.- Publishing uses npm OIDC/provenance (
id-token: write+npm@latest); noNPM_TOKENsecret is needed.