shadcn/ui Roadmap and Our CMS: How We Track Upstream Changes

The Bi-Weekly Audit Workflow for 51 Components and 18 Local Mods

August 2, 2026 · 9 min read
shadcn/ui Roadmap and Our CMS: How We Track Upstream Changes

"You own the code" is shadcn/ui's biggest selling point. It's also the part that quietly becomes your problem at month three. The components live in your repo. That means upstream changes — bug fixes, new variants, accessibility patches, Tailwind v4 migrations — don't auto-update through npm. You pull them in manually, like any code change in any codebase.

Most "shadcn in production" advice skips this. The CLI works. The components are great. What nobody writes about is the workflow for keeping a 50+ component fork in sync with shadcn's 6-7 releases per month without breaking your existing customisations. This post is that workflow, written from the seat of someone maintaining 51 shadcn components across 205 admin pages for the last 12 months.

Disclosure: I work on UnfoldCMS. The patterns below are battle-tested in our admin tree, not theoretical.

TL;DR — tracking shadcn upstream when you've forked

shadcn/ui releases 6-7 versions per month as of mid-2026 (about 72-84 per year, faster than React, Next.js, or Tailwind). Most releases are non-breaking, but the Tailwind v3 → v4 migration (October 2024) and React 18 → 19 alignment forced real work across the entire component tree. For UnfoldCMS — 51 components, ~18 with local modifications — we run a bi-weekly upstream audit: scan release notes, diff our forked components against upstream, merge what applies cleanly, log what conflicts. Total time: 1-2 hours every two weeks for the whole component tree. No CLI auto-magic. Just git.

Cadence What we do
Daily Nothing — releases land in shadcn-ui/ui without our intervention
Bi-weekly Audit upstream changes, merge clean ones, log conflicts
Quarterly Review modified components for "can we revert to upstream now?"
Per major migration (Tailwind v4, React 19, etc.) Dedicated sprint, all-hands

What shadcn/ui's roadmap actually looks like

There isn't a single "roadmap document." shadcn doesn't publish quarterly plans. Direction surfaces through three signals:

  • GitHub releases. github.com/shadcn-ui/ui/releases — patch and minor releases land every few days, major changes signposted in advance.
  • shadcn's Twitter / X — @shadcn (the maintainer) posts about new components, Block library updates, Tailwind v4 migrations before they ship.
  • Discord + GitHub Discussions — the community surfaces breaking changes and migration paths before stable releases.

For a CMS builder running shadcn at scale, this matters because you can't subscribe to a stable release channel and ignore minor bumps. Any release might quietly fix the bug you'd already patched, or introduce a new variant that conflicts with yours.

Recent release pattern (April-June 2026):

  • 4.x patches landing every 2-5 days
  • Major API surface stable since Tailwind v4 migration completed
  • Block library expanding (sidebar blocks, dashboard blocks, auth blocks)
  • New components added quarterly (recent additions: Drawer, Combobox revamp)

Source: shadcn-ui/ui GitHub releases.

The maintenance pattern that actually works

After 12 months and ~50 upstream sync cycles, here's the workflow that didn't blow up:

1. Pin to a known-good commit, not a version

shadcn doesn't ship as a versioned npm package. The components are added via CLI or manual copy. There's no package.json version to pin. What you pin is the commit hash of shadcn/ui you last synced to.

We keep this in a SHADCN_VERSION.md file in the repo:

Last synced: 2026-06-09
Upstream commit: a1b2c3d
Components synced: button, card, dialog, dropdown-menu, ...

Without this, "we already have the latest" becomes guesswork after three engineers have touched the component tree.

2. Maintain a "modified components" inventory

About 18 of our 51 components have local diffs from upstream. Without tracking which, you can't audit. We keep a components/ui/MODIFIED.md:

button.tsx        - added 'xs' size variant + brand-blue focus ring
data-table.tsx    - swapped to TanStack Table wrapper + server-side pagination
dialog.tsx        - removed default close-button (we use a custom one)
form.tsx          - added autosave hook integration
...

When upstream changes one of these, we know to look at the local diff before merging.

3. Bi-weekly audit ritual

Every other Monday, we:

  1. Pull shadcn-ui/ui's main branch.
  2. Diff our pinned commit against current main: git log --oneline {OLD_HASH}..main -- registry/.
  3. Filter for changes to components we use (those 51).
  4. For each affected component:
    • If we haven't modified it: apply upstream directly.
    • If we have modified it: read the upstream diff, decide whether to merge, log the decision.
  5. Update SHADCN_VERSION.md with the new commit hash.
  6. Run our component test suite (we use Vitest + React Testing Library).

Total time: 60-120 minutes for the whole pass. About 80% of changes apply cleanly. About 10% need a manual merge. About 10% we skip because they don't match our use case.

4. Major migration sprints

Some changes can't be done in a bi-weekly audit:

  • Tailwind v3 → v4 (October 2024) took us 6 dedicated hours across the team — every component had to be touched to migrate from tailwind.config.js colour declarations to CSS-variable @theme blocks.
  • React 18 → 19 (early 2025) required component-by-component review for new behaviours (use-deferred-value patterns, ref forwarding changes).
  • Block library introduction (mid-2024) wasn't strictly required — we kept hand-coding blocks — but the migration to upstream Block patterns saved time on new admin pages.

Plan for one of these every 6-9 months. Calendar it; don't get surprised.

What breaks the workflow

Three patterns we learned the hard way:

Don't auto-merge upstream

The npx shadcn add {component} CLI command overwrites your modified component without confirmation. Don't run it against components you've modified. The CLI is great for adding new components; it's dangerous for updating existing ones with local mods.

Don't let "modified" components proliferate

Every locally-modified component is upstream-merge debt. At 18 modified out of 51, we're at the limit of what's tractable. Past 20-25, the bi-weekly audit becomes a quarterly nightmare.

The discipline is: before adding a local modification, ask "could we live with the upstream version + a className override?" Most of the time, yes. Reserve real modifications for behaviours that override mechanics, not aesthetics.

Don't skip the upstream changelog

About every 4-6 months, shadcn ships a "non-breaking" change that subtly changes a default. The Dialog close behaviour changed once (focus return on close moved from the trigger to body). It was clearly documented in the release notes. We missed it because we'd been skim-reading. Three weeks of subtle accessibility regressions later, we backtracked. Read the notes.

When to fork hard (and stop tracking)

For a small subset of components — usually 2-3 in any large codebase — the right move is to stop tracking upstream entirely. The component has diverged so far that merging upstream changes is more work than just owning it.

For us, data-table.tsx is fork-hard. It's a TanStack Table wrapper with server-side pagination, multi-sort, column resize, sticky headers, mobile responsive sheet variant — none of which shadcn ships in core. We track shadcn's <Table> primitive but our <DataTable> is ours.

For these components, we still benefit from shadcn's primitive (<Table>, <TableHeader>, <TableRow>, <TableCell>). The composition stays in our control.

For the longer narrative on what "production patterns" actually look like across the component tree, see shadcn/ui in Production: 1 Year, 51 Components, 205 Admin Pages — Lessons.

The Block library is the new vector

shadcn's Block library (launched mid-2024, expanded heavily in 2026) is a parallel surface to track. Blocks are full UI sections — sidebars, login pages, dashboards — composed of shadcn components. They're added the same way as components (npx shadcn add block-name).

For a CMS admin, Blocks are useful for:

  • Onboarding pages — login, password reset, signup.
  • Dashboard layouts — sidebar + main content composition.
  • Settings pages — sectioned form layouts.

We use about 5 blocks today. They're easier to track than components because we don't typically modify them — if the block doesn't fit, we don't use it. Skip the merge problem entirely.

People Also Ask

Does shadcn/ui have a roadmap?

Not in the formal sense. Direction surfaces through GitHub releases (6-7/month), maintainer Twitter, and Discord discussions. The maintainer doesn't publish quarterly plans. For production users, subscribe to the GitHub releases feed and follow @shadcn on Twitter.

How do I update shadcn components in my project?

Two patterns. For unmodified components: npx shadcn add {component} overwrites with current upstream. For modified components: don't use the CLI — manually diff your version against upstream and merge selectively. We do this in a bi-weekly audit.

How often does shadcn/ui release updates?

Roughly 6-7 releases per month as of mid-2026. About 72-84 per year. Most are patches (bug fixes, accessibility improvements). Minor releases add components or variants. Major migrations (Tailwind v4, React 19) happen once every 6-9 months.

Will Tailwind v5 break my shadcn fork?

Tailwind v5 hadn't shipped as of June 2026, but based on the v3 → v4 pattern: expect a dedicated migration sprint when it does land. Plan 6-12 hours for a 50-component tree. The good news is that v4's CSS-variable theming model is unlikely to be revisited soon.

Should I use the shadcn CLI or copy components manually?

CLI for first install of a component you don't have. Manual for everything else, especially anything you've modified. The CLI is fast but overwrites — a bug your modified Button has fixed will quietly reappear if you let the CLI replace it.

Bottom line

shadcn's "you own the code" model is real and good — but ownership includes maintenance. For production users, the 1-2 hours of bi-weekly audit work is the cost of admission. Skip it, and your 51-component tree quietly diverges from upstream until a migration becomes a multi-week project. Run the audit, and you get the best of both worlds: code-in-your-repo modifiability with current-shadcn polish.

For more on what "long-term shadcn" actually looks like, see shadcn/ui in Production: 1 Year, 51 Components, 205 Admin Pages — Lessons and Customizing the shadcn Admin: Fork-and-Modify Beats Vendor Widgets. To see the 12-month result in production, try the UnfoldCMS demo.


Sources and methodology

  • shadcn/ui releasesgithub.com/shadcn-ui/ui/releases, release cadence sampled over 90-day period (April-June 2026) = 20 releases in 90 days ≈ 6-7/month average.
  • Tailwind v3 → v4 migration impact — documented in our internal commit history; aligned with broader Tailwind v4 release notes and the shadcn Tailwind v4 migration guide.
  • shadcn Blocksui.shadcn.com/blocks for the official library.
  • UnfoldCMS countsfind cms/resources/js/components/ui -name "*.tsx" \| wc -l = 51; find cms/resources/js/pages/admin -name "*.tsx" \| wc -l = 205. ~18 components with local modifications (verified by git diff).
  • Workflow patterns — drawn from internal commit history and post-merge retrospectives, April 2024 - June 2026.
  • All cadence figures subject to update as shadcn evolves. Re-verify before depending on absolute numbers.

Free & Open Source

Own your CMS. No subscriptions.

Unfold CMS is free to download and self-host. Built on Laravel + React, full source code included.

Share this post:

Discussion

Comments (0)

Leave a Comment

Please log in to leave a comment.

Don't have an account? Register here

No comments yet. Be the first to share your thoughts!

Keep Reading

Related Posts

Back to all posts