PHPackages                             ducrot/twigcn-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. ducrot/twigcn-bundle

ActiveSymfony-bundle[Templating &amp; Views](/categories/templating)

ducrot/twigcn-bundle
====================

Beautiful, accessible UI components for Symfony &amp; Twig. Inspired by shadcn/ui.

v1.1.1(1mo ago)02MITPHPPHP &gt;=8.2

Since May 10Pushed 1mo agoCompare

[ Source](https://github.com/ducrot/twigcn-bundle)[ Packagist](https://packagist.org/packages/ducrot/twigcn-bundle)[ RSS](/packages/ducrot-twigcn-bundle/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (9)Versions (6)Used By (0)

TwigcnBundle
============

[](#twigcnbundle)

[![CI](https://camo.githubusercontent.com/498858c603c1c4cddb31b775883957a60eea69d72f2bea68be6f6ca482195f1c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f647563726f742f74776967636e2f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d4349266c6f676f3d676974687562)](https://github.com/ducrot/twigcn/actions/workflows/tests.yml)[![Packagist](https://camo.githubusercontent.com/a28f1a90b611f9b712806ece85cd292c380907b58ad6e871a26109b2553dcdbc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f647563726f742f74776967636e2d62756e646c652e7376673f6c6162656c3d7061636b6167697374)](https://packagist.org/packages/ducrot/twigcn-bundle)[![PHP](https://camo.githubusercontent.com/e084380ce870ea8bad95f4e4f04e5becfba754ab2d5593ceb01ee89bf057cdd7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f647563726f742f74776967636e2d62756e646c652e737667)](composer.json)[![License](https://camo.githubusercontent.com/e99e88e215abb6bb0e7e6c2b23176a0460bb487fb90cc6f140f34616fc9a6338/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f647563726f742f74776967636e2d62756e646c652e737667)](LICENSE)

> **Read-only mirror.** This repository is a subtree split of [`ducrot/twigcn`](https://github.com/ducrot/twigcn) and exists so Composer/Packagist can ship the bundle. Issues and pull requests are intentionally disabled here — please open them in the [main repository](https://github.com/ducrot/twigcn/issues).

Beautiful, accessible UI components for Symfony &amp; Twig. Inspired by shadcn/ui, built for Symfony.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Symfony 7.0+
- Node.js 22+ (for asset compilation)
- Tailwind CSS 4.0+

Installation
------------

[](#installation)

### Step 1: Install the PHP Bundle

[](#step-1-install-the-php-bundle)

```
composer require ducrot/twigcn-bundle
```

The bundle registers automatically via Symfony Flex.

### Step 2: Install the NPM Package

[](#step-2-install-the-npm-package)

```
npm install @ducrot/twigcn-ui
```

If your project uses **AssetMapper** (the Symfony 7.x `webapp` default), also expose the package to the importmap so it can be imported from JavaScript:

```
php bin/console importmap:require @ducrot/twigcn-ui
```

Webpack Encore projects pick up `node_modules` automatically and do not need this step.

### Step 3: Configure Your CSS

[](#step-3-configure-your-css)

Tailwind processes a source file into a static stylesheet. Keep the source out of `assets/` (so AssetMapper does not also serve it raw) — for example `tailwind.css` at the project root:

```
@import "tailwindcss";
@import "@ducrot/twigcn-ui/styles";

/* IMPORTANT: Scan bundle templates for Tailwind classes */
@source "../vendor/ducrot/twigcn-bundle/templates";

/* Scan your own templates */
@source "./templates/**/*.html.twig";

/* Optional: Override theme variables */
:root {
    --primary: #6b5fc3;
    --primary-foreground: #ffffff;
    --radius: 0.5rem;
}
```

Then build with the Tailwind CLI (Symfony does not bundle CSS itself):

```
npx @tailwindcss/cli -i tailwind.css -o assets/styles/app.css --watch
```

The compiled output at `assets/styles/app.css` is what AssetMapper or Encore serves. Re-run the build whenever templates or styles change (or use `--watch` during development).

### Step 4: Register Stimulus Controllers

[](#step-4-register-stimulus-controllers)

**Option A: Automatic (Symfony UX)**

Create or update `assets/controllers.json`:

```
{
    "controllers": {
        "@ducrot/twigcn-ui": {
            "accordion": { "enabled": true },
            "carousel": { "enabled": true },
            "combobox": { "enabled": true },
            "command": { "enabled": true },
            "custom-select": { "enabled": true },
            "dialog": { "enabled": true },
            "drawer": { "enabled": true },
            "drawer-trigger": { "enabled": true },
            "popover": { "enabled": true },
            "slider": { "enabled": true },
            "tabs": { "enabled": true },
            "theme": { "enabled": true },
            "toaster": { "enabled": true },
            "tooltip": { "enabled": true }
        }
    }
}
```

**Option B: Manual Registration**

In a Symfony project that uses StimulusBundle (the default in the `webapp`recipe), register the controllers on the existing Stimulus application from `assets/bootstrap.js` (or `assets/stimulus_bootstrap.js`) — do not start a second one:

```
import { startStimulusApp } from '@symfony/stimulus-bundle';
import { registerControllers } from '@ducrot/twigcn-ui';

const app = startStimulusApp();
registerControllers(app);
```

For non-Symfony or fully custom Stimulus setups (e.g. Webpack Encore without StimulusBundle):

```
import { Application } from '@hotwired/stimulus';
import { registerControllers } from '@ducrot/twigcn-ui';

const app = Application.start();
registerControllers(app);
```

### Alternative: Vite via `pentatrion/vite-bundle`

[](#alternative-vite-via-pentatrionvite-bundle)

For projects that prefer a real bundler (recommended for Tailwind + TypeScript

- Stimulus), use [`pentatrion/vite-bundle`](https://github.com/lhapaipai/vite-bundle) together with [`vite-plugin-symfony`](https://github.com/lhapaipai/vite-plugin-symfony) and `@tailwindcss/vite`. This is the setup the [demo app](../demo) in this repository uses. Vite replaces both the Tailwind CLI build (Tailwind 4 runs as a Vite plugin) and the StimulusBundle controller registration (`vite-plugin-symfony` provides its own Stimulus integration).

Install (replaces Steps 2–4 above):

```
composer require pentatrion/vite-bundle ducrot/twigcn-bundle
npm install @ducrot/twigcn-ui
npm install --save-dev vite vite-plugin-symfony @tailwindcss/vite tailwindcss
```

`vite.config.ts`:

```
import { defineConfig } from 'vite';
import tailwindcss from '@tailwindcss/vite';
import symfonyPlugin from 'vite-plugin-symfony';
import { resolve } from 'path';

export default defineConfig({
    plugins: [
        symfonyPlugin({ stimulus: true }),
        tailwindcss(),
    ],
    publicDir: false,
    build: {
        manifest: true,
        outDir: 'public/build',
        rollupOptions: {
            input: { app: resolve(__dirname, 'assets/app.ts') },
        },
    },
});
```

`assets/app.ts`:

```
import './app.css';

import { Application } from '@hotwired/stimulus';
import { registerControllers } from '@ducrot/twigcn-ui';

const app = Application.start();
registerControllers(app);
```

`assets/app.css`:

```
@import "tailwindcss";
@import "@ducrot/twigcn-ui/styles";

/* Scan bundle templates *and* PHP component classes for Tailwind classes —
 * variant strings live in PHP, so the @source must include `src` too. */
@source "../vendor/ducrot/twigcn-bundle/templates";
@source "../vendor/ducrot/twigcn-bundle/src";
@source "../templates";
```

In your base Twig template:

```
{% block stylesheets %}
    {{ vite_entry_link_tags('app') }}
{% endblock %}

{% block javascripts %}
    {{ vite_entry_script_tags('app') }}
{% endblock %}
```

Then `npm run dev` for HMR or `npm run build` for production. The bundle's [`config/packages/pentatrion_vite.yaml`](../demo/config/packages/pentatrion_vite.yaml)in the demo shows the minimal Symfony-side configuration.

Usage
-----

[](#usage)

Components are namespaced under `Twigcn:` in Twig (Symfony UX TwigComponent prefixes third-party bundle components with their bundle namespace):

```
{# Button #}
Click me

{# Button as link #}

    Go to Dashboard

{# Dialog (uses the native HTML  element) #}

    Open Dialog

        Confirm Action
        Are you sure you want to proceed?

            Cancel

            Confirm

{# Drawer (open via the dedicated DrawerTrigger) #}

    Open Settings

            Settings

        Drawer content goes here.

            Close

{# Tabs #}

        Account
        Password

        Manage your account settings here.

        Change your password here.

{# Accordion #}

        Yes. It adheres to the WAI-ARIA design pattern.

        Yes. It comes with default styles using Tailwind CSS.

{# Form elements #}

    Email

{# Alerts #}

    Error! Something went wrong.

```

Available Components
--------------------

[](#available-components)

### Form

[](#form)

- `Button` - Clickable button with variants
- `ButtonGroup` - Group of related buttons
- `Checkbox` - Checkbox input
- `ChoiceCard` - Selectable card-style option
- `Combobox` - Autocomplete input with suggestions
- `CustomSelect` - Enhanced select with search
- `Field` - Form field wrapper
- `Form` - Form container
- `Input` - Text input field
- `InputGroup` - Input with prefix/suffix slots
- `Label` - Form label
- `Radio` / `RadioGroup` - Radio buttons
- `Select` - Native select dropdown
- `Slider` - Range slider
- `Switch` - Toggle switch
- `Textarea` - Multi-line text input

### Layout

[](#layout)

- `Accordion` / `AccordionItem` - Collapsible sections
- `Breadcrumb` / `BreadcrumbItem` / `BreadcrumbSeparator` - Breadcrumb navigation
- `Card` - Container with border and shadow
- `Pagination` / `PaginationItem` - Page navigation
- `Sidebar` - Collapsible sidebar navigation (with `SidebarHeader`, `SidebarContent`, `SidebarFooter`, `SidebarGroup`, `SidebarMenu`, `SidebarMenuItem`, `SidebarMenuButton`)
- `Table` - Data table
- `Tabs` / `TabsList` / `TabsTrigger` / `TabsContent` - Tabbed content panels

### Overlay

[](#overlay)

- `Command` - Command palette (with `CommandInput`, `CommandList`, `CommandGroup`, `CommandItem`, `CommandShortcut`, `CommandSeparator`, `CommandEmpty`)
- `Dialog` - Modal dialog (use `:closeOnBackdrop="false"` for alert-dialog behavior)
- `Drawer` - Slide-out panel (with `DrawerTrigger`, `DrawerContent`, `DrawerHeader`, `DrawerFooter`, `DrawerClose`)
- `DropdownMenu` / `DropdownMenuTrigger` / `DropdownMenuContent` / `DropdownMenuItem` - Dropdown menu
- `Popover` / `PopoverTrigger` / `PopoverContent` - Floating content on trigger
- `Tooltip` - Hover tooltip

### Feedback

[](#feedback)

- `Alert` - Alert messages
- `Avatar` - User avatar
- `Badge` - Status badges
- `Carousel` - Image/content carousel (with `CarouselContent`, `CarouselItem`, `CarouselNext`, `CarouselPrevious`)
- `Empty` - Empty-state placeholder
- `Item` - Generic content item
- `Kbd` - Keyboard key display
- `Progress` - Progress bar
- `Skeleton` - Loading placeholder
- `Spinner` - Loading spinner
- `ThemeSwitcher` - Dark/light mode toggle
- `Toast` / `Toaster` (with `ToastTitle`, `ToastDescription`, `ToastClose`) - Toast notifications

### Naming Notes

[](#naming-notes)

A few PHP class names differ from their Twig component tag because the tag name is reserved or already taken in PHP:

Twig tagPHP class```EmptyState````SwitchComponent````FieldForm`Theming
-------

[](#theming)

Components use CSS custom properties for theming. Override these in your CSS:

```
:root {
    /* Colors */
    --background: #ffffff;
    --foreground: #333333;
    --primary: #6b5fc3;
    --primary-foreground: #ffffff;
    --secondary: #e7e7ea;
    --secondary-foreground: #4e4d58;
    --muted: #ececef;
    --muted-foreground: #6c6b75;
    --accent: #d6d9f0;
    --accent-foreground: #433669;
    --destructive: #ef4444;
    --destructive-foreground: #ffffff;
    --border: #dbdadf;
    --input: #dbdadf;
    --ring: #6b5fc3;

    /* Radius */
    --radius: 0.375rem;
}

/* Dark mode */
.dark {
    --background: #171717;
    --foreground: #e5e5e5;
    /* ... other dark mode overrides */
}
```

Dark Mode
---------

[](#dark-mode)

Toggle dark mode by adding/removing the `dark` class on the `` element:

```

```

Or manually:

```
document.documentElement.classList.toggle('dark');
```

Contributing &amp; Issues
-------------------------

[](#contributing--issues)

Development happens in [`ducrot/twigcn`](https://github.com/ducrot/twigcn). Open issues at  and pull requests against the same repo. Release notes are tracked in the monorepo's [CHANGELOG](https://github.com/ducrot/twigcn/blob/main/CHANGELOG.md).

License
-------

[](#license)

MIT License

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance94

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

5

Last Release

30d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/58b40adf73699240182a2fa64cd0e77c8ecb289927c95c60cc40d2188b48ae21?d=identicon)[ducrot](/maintainers/ducrot)

---

Tags

symfonytwiguicomponentstailwindstimulus

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/ducrot-twigcn-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/ducrot-twigcn-bundle/health.svg)](https://phpackages.com/packages/ducrot-twigcn-bundle)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
