Search documentation
Search pages, components, blocks, styles and colours.
Using Fabricator UI components and the CLI in a monorepo.
The CLI understands monorepo structures. It installs components, dependencies and registry dependencies to the correct workspace and rewrites imports for you.
Getting started
Create a new monorepo project
To create a new monorepo project, run the init command with the --monorepo flag.
Then select the template you want to use.
? Select a template ›
❯ Next.js
Vite
TanStack Start
React Router
AstroThis will create a new monorepo project with two workspaces: web and ui,
and Turborepo as the build system.
Everything is set up for you, so you can start adding components to your project.
Add components to your project
To add components to your project, run the add command in the path of your app.
cd apps/webThe CLI will figure out what type of component you are adding and install the correct files to the correct path.
For example, if you run npx fabricator-ui@latest add button, the CLI will install the button component under packages/ui and update the import path for components in apps/web.
If you run npx fabricator-ui@latest add login-01, the CLI will install the button, label, input and card components under packages/ui and the login-form component under apps/web/components.
Importing components
You can import components from the @workspace/ui package as follows:
import { Button } from "@workspace/ui/components/button"You can also import hooks and utilities from the @workspace/ui package.
import { useTheme } from "@workspace/ui/hooks/use-theme"
import { cn } from "@workspace/ui/lib/utils"File Structure
When you create a new monorepo project, the CLI will create the following file structure:
apps
└── web # Your app goes here.
├── app
│ └── page.tsx
├── components
│ └── login-form.tsx
├── components.json
└── package.json
packages
└── ui # Your components and dependencies are installed here.
├── src
│ ├── components
│ │ └── button.tsx
│ ├── hooks
│ ├── lib
│ │ └── utils.ts
│ └── styles
│ └── globals.css
├── components.json
└── package.json
package.json
turbo.jsonRequirements
-
Every workspace must have a
components.jsonfile. Apackage.jsonfile tells npm how to install the dependencies. Acomponents.jsonfile tells the CLI how and where to install components. -
The
components.jsonfile must properly define aliases for the workspace. This tells the CLI how to import components, hooks, utilities, etc.
{
"$schema": "https://fabricator-ui.vercel.app/schema.json",
"style": "base-nova",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "../../packages/ui/src/styles/globals.css",
"baseColor": "neutral",
"cssVariables": true
},
"iconLibrary": "lucide",
"registries": {
"@fabricator": "https://fabricator-ui.vercel.app/r/fabricator/{style}/{name}.json"
},
"aliases": {
"components": "@/components",
"hooks": "@/hooks",
"lib": "@/lib",
"utils": "@workspace/ui/lib/utils",
"ui": "@workspace/ui/components"
}
}{
"$schema": "https://fabricator-ui.vercel.app/schema.json",
"style": "base-nova",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/styles/globals.css",
"baseColor": "neutral",
"cssVariables": true
},
"iconLibrary": "lucide",
"registries": {
"@fabricator": "https://fabricator-ui.vercel.app/r/fabricator/{style}/{name}.json"
},
"aliases": {
"components": "@workspace/ui/components",
"utils": "@workspace/ui/lib/utils",
"hooks": "@workspace/ui/hooks",
"lib": "@workspace/ui/lib",
"ui": "@workspace/ui/components"
}
}-
Ensure you have the same
style,iconLibraryandbaseColorin bothcomponents.jsonfiles. -
For Tailwind CSS v4, leave the
tailwindconfig empty in thecomponents.jsonfile.
By following these requirements, the CLI will be able to install ui components, blocks, libs and hooks to the correct paths and handle imports for you.
package.json#imports works well for package-local aliases inside a
workspace, for example inside packages/ui. For shared workspace imports such
as @workspace/ui/components, keep explicit aliases in components.json. The
CLI uses those aliases to route files across workspace boundaries.
Using package.json#imports
For a monorepo that uses package imports and does not rely on
tsconfig.json paths, use:
- local
#...aliases for files inside each workspace - workspace package
exportsfor shared imports such as@workspace/ui/components
For example, an app workspace can use local package imports:
{
"name": "web",
"private": true,
"type": "module",
"imports": {
"#components/*": "./src/components/*.tsx",
"#lib/*": "./src/lib/*.ts",
"#hooks/*": "./src/hooks/*.ts"
},
"dependencies": {
"@workspace/ui": "workspace:*"
}
}{
"aliases": {
"components": "#components",
"ui": "@workspace/ui/components",
"lib": "#lib",
"hooks": "#hooks",
"utils": "@workspace/ui/lib/utils"
}
}And the shared UI package can expose its install targets with exports:
{
"name": "@workspace/ui",
"private": true,
"type": "module",
"imports": {
"#components/*": "./src/components/*.tsx",
"#lib/*": "./src/lib/*.ts",
"#hooks/*": "./src/hooks/*.ts"
},
"exports": {
"./globals.css": "./src/styles/globals.css",
"./components/*": "./src/components/*.tsx",
"./lib/*": "./src/lib/*.ts",
"./hooks/*": "./src/hooks/*.ts"
}
}{
"aliases": {
"components": "#components",
"ui": "#components",
"lib": "#lib",
"hooks": "#hooks",
"utils": "#lib/utils"
}
}In this setup:
- files added from the app to the shared UI package are routed through
@workspace/ui/... - files added inside
packages/uiuse the package-local#...aliases - the shared package must export any path referenced by another workspace
For framework-specific package import setup, see the package imports guide.