shadcn/ui-style CLI to install Blade + Alpine components in Laravel projects.
Copies components from bladcn-components (CSS, JS, Blade) and resolves dependencies from each dependencies.json.
bladcn-components/
├── resources/
│ ├── js/ # bladcn.js + carousel (import from app.js)
│ ├── css/ # Theme and base CSS (bladcn init)
│ ├── views/components/ui/ # Blade components (bladcn add)
│ └── views/partials/ # bladcn-boot
The CLI package does not ship component assets; they live in bladcn-components (default ../bladcn-components).
# .env
BLADCN_REGISTRY=../bladcn-components
# optional: publish config to customize defaults
php artisan vendor:publish --tag=bladcn-configexport BLADCN_REGISTRY=../bladcn-components
bladcn initcomposer require ailuracode/bladcn --devOr clone this repo and use the binary directly:
cd bladcn-cli
composer install
cp .env.example .env # optional: local registry defaults
./bin/bladcn --version# Full setup: bladcn.json + stubs (CSS, ServiceProvider, boot)
php artisan bladcn:init
# Useful options
php artisan bladcn:init --with-dark-mode --skip-prompts
php artisan bladcn:init --force
php artisan bladcn:list
php artisan bladcn:add accordion
php artisan bladcn:add --all
php artisan bladcn:add button --dry-runFrom your Laravel app root:
# 1. Create bladcn.json and base assets
bladcn init
# 2. List available components
bladcn list
# 3. Add a component (and its dependencies)
bladcn add accordion
# 4. Add several at once
bladcn add dialog button card
# 5. Component only, no dependencies
bladcn add button --no-deps
# 6. Preview without copying
bladcn add drawer --dry-run
# 7. Install every component in the registry
bladcn add --all
# 8. Overwrite existing files
bladcn add button --overwrite{
"$schema": "./vendor/ailuracode/bladcn/resources/bladcn.schema.json",
"componentsPath": "resources/views/components/ui",
"registry": "github:ailuracode/bladcn-components",
"registryBranch": "main",
"resolved": ["accordion", "icon"]
}The default registry points to bladcn-components. You can change it using any of these formats:
{
"registry": "https://github.com/ailuracode/bladcn-components"
}{
"registry": "https://github.com/other-user/other-registry/tree/develop",
"registryBranch": "develop"
}bladcn init --registry ../bladcn-components --forceYou can also set a relative path in registry:
{
"registry": "../bladcn-components"
}Resolution is declarative: the CLI reads each component's dependencies.json in the registry and persists installed components in resolved inside bladcn.json. It does not infer dependencies from Blade imports.
Registry locates components under resources/views/components/ui/ (preferred) or components/ inside the configured registry. A component is either a folder (accordion/) or a single file (foo.blade.php).
Only folder components may include a manifest. ComponentManifest parses:
{
"dependencies": ["icon"],
"composer": ["mallardduck/blade-lucide-icons"],
"npm": ["embla-carousel"],
"css": ["sonner.css"],
"js": ["bladcn/carousel.js"]
}| Field | Purpose |
|---|---|
dependencies |
Other registry components installed first (transitive, depth-first) |
composer |
Packages passed to composer require when missing |
npm |
Documented for the host project (not installed automatically) |
css |
CSS files copied from the registry and imported into the main CSS file |
js |
JS files copied under resources/js/ and wired into bladcn.js when needed |
Same-group sub-components (e.g. accordion/trigger.blade.php) are not listed in dependencies; only external registry components are.
flowchart TD
A["bladcn add carousel"] --> B["Registry: local path or GitHub cache"]
B --> C["Read carousel/dependencies.json"]
C --> D["DFS plan: icon → button → carousel"]
D --> E["Copy Blade files to componentsPath"]
D --> F["composer require listed packages"]
D --> G["Publish CSS/JS assets from manifest"]
E --> H["Update resolved in bladcn.json"]
F --> H
G --> H
When you run bladcn add accordion, the CLI:
- Validates the component exists in the registry
- Builds an ordered install plan via
ComponentInstaller::resolveInstallPlan()(dependencies first) - Copies each component folder/file to
componentsPath(skipsdependencies.json) - Runs
composer requirefor aggregatedcomposerentries (--no-external-depsskips this) - Publishes
css/jsassets and updates imports inapp.css/bladcn.js - Merges newly installed names into
resolvedinbladcn.json
Use --no-deps to install only the requested component without transitive registry dependencies.
ComponentRemover uses resolved plus DependencyResolver to detect orphans: internal components, Composer packages, and CSS/JS assets that no remaining installed component still needs. Orphan removal can be skipped with --no-orphans.
Copied components require the following in the host app (this CLI does not install them):
| Dependency | Purpose |
|---|---|
livewire/blaze |
@blaze directive |
mallardduck/blade-lucide-icons |
<x-ui.icon> |
@ailuracode/alpine-child |
Client-side as-child slot delegation |
resources/css/app.css |
Tailwind 4 + shadcn tokens |
resources/js/bladcn.js |
Alpine helpers (bladcnOnAlpine, scroll-area, copy button) |
resources/js/bladcn/carousel.js |
Embla carousel registration |
resources/views/partials/bladcn-boot.blade.php |
Layout hook before @stack('bladcn-scripts') |
| Artisan | Binary | Description |
|---|---|---|
bladcn:init |
bladcn init |
Create bladcn.json and publish base stubs |
bladcn:list |
bladcn list |
List registry components |
bladcn:add |
bladcn add |
Install components and dependencies |
bladcn:remove |
bladcn remove |
Remove components and orphan deps |
| Option | Description |
|---|---|
--all |
Install every component from the registry |
--no-deps |
Skip internal dependencies |
--no-external-deps |
Skip automatic composer require |
--overwrite |
Overwrite existing components |
--dry-run |
Preview without copying |
| Option | Description |
|---|---|
--no-orphans |
Do not remove orphan internal dependencies |
--yes |
Remove orphans without prompting |
--dry-run |
Preview without deleting |
| Option | Description |
|---|---|
--with-dark-mode |
CSS theme with .dark variables |
--css-file=app.css |
Main CSS file to import the theme into |
--theme-file=bladcn-theme.css |
Theme file name |
--skip-prompts |
Skip interactive prompts |
--skip-assets |
Only bladcn.json, no stubs |
--force |
Overwrite existing files |
Aligned with laravel-starter-kit: Laravel Pint (strict preset), Larastan (max level + bleedingEdge), Rector with rector-laravel.
See AGENTS.md for architecture notes and agent conventions.
composer lint # rector + pint (apply changes)
composer test # phpunit + lint check + phpstan
composer ci # alias for test
composer test:unit # phpunit
composer test:lint # pint --test + rector --dry-run
composer test:types # phpstan (Larastan, max level)
composer pint # format code
composer pint:check # check format without modifying
composer phpstan # static analysis
composer rector # apply refactorings
composer rector:check # suggested refactorings (dry-run)MIT. See LICENSE.