āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā š shadcn/directory/crafter-station/elements/monorepo ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
This project is now organized as a Turborepo monorepo for better organization and scalability.
elements/
āāā apps/
ā āāā web/ # Main Next.js application
ā āāā app/ # Next.js app directory
ā āāā components/ # React components
ā āāā lib/ # Utilities and helpers
ā āāā package.json # Web app dependencies
āāā packages/
ā āāā clerk/ # Clerk authentication components
ā ā āāā registry/ # Component registry files
ā ā ā āāā clerk/ # Clerk component implementations
ā ā āāā registry.json # Clerk registry schema
ā ā āāā package.json
ā āāā uploadthing/ # UploadThing file upload components
ā ā āāā registry/
ā ā ā āāā uploadthing/
ā ā āāā registry.json
ā ā āāā package.json
ā āāā polar/ # Polar sponsorship components
ā ā āāā registry/
ā ā ā āāā polar/
ā ā āāā registry.json
ā ā āāā package.json
ā āāā logos/ # Logo components library
ā ā āāā registry/
ā ā ā āāā logos/
ā ā āāā registry.json
ā ā āāā package.json
ā āāā theme/ # Theme switcher components
ā āāā registry/
ā ā āāā theme-switcher/
ā āāā registry.json
ā āāā package.json
āāā scripts/
ā āāā merge-registry.ts # Merges all package registries into one
ā āāā split-registry.ts # Splits main registry into packages
āāā turbo.json # Turborepo configuration
āāā registry.json # Merged registry (auto-generated)
āāā package.json # Root workspace configuration
Each provider (clerk, uploadthing, polar, etc.) has its own package with:
The main registry.json at the root is auto-generated from all package registries:
bun run registry:merge
This script:
registry.json filesregistry.jsonThe split-registry.ts script was used to split the original monolithic registry:
bun run scripts/split-registry.ts
bun run dev
This runs the Next.js dev server for the web app using Turborepo.
bun run build
Builds all packages in the correct order based on dependencies.
bun run lint
Runs linting across all packages.
12 components
2 components
2 components
40 components
6 components
Create a new directory in packages/:
mkdir packages/my-provider
Add package.json:
{
"name": "@elements/my-provider",
"version": "0.1.0",
"private": true,
"description": "My provider components",
"scripts": {
"dev": "echo 'No dev script'",
"build": "echo 'No build script'",
"lint": "biome check ."
}
}
Create registry.json:
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "elements-my-provider",
"homepage": "https://tryelements.dev",
"items": []
}
Add your component files in registry/my-provider/
Run bun run registry:merge to update the main registry
The turbo.json defines task pipelines:
package.json has minimal dependencies (only dev tools)apps/web/package.jsonregistry.json is auto-generated - don't edit it manuallyā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā