Skip to content

A renderer-first component workbench for server-rendered template systems (Twig, Nunjucks, PHP)

License

Notifications You must be signed in to change notification settings

southleft/trellis

Repository files navigation

Trellis

A component workbench for server-rendered template systems

Trellis is a renderer-first component workbench that treats server-rendered templates (Twig, Nunjucks, PHP) as first-class citizens. Unlike Storybook, which requires JavaScript framework adapters, Trellis is built natively for the PHP/CMS ecosystem.

Features

  • Renderer-First Architecture: Template engines are the primary abstraction, not JavaScript frameworks
  • Multiple Template Support: Nunjucks, Twig, and PHP renderers included
  • Metadata-Driven: Components described using JSON/YAML schemas
  • Component Composition: Reference components in specimen slots for true nesting without hardcoded HTML
  • Live Development Server: Hot reload with instant preview updates
  • Workbench UI: Sidebar navigation, preview panel, and auto-generated controls
  • Keyboard Shortcuts: Full keyboard navigation with ? for help overlay
  • Error Overlay: Detailed error display with source code context and line numbers
  • Accessibility Checks: Integrated axe-core for automatic accessibility validation
  • Static Build: Generate documentation sites deployable anywhere
  • MCP Server: AI-powered design system interaction with 40+ tools
  • Migration Tools: Migrate from Fractal, Pattern Lab, or Storybook

Quick Start

# Install dependencies
pnpm install

# Start the dev server (from example directory)
cd examples/basic
pnpm trellis serve

# Build static documentation
pnpm trellis build

# Migrate from another tool
pnpm trellis migrate --from fractal --source ./my-fractal-project

Target Platforms

  • WordPress themes (PHP, Timber/Twig)
  • Drupal themes (Twig)
  • Craft CMS (Twig)
  • Eleventy sites (Nunjucks)
  • Any PHP-based template system

Project Structure

trellis/
├── packages/
│   ├── core/              # Core types, config, component discovery
│   ├── cli/               # Command-line interface (serve, build, migrate)
│   ├── server/            # Development server with Hono
│   ├── mcp/               # MCP server for AI integration
│   └── renderers/
│       ├── nunjucks/      # Nunjucks template adapter
│       ├── twig/          # Twig template adapter (twig.js)
│       └── php/           # PHP subprocess renderer
├── schemas/               # JSON Schemas for validation
├── examples/
│   └── basic/             # Example project with Button and Card components
└── docs/                  # Documentation

Component Structure

Components are organized in directories with metadata files:

components/
└── button/
    ├── component.yml      # Component metadata and props schema
    ├── specimens.json     # Specimen definitions (variants)
    ├── button.njk         # Template file
    ├── button.docs.md     # Documentation (optional)
    └── button.css         # Styles (optional)

component.yml

name: Button
description: A versatile button component
category: Actions
status: stable
template: button.njk
props:
  type: object
  properties:
    label:
      type: string
      description: Button text
    variant:
      type: string
      enum: [primary, secondary, ghost, danger]
      default: primary

specimens.json

{
  "specimens": [
    {
      "name": "Primary Button",
      "args": {
        "label": "Click Me",
        "variant": "primary"
      }
    },
    {
      "name": "Secondary Button",
      "args": {
        "label": "Secondary",
        "variant": "secondary"
      }
    }
  ]
}

Component Composition

Specimens can reference other components in their slots, enabling true component nesting without hardcoded HTML:

# card.specimens.yaml
specimens:
  # Traditional string slot (backward compatible)
  - id: with-footer
    name: Card with Footer
    props:
      title: Action Card
    slots:
      footer: '<button class="btn">Click Me</button>'

  # Component reference in slot
  - id: with-button-component
    name: Card with Button
    props:
      title: Composed Card
    slots:
      footer:
        component: button
        specimen: primary
        props:
          label: Learn More

  # Multiple components in a slot
  - id: with-multiple-buttons
    name: Card with Actions
    props:
      title: Action Card
    slots:
      footer:
        - component: button
          props: { label: Save, variant: primary }
        - html: " "
        - component: button
          props: { label: Cancel, variant: ghost }

Composition is resolved at render time - the referenced components are rendered with their actual templates, then the HTML is passed to the parent component's slot. This works with any renderer (Nunjucks, Twig, PHP) since composition happens in core before rendering.

CLI Commands

trellis serve

Start the development server with hot reload.

trellis serve [options]

Options:
  -p, --port <port>    Port number (default: 3000)
  -c, --config <path>  Config file path

trellis build

Generate a static documentation site.

trellis build [options]

Options:
  -o, --output <path>  Output directory (default: dist)
  --minify             Minify output
  -c, --config <path>  Config file path

trellis migrate

Migrate components from another tool.

trellis migrate [options]

Options:
  --from <tool>        Source tool (fractal, pattern-lab, storybook)
  --source <path>      Path to source project
  --output <path>      Output directory (default: ./trellis-components)
  --dry-run            Analyze without writing files

trellis mcp

Start the MCP server for AI integration.

trellis mcp [options]

Options:
  -c, --config <path>  Config file path

trellis vrt

Run visual regression tests using Playwright.

trellis vrt [options]

Options:
  -u, --update           Update baselines instead of comparing
  -p, --port <number>    Port of running Trellis server (default: 3000)
  -o, --output <path>    Output directory for screenshots
  --components <list>    Comma-separated list of components to test
  --specimens <list>     Comma-separated list of specimens to test
  --theme <name>         Theme to use for captures
  --viewports <list>     Viewports to test (default: mobile,tablet,desktop)

trellis dist

Generate CMS distribution packages for WordPress, Drupal, or Craft CMS.

trellis dist --platform <platform> [options]

Options:
  --platform <type>      Target CMS platform (wordpress, drupal, craft) (required)
  -o, --output <path>    Output directory (default: ./dist-<platform>)
  --components <list>    Comma-separated list of components to include
  --include-specimens    Include specimen examples
  --include-docs         Include documentation (default: true)
  --blocks               WordPress: Generate Gutenberg blocks
  --sdc                  Drupal: Generate Single Directory Components (default: true)
  --text-domain <name>   WordPress: Text domain for translations
  --theme-name <name>    Drupal: Theme machine name
  -c, --config <path>    Config file path

Example:

# Generate WordPress theme components with Gutenberg blocks
trellis dist --platform wordpress --blocks

# Generate Drupal SDC components
trellis dist --platform drupal --theme-name my_theme

# Generate Craft CMS templates
trellis dist --platform craft

MCP Server Tools

The @trellis/mcp package provides AI-powered tools for design system interaction:

Component Tools

Tool Description
trellis_list_components List all components
trellis_get_component Get component details
trellis_search_components Search by natural language

Specimen Tools

Tool Description
trellis_list_specimens List component specimens
trellis_get_specimen Get specimen details
trellis_render_specimen Render specimen to HTML
trellis_render_component Render with custom props

Composition Tools

Tool Description
trellis_compose Generate compositions
trellis_create_node Create composition nodes
trellis_suggest_components Get suggestions for use case
trellis_validate Validate compositions
trellis_check_props Validate component props

Documentation Tools

Tool Description
trellis_get_component_docs Get component documentation
trellis_get_guidelines Get design guidelines
trellis_get_considerations Get implementation considerations
trellis_get_tokens Get design token documentation
trellis_get_patterns Get design patterns
trellis_search_docs Search documentation

Visual Regression Tools

Tool Description
trellis_list_baselines List visual baselines
trellis_visual_status Get visual regression status
trellis_update_baseline Update/create baseline
trellis_compare_visual Compare against baseline
trellis_delete_baseline Delete baseline
trellis_visual_config Get VRT configuration

Relationship Tools

Tool Description
trellis_get_dependencies Get component dependencies
trellis_get_dependents Get components that depend on this
trellis_dependency_graph Get full dependency graph
trellis_analyze_relationships Comprehensive relationship analysis
trellis_impact_analysis Analyze change impact
trellis_find_cycles Find circular dependencies

Governance Tools

Tool Description
trellis_governance_summary Get governance status overview
trellis_check_transition Check status transition validity
trellis_transition_requirements Get transition requirements
trellis_component_lifecycle Get component lifecycle info
trellis_deprecation_plan Create deprecation plan
trellis_list_by_status List components by status

Token Tools

Tool Description
trellis_tokens_overview Get token system overview
trellis_tokens_by_category List tokens by category
trellis_search_tokens Search for tokens
trellis_get_token Get token details
trellis_suggest_token Suggest token for value
trellis_color_palette Get color palette
trellis_spacing_scale Get spacing scale
trellis_reload_tokens Reload tokens from files

Configuration

Create a trellis.config.js in your project root:

export default {
  name: 'My Design System',
  description: 'Component library documentation',
  componentsPath: './components',
  outputPath: './dist',
  renderer: 'nunjucks', // or 'twig', 'php', 'auto'
  themes: [
    { name: 'default', file: './tokens/default.css', default: true }
  ],
  globals: {
    siteName: 'My Site'
  }
};

Development

# Install dependencies
pnpm install

# Build all packages
pnpm build

# Type check
pnpm typecheck

# Lint
pnpm lint

Implemented Features

M0: Project Foundation

  • Project scaffolding with Bun + TypeScript monorepo
  • Plugin system with renderer adapter interface
  • CLI foundation with Commander.js
  • File watcher abstraction
  • JSON Schemas for component and specimen validation
  • Configuration loader (trellis.config.js)

M1: Dev Server & UI

  • Nunjucks renderer implementation
  • Component discovery and indexing
  • Development server with Hono and WebSocket hot reload
  • Workbench UI with sidebar, preview, and source viewer
  • Controls panel auto-generated from props schema
  • Error overlay with source code and line numbers
  • Accessibility checks with axe-core
  • Static site generator
  • Keyboard shortcuts with help overlay

M2: Template Renderers

  • Twig renderer (twig.js with custom filters)
  • PHP subprocess renderer (Bun.spawn bridge)

M3: AI Integration (MCP)

  • MCP server with component introspection tools
  • Documentation context tools
  • Visual regression hooks
  • Component relationship analysis
  • Governance & status workflow
  • Design token integration

M4: Migration Tools

  • Fractal migrator (Handlebars → Nunjucks)
  • Pattern Lab migrator (Mustache → Nunjucks)
  • Storybook migrator (stories → specimens)

Roadmap

  • Search functionality in UI
  • Keyboard shortcuts
  • Visual regression image capture (Playwright integration)
  • Static site search (full-text with fuzzy matching)
  • CMS distribution packages (WordPress, Drupal, Craft)
  • Component versioning
  • Sass/SCSS compilation for component styles

License

MIT

About

A renderer-first component workbench for server-rendered template systems (Twig, Nunjucks, PHP)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published