✳️ 581+ Pro Blocks, lifetime updates, unlimited projects — Get 50+ fresh blocks every month ✳️ 👇
Grab the deal →

shadcn CLI Local File Support

shadcn CLI adds local JSON support

by Yucel F. Sahan
5 min read
Updated on

Before July 2025 you had to pull every component, theme or util from a remote registry.json.
Now the shadcn CLI (v 2.8) understands plain JSON files that live right next to your code, so a laptop on a train-ride or a company network behind a firewall can still spin-up a full design system with one command.

Why local-file support matters

The pain it fixes

  • Firewalled teams often saw npx shadcn init fail because the registry URL was blocked.

  • Custom folder structures needed hacks or post-copy scripts; now any path is valid JSON.

  • Keeping proprietary UI private meant setting up an internal registry; now you can just check components into Git.

What shipped in v 2.8

  • init and add accept a local path or URL interchangeably.

  • Zero network calls → instant install even offline.

  • Faster iteration: edit JSON, re-run add, inspect changes live.

  • Works with the new Universal Registry Items introduced the same month.

Quick-start: bootstrapping offline in three steps

1 — Craft a minimal template.json

{
  "$schema": "https://ui.shadcn.com/schema.json",
  "name": "acme-offline-starter",
  "style": "new-york",
  "components": ["button", "dialog"]
}

2 — Initialise without the internet

npx shadcn init ./template.json        # local file 📄

The CLI reads the JSON, installs Tailwind, sets up cn utils and scaffolds folders in seconds.

3 — Add a component later

npx shadcn add ./blocks/hero.json

Again, no registry hit—just a local file copy plus auto-merge of Tailwind keys.

Customising paths & aliases

Need components inside packages/ui/src?
Add or tweak components.json once and every future install follows it:

{
  "aliases": {
    "ui": "@/packages/ui/src",
    "components": "@/packages/ui/src/components"
  }
}

The CLI resolves those aliases when dropping files, so your monorepo stays tidy.

A complete offline workflow example

# 1. Create a local registry item
cat > avatar.json <<'EOF'
{
  "name": "avatar",
  "files": {
    "avatar.tsx": "export const Avatar = () => <img className='rounded-full' />"
  },
  "dependencies": ["react"]
}
EOF

# 2. Add it to an existing project
npx shadcn add ./avatar.json --path ./src/components

# 3. Use it in code
import { Avatar } from '@/components/avatar'

Behind the scenes shadcn merges avatar.tsx, updates tsconfig paths if needed and runs prettier.

Tips & gotchas

Problem

Fix

JSON typo throws “invalid registry item”

Validate with the $schema URL in VS Code.

Components land in the wrong folder

Double-check aliases.ui / --path flag.

You still need internet for NPM deps

Run npm ci --offline after caching packages once.

Sharing inside the org

Commit the JSON files or host them on an internal Git repo—add works with any URL.


What the community is saying

  • Devs like the “code-lives-in-your-repo” philosophy and the speed bump from local installs.

  • Some argue it’s “just another registry”, but admit pointing to any repo is ergonomic.

  • GitHub discussions show teams already scripting custom folder layouts via components.json.

Below are four practical FAQs that readers often ask after discovering shadcn CLI Local File Support. Each answer includes the exact command syntax or config snippet you’ll need, plus clarifications on common “gotchas”.


Some use cases, questions and answers

1. How do I initialise a new project completely offline with my own template?

Save your starter JSON (for example template.json) in the project folder and run:

npx shadcn init ./template.json

The CLI reads the local file instead of calling the public registry, so the scaffolding step works without an internet connection.
Remember that dependency installation still goes through your package-manager; to stay offline you must cache packages first and then use flags such as npm ci --offline or npm ci --prefer-offline

2. Can I mix local files and remote items in the same add command?

Yes. Every argument passed to shadcn add can be a name from the public registry, a direct URL, or a relative/absolute file path. The CLI treats them identically (see “components — name, URL or local path” in the help text)
Example:

npx shadcn add ./avatar.json button https://example.com/r/hero.json

The command grabs avatar from disk, button from the official registry, and hero from your internal URL—all in one go.

3. Where will the CLI place components added from local files, and how can I change that?

File destinations are resolved through the aliases section of components.json.
Setting

{
  "aliases": {
    "components": "@/packages/ui/src/components",
    "ui": "@/packages/ui/src/components/ui"
  }
}

tells the CLI to write UI primitives to packages/ui/src/components/ui, not the default app/components/ui.
This mechanism also underpins monorepo support, letting each workspace keep its own components.json so installations land in the correct package.


4. What’s the easiest way to share my local JSON items with the team?

Commit the JSON files to your repo or expose them from an internal Git HTTP route; the CLI can consume any reachable URL just like a file path, so teammates only need:

npx shadcn add https://git.example.com/ui/avatar.json

This keeps proprietary code private yet still one-command installable.
For larger libraries you might publish a custom registry (a folder of JSON files plus a registry.json manifest) and let colleagues run shadcn build to generate or test items locally before pushing upstream.


Key take-away: Local-file support makes shadcn a portable scaffolder—you can initialise, iterate and share UI code anywhere, with remote registries becoming purely optional.


Conclusion

Local-file support turns the shadcn CLI into a portable scaffolder: whether you’re offline, on a locked-down VPN, or iterating on unreleased components, your workflow is one JSON and one command away.

Try converting a few favourite components to .json, disconnect Wi-Fi, and watch your project spin-up in silence—that’s faster offline development.

Yucel F. Sahan

Yucel is a digital product creator and content writer with a knack for full-stack development. He loves blending technical know-how with engaging storytelling to build practical, user-friendly solutions. When he's not coding or writing, you'll likely find him exploring new tech trends or getting inspired by nature.