Agent skill

Live Component

by smnandre in smnandre/symfony-ux-skills

Symfony UX LiveComponent for reactive server-rendered UI -- components that re-render via AJAX on user interaction, zero JavaScript required.

MITAuto-check passedFrontend & Design

Install Live Component

skills CLI
$ npx skills add smnandre/symfony-ux-skills --skill live-component -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install smnandre/symfony-ux-skills live-component --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/smnandre/symfony-ux-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/live-component .claude/skills/live-component && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
live-component
GitHub stars
180
Token cost
~3.3k tokens
SKILL.md length
471 words
Files
4 (incl. references)
Skills in repo
7
Repo updated
First seen
Licence
MIT

At a glance

Symfony UX LiveComponent for reactive server-rendered UI -- components that re-render via AJAX on user interaction, zero JavaScript required.

  • Building live search
  • SKILL.md covers When to Use LiveComponent, Installation, Quick Reference and Basic Example, plus 14 more sections
  • Calls composer
  • Real-time filtering

What it does

Live Component is an agent skill from smnandre/symfony-ux-skills. Symfony UX LiveComponent for reactive server-rendered UI -- components that re-render via AJAX on user interaction, zero JavaScript required. Use when building live search, real-time filtering, dynamic forms, inline validation, dependent selects, auto-save, polling, deferred/lazy rendering, or any UI that updates itself based on user input. Code triggers: AsLiveComponent, LiveProp, LiveAction, data-model, data-loading, data-live-action-url, ComponentWithFormTrait, LiveListener, emit, defer, lazy, polling. Also…

Its SKILL.md is about 3.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `references/api.md`, `references/gotchas.md` and `references/patterns.md`).

It sits in Frontend & Design. It works with Symfony, JavaScript, PHP and Google Gemini. The repository describes itself as: Symfony UX skills for Claude, Gemini, Codex, ... Live Component, Twig Component, Turbo, Stimulus. The licence is MIT.

When your agent uses it

  • Building live search
  • Real-time filtering
  • Inline validation
  • Dependent selects

Example prompts

  • “how to build a search that filters as I type”
  • “how to validate a form in real-time”
  • “how to make a reactive component in PHP”
  • “/live-component”

What it can do on your machine

Read from SKILL.md and the folder at commit 1e99301. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • composer

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Live Component loads about 3.3k tokens when it runs, and up to ~12k if it reads all its reference files. Until then it costs about 253 tokens; SKILL.md has 471 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~253
When it runs · the whole SKILL.md, loaded when a task matches
~3.3k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~12k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from smnandre/symfony-ux-skills at commit 1e99301, republished under its MIT licence (© smnandre). 471 words, ~3,320 tokens.

Download SKILL.mdSave it as .claude/skills/live-component/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
live-component
description
Symfony UX LiveComponent for reactive server-rendered UI -- components that re-render via AJAX on user interaction, zero JavaScript required. Use when building live search, real-time filtering, dynamic forms, inline validation, dependent selects, auto-save, polling, deferred/lazy rendering, or any UI that updates itself based on user input. Code triggers: AsLiveComponent, LiveProp, LiveAction, data-model, data-loading, data-live-action-url, ComponentWithFormTrait, LiveListener, emit, defer, lazy, polling. Also trigger when the user asks "how to build a search that filters as I type", "how to validate a form in real-time", "how to make a reactive component in PHP", "how to build dependent selects", "how to defer component rendering", "how to communicate between components via emit", "how to bind a form to a LiveComponent". Do NOT trigger for static reusable UI without reactivity (use twig-component), pure client-side JS behavior (use stimulus), or page-level navigation (use turbo).
license
MIT
metadata.author
Simon Andre
metadata.email
smn.andre@gmail.com
metadata.url
https://smnandre.dev
metadata.version
1.2.0

LiveComponent

TwigComponents that re-render dynamically via AJAX. Build reactive UIs in PHP + Twig with zero JavaScript. Every user interaction triggers a server round-trip that re-renders the component and morphs the DOM.

When to Use LiveComponent

Use LiveComponent when a component's output depends on user interaction -- search results that update as you type, forms with real-time validation, filters that refine a list, anything where the UI needs to change based on user input and that change requires server-side data or logic.

If the component never re-renders after initial load, use TwigComponent instead (less overhead, no AJAX). If the interaction is purely client-side (toggle, animation), use Stimulus instead.

Installation

bash
composer require symfony/ux-live-component

Quick Reference

#[AsLiveComponent]           Make component live (re-renderable via AJAX)
#[LiveProp]                  State that persists across re-renders
#[LiveProp(writable: true)]  State that the frontend can modify
#[LiveAction]                Server method callable from frontend
data-model="prop"            Two-way bind input to LiveProp
data-action="live#action"    Call LiveAction on event
data-loading="..."           Show/hide/style elements during AJAX
{{ attributes }}             REQUIRED on root element (wires the Stimulus controller)

Basic Example

php
// src/Twig/Components/Counter.php
namespace App\Twig\Components;

use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\DefaultActionTrait;

#[AsLiveComponent]
final class Counter
{
    use DefaultActionTrait;

    #[LiveProp]
    public int $count = 0;

    #[LiveAction]
    public function increment(): void
    {
        $this->count++;
    }

    #[LiveAction]
    public function decrement(): void
    {
        $this->count--;
    }
}
twig
{# templates/components/Counter.html.twig #}
<div {{ attributes }}>
    <button data-action="live#action" data-live-action-param="decrement">-</button>
    <span>{{ count }}</span>
    <button data-action="live#action" data-live-action-param="increment">+</button>
</div>

Critical: The root element must render {{ attributes }}. This injects the Stimulus data-controller="live" attribute that makes the whole system work. Without it, nothing re-renders.

LiveProp

State that persists between AJAX re-renders. Props are serialized to the frontend and sent back on every request.

Basic Props
php
#[LiveProp]
public string $query = '';

#[LiveProp]
public int $page = 1;

#[LiveProp]
public ?User $user = null;  // Entities auto-hydrate by ID
Writable Props (Two-way Binding)

Only writable props can be modified from the frontend via data-model:

php
#[LiveProp(writable: true)]
public string $search = '';

// Writable with specific fields for objects
#[LiveProp(writable: ['email', 'name'])]
public User $user;
URL Binding

Sync a prop to a URL query parameter -- enables bookmarkable/shareable state:

php
#[LiveProp(writable: true, url: true)]
public string $query = '';
// URL becomes: ?query=search+term

// Custom parameter name
use Symfony\UX\LiveComponent\Metadata\UrlMapping;

#[LiveProp(writable: true, url: new UrlMapping(as: 'q'))]
public string $query = '';
// URL becomes: ?q=search+term
Hydration

Doctrine entities auto-hydrate by ID. For custom types:

php
#[LiveProp(hydrateWith: 'hydrateStatus', dehydrateWith: 'dehydrateStatus')]
public Status $status;

public function hydrateStatus(string $value): Status
{
    return Status::from($value);
}

public function dehydrateStatus(Status $status): string
{
    return $status->value;
}

Data Binding (data-model)

Bind inputs to writable LiveProps. When the input changes, the component re-renders with the new value.

twig
{# Re-render on change (default) #}
<input type="text" data-model="search">

{# Debounced -- wait 300ms after last keystroke #}
<input type="text" data-model="debounce(300)|search">

{# Only update on blur #}
<input type="text" data-model="on(blur)|search">

{# Update model but don't re-render yet #}
<input type="text" data-model="norender|search">

{# Checkbox, radio, select #}
<input type="checkbox" data-model="enabled">
<select data-model="category">
    <option value="1">Category 1</option>
</select>
Validation Modifiers
twig
{# Only re-render when input meets criteria #}
<input data-model="minlength(3)|search">
<input data-model="maxlength(100)|bio">
<input data-model="min(0)|quantity">
<input data-model="max(999)|price">

LiveAction

Server methods callable from the frontend:

php
#[LiveAction]
public function save(): void
{
    // Called via data-action="live#action" data-live-action-param="save"
}

#[LiveAction]
public function delete(#[LiveArg] int $id): void
{
    // With typed argument via data-live-id-param="123"
}
Calling Actions from Twig
twig
{# Button click #}
<button data-action="live#action" data-live-action-param="save">Save</button>

{# With arguments #}
<button
    data-action="live#action"
    data-live-action-param="delete"
    data-live-id-param="{{ item.id }}"
>Delete</button>

{# Form submit (prevent default) #}
<form data-action="live#action:prevent" data-live-action-param="submit">

Search Example (Complete)

php
#[AsLiveComponent]
final class ProductSearch
{
    use DefaultActionTrait;

    #[LiveProp(writable: true, url: true)]
    public string $query = '';

    #[LiveProp(writable: true)]
    public string $category = '';

    public function __construct(
        private readonly ProductRepository $products,
    ) {}

    public function getProducts(): array
    {
        return $this->products->search($this->query, $this->category);
    }
}
twig
<div {{ attributes }}>
    <input type="search" data-model="debounce(300)|query" placeholder="Search...">

    <select data-model="category">
        <option value="">All Categories</option>
        {% for cat in categories %}
            <option value="{{ cat.id }}">{{ cat.name }}</option>
        {% endfor %}
    </select>

    <div data-loading="addClass(opacity-50)">
        {% for product in this.products %}
            <div>{{ product.name }}</div>
        {% endfor %}
    </div>
</div>

Loading States

Show visual feedback during AJAX re-renders:

twig
{# Add/remove class while loading #}
<div data-loading="addClass(opacity-50)">
<div data-loading="removeClass(hidden)">

{# Show/hide element while loading #}
<span data-loading="show">Loading...</span>
<div data-loading="hide">Content</div>

{# Disable button while loading #}
<button data-loading="attr(disabled)">Submit</button>

{# Scoped to specific action or model #}
<span data-loading="action(save)|show">Saving...</span>
<span data-loading="model(query)|show">Searching...</span>

{# Delay before showing (avoid flicker on fast responses) #}
<span data-loading="delay(300)|show">Loading...</span>

Form Integration

php
use Symfony\Component\Form\FormInterface;
use Symfony\UX\LiveComponent\ComponentWithFormTrait;

#[AsLiveComponent]
final class RegistrationForm extends AbstractController
{
    use DefaultActionTrait;
    use ComponentWithFormTrait;

    #[LiveProp]
    public ?User $initialFormData = null;

    protected function instantiateForm(): FormInterface
    {
        return $this->createForm(UserType::class, $this->initialFormData);
    }

    #[LiveAction]
    public function save(EntityManagerInterface $em): Response
    {
        $this->submitForm();
        $user = $this->getForm()->getData();
        $em->persist($user);
        $em->flush();

        return $this->redirectToRoute('app_success');
    }
}
twig
<div {{ attributes }}>
    {{ form_start(form, {
        attr: {
            'data-action': 'live#action:prevent',
            'data-live-action-param': 'save'
        }
    }) }}

    {{ form_row(form.email) }}
    {{ form_row(form.password) }}

    <button type="submit" data-loading="attr(disabled)">Register</button>

    {{ form_end(form) }}
</div>
Real-time Validation
twig
{{ form_row(form.email, {
    attr: {'data-model': 'on(blur)|validatedFields'}
}) }}

Component Communication

Emit Events (Child to Parent)
php
use Symfony\UX\LiveComponent\ComponentToolsTrait;

#[AsLiveComponent]
final class ChildComponent
{
    use DefaultActionTrait;
    use ComponentToolsTrait;

    #[LiveAction]
    public function save(): void
    {
        // ... save logic
        $this->emit('itemSaved', ['id' => $this->item->getId()]);
    }
}
Listen to Events (Parent)
php
use Symfony\UX\LiveComponent\Attribute\LiveListener;

#[AsLiveComponent]
final class ParentComponent
{
    use DefaultActionTrait;

    #[LiveListener('itemSaved')]
    public function onItemSaved(#[LiveArg] int $id): void
    {
        // Component re-renders automatically after this method
    }
}
Browser Events (LiveComponent to Stimulus)
php
$this->dispatchBrowserEvent('modal:close');
html
<!-- Stimulus picks it up -->
<div data-action="modal:close@window->modal#close">

Polling

Auto-refresh a component on a timer:

twig
{# Default: every 2 seconds #}
<div {{ attributes }} data-poll>

{# Custom interval #}
<div {{ attributes }} data-poll="delay(5000)">

{# Call specific action on each poll #}
<div {{ attributes }} data-poll="action(refresh)">

Lazy / Deferred Loading

twig
{# Load component after page renders (deferred AJAX call) #}
<twig:HeavyComponent defer />

{# Load when element scrolls into viewport (IntersectionObserver) #}
<twig:HeavyComponent lazy />

{# Placeholder while loading #}
<twig:HeavyComponent lazy>
    <div>Loading...</div>
</twig:HeavyComponent>

Data Preservation

twig
{# Prevent re-render from modifying this subtree #}
<div data-live-ignore>
    {# Third-party widget, contenteditable, etc. #}
</div>

{# Preserve specific attribute during DOM morph #}
<input data-live-preserve="value">

Computed Properties

Same as TwigComponent -- getXxx() methods are accessible as this.xxx. Use computed.xxx for caching within a single render cycle (avoids calling the method multiple times in a loop).

php
public function getFilteredItems(): array
{
    return array_filter($this->items, fn($i) => $i->isActive());
}
twig
{# Uncached -- called each time #}
{% for item in this.filteredItems %}

{# Cached within this render #}
{% for item in computed.filteredItems %}
Show full SKILL.md (175 more words)Show less

Key Principles

Every interaction is a server round-trip. LiveComponent is not a client-side framework. Each re-render sends the full component state to the server, re-executes PHP, and morphs the DOM. For high-frequency interactions (drag-and-drop, real-time drawing), use Stimulus instead.

Keep components small. Large components with many LiveProps and complex templates are slow to re-render. Split into smaller, focused components that communicate via emit/listen.

Use norender and on(blur) to reduce requests. Not every keystroke needs a server call. Debounce text inputs, defer binding to blur events for fields that don't need instant feedback.

{{ attributes }} on root element is non-negotiable. Without it, the live behavior Stimulus controller is never attached and nothing works.

References

See Also

  • UX Map provides ComponentWithMapTrait for reactive maps inside LiveComponents. The map automatically updates when LiveProps change.
  • UX Icons work inside LiveComponent templates with no special setup -- icons re-render on each server round-trip like any other Twig markup.

© smnandre, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 3 other files (references) in skills/live-component of smnandre/symfony-ux-skills.

  • SKILL.md
  • references/api.md
  • references/gotchas.md
  • references/patterns.md

Open the folder on GitHubat commit 1e99301

Compare with similar skills

Live Component next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Live Component compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Live Component this skillsmnandre/symfony-ux-skills180—~3.3kAutomated safety check: PassMIT
Tailwindcss Developmentanonaddy/anonaddy4.9k10 repos~865Automated safety check: PassMIT
Tailwindcss Developmentcachethq/core230—~1.1kAutomated safety check: PassMIT
Alsacreations Guidelinesalsacreations/kiwipedia338—~900Automated safety check: PassNone
Figma use_figma Plugin API Ruleswarpdotdev/warp65k4 repos~4.4kAutomated safety check: PassAGPL-3.0
MCP Developmentcoollabsio/coolify63k1 repos~949Automated safety check: PassMIT

Similar skills

  • Tailwindcss Development

    anonaddy/anonaddy

    Always invoke when the user's message includes 'tailwind' in any form.

    4.9k GitHub starsUsed in 10 repos~865 tokens
    Frontend & DesignAuto-check passed
  • A skill your agent uses for Cachet Tailwind CSS and UI styling: Blade utility classes, public status-page components, Filament dashboard theme work, responsive layout, dark mode, spacing…

    230 GitHub stars~1.1k tokensUpdated 2 days ago
    Frontend & DesignAuto-check passed
  • Alsacreations Guidelines

    alsacreations/kiwipedia

    Guidelines techniques et conventions internes d'Alsacréations (Kiwipedia) — HTML, CSS, JavaScript, TypeScript, Vue.js, WordPress, PHP/MySQL, accessibilité, performance, SEO, RGPD, écoconception…

    338 GitHub stars~900 tokensUpdated 18 days ago
    DatabasesAuto-check passed
  • Required groundwork before any use_figma call: the rules and reference files for running JavaScript in a Figma file through the Plugin API without common failures.

    65k GitHub starsUsed in 4 repos~4.4k tokens
    Frontend & DesignAuto-check passed
  • MCP Development

    coollabsio/coolify

    A skill your agent uses for Laravel MCP development. An agent skill from coollabsio/coolify.

    63k GitHub starsUsed in 1 repo~949 tokens
    Frontend & DesignAuto-check passed
  • GSAP Core Animation

    greensock/gsap-skills

    Covers the GSAP core API for tweens, easing, staggers, defaults and matchMedia, and when to choose GSAP over CSS animations or other JavaScript animation libraries.

    16k GitHub starsUsed in 4 repos~3.7k tokens
    Frontend & DesignAuto-check passed

More from smnandre/symfony-ux-skills

  • Stimulus

    smnandre/symfony-ux-skills

    Stimulus JS framework for Symfony UX -- client-side behavior via HTML data attributes, zero server round-trips.

    180 GitHub stars~2.1k tokensUpdated 3 mo ago
    Auto-check passed
  • Turbo

    smnandre/symfony-ux-skills

    Hotwire Turbo for Symfony UX -- SPA-like speed with zero JavaScript.

    180 GitHub stars~2.9k tokensUpdated 3 mo ago
    Auto-check passed
  • Twig Component

    smnandre/symfony-ux-skills

    Symfony UX TwigComponent for reusable UI building blocks -- server-rendered components with PHP classes and Twig templates.

    180 GitHub stars~2.5k tokensUpdated 3 mo ago
    Auto-check passed
  • UX Icons

    smnandre/symfony-ux-skills

    Symfony UX Icons for rendering SVG icons in Twig templates. An agent skill from smnandre/symfony-ux-skills.

    180 GitHub stars~1.9k tokensUpdated 3 mo ago
    Auto-check passed
  • UX Map

    smnandre/symfony-ux-skills

    Symfony UX Map for interactive maps with Leaflet or Google Maps in Symfony.

    180 GitHub stars~3k tokensUpdated 3 mo ago
    Auto-check: notes
  • Symfony UX

    smnandre/symfony-ux-skills

    Symfony UX frontend stack -- decision tree and orchestrator for choosing between Stimulus, Turbo, TwigComponent, LiveComponent, UX Icons, and UX Map.

    180 GitHub stars~3.4k tokensUpdated 3 mo ago
    Auto-check passed

Questions about Live Component

What does Live Component do?

Symfony UX LiveComponent for reactive server-rendered UI -- components that re-render via AJAX on user interaction, zero JavaScript required. Live Component is an agent skill from smnandre/symfony-ux-skills. Symfony UX LiveComponent for reactive server-rendered UI -- components that re-render via AJAX on user interaction, zero JavaScript required.

When should I use Live Component?

Live Component fits situations like: building live search; real-time filtering; inline validation; dependent selects.

How do I install Live Component in Claude Code?

Run `npx skills add smnandre/symfony-ux-skills --skill live-component -a claude-code`. Or copy the skill folder (skills/live-component in smnandre/symfony-ux-skills) into .claude/skills/live-component in your project. Claude Code loads it when a task matches its description.

How do I install Live Component in Codex?

Run `npx skills add smnandre/symfony-ux-skills --skill live-component -a codex`. Or copy the skill folder (skills/live-component in smnandre/symfony-ux-skills) into .agents/skills/live-component in your project. Codex loads it when a task matches its description.

Can I use Live Component in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add smnandre/symfony-ux-skills --skill live-component -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/live-component, .gemini/skills/live-component, .github/skills/live-component and .opencode/skills/live-component in your project.

What does Live Component need to run?

Going by SKILL.md and its folder, Live Component needs the command-line tools its instructions call (composer).

Does Live Component access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Live Component safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Live Component use?

Live Component is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Live Component use?

About 3.3k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 8.5k tokens, read only when the agent opens those files.

What are the alternatives to Live Component?

Skills that share tags, products or a category with Live Component: Tailwindcss Development (anonaddy/anonaddy, 4.9k stars), Tailwindcss Development (cachethq/core, 230 stars), Alsacreations Guidelines (alsacreations/kiwipedia, 338 stars) and Figma use_figma Plugin API Rules (warpdotdev/warp, 65k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Live Component?

smnandre (a GitHub user) maintains it in smnandre/symfony-ux-skills, which has 180 GitHub stars. The repository holds 7 skills in this directory. The repository was last updated on June 14, 2026.

Source: smnandre/symfony-ux-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.