Open source · MIT

Shadcn-style Phoenix components AI assistants can actually use

Petal Components is the shadcn-style component system for Phoenix LiveView. Composable HEEx primitives (<.button>, <.modal>, <.table>) plus a hosted MCP server so Claude Code, Cursor, Codex, and Windsurf write idiomatic markup instead of inventing it.

30+ components Tailwind v4 Works in live and dead views MIT
1

Composable primitives

Every component is a plain HEEx tag. Use them in LiveView, dead views, or anywhere Phoenix renders. No JSX, no React, no build step beyond Tailwind.

2

You own the patterns

Override CSS classes with the pc-* prefix, swap in your own styles, fork what you don't like. The components are a starting point, not a cage.

3

AI agents know how to use it

The MCP server at mcp.petal.build exposes every component's real schema. AI assistants query it before writing HEEx, so they reach for <.button> instead of inventing markup.

Install in two steps

Step one runs once. Step two works in any Phoenix project, ever.

1. Install the MCP server
claude mcp add petal \
  --transport http \
  https://mcp.petal.build/mcp

Other AI tools: see the per-tool snippets below.

2. In your Phoenix project, tell your AI:
install petal_components

The agent calls get_install_instructions, then patches your mix.exs, app.css, and web module. Works in umbrella apps too.

Prefer to do it by hand? Manual install instructions are on the README.

Works with every major AI coding tool

The MCP runs over HTTP, so any AI tool with MCP support can connect. Use whatever you already have configured. Drop the canonical rules.md into your tool's rules system and the agent reaches for petal_components by default.

Claude Code

claude mcp add petal \
  --transport http \
  https://mcp.petal.build/mcp

Cursor

Add to .cursor/mcp.json:

{
  "mcpServers": {
    "petal": {
      "url": "https://mcp.petal.build/mcp"
    }
  }
}

Codex

Add to ~/.codex/config.toml:

[mcp_servers.petal]
url = "https://mcp.petal.build/mcp"

Windsurf

Add to Windsurf settings β†’ MCP servers. Point the URL at https://mcp.petal.build/mcp over HTTP.

Continue

Add to ~/.continue/config.json under mcpServers with the URL above.

Cline

Configure via the Cline MCP settings panel. URL: https://mcp.petal.build/mcp.

What writing UI looks like

Three primitives. The rest of the catalogue follows the same shape.

Form in a card
<.card>
  <.card_content>
    <.form for={@form} phx-submit="save">
      <.field field={@form[:name]} label="Name" />
      <.field field={@form[:email]} type="email" label="Email" />
      <.button type="submit">Save</.button>
    </.form>
  </.card_content>
</.card>
Modal with form
<.modal title="Edit user" max_width="md">
  <.form for={@form} phx-submit="save">
    <.field field={@form[:name]} label="Name" />
    <.button type="submit">Save</.button>
  </.form>
</.modal>
Table with row actions
<.table rows={@users}>
  <:col :let={user} label="Name">{user.name}</:col>
  <:col :let={user} label="Email">{user.email}</:col>
  <:col :let={user} label="">
    <.button size="xs" variant="outline"
      phx-click="edit" phx-value-id={user.id}>
      Edit
    </.button>
  </:col>
</.table>
Loading button
<.button loading={@saving} phx-click="save">
  Save
</.button>

What's in the box

30+ components covering the patterns a real Phoenix app needs. The MCP is always the canonical inventory - call list_components for the live list.

Layout & content

container, card, accordion, tabs, stepper, skeleton, breadcrumbs

Forms

field, text_input, select, checkbox, radio_group, switch, textarea, date_input, file_input

Actions

button, button_group, dropdown, menu, user_dropdown_menu

Feedback

alert, modal, slide_over, progress, spinner, rating

Data display

table, pagination, badge, avatar, marquee, icon, link, typography

More on the way

Tooltip, popover, combobox, command palette, toast. Tracked on the public roadmap.

How is this different from shadcn?

Same composable-primitives philosophy. Same idea that you own the patterns. Different runtime: HEEx not JSX, Tailwind v4 not Tailwind 3 + CSS variables, distributed as a Hex package instead of a CLI that copies source into your repo.

The big one that shadcn does not have yet: a hosted MCP server so AI coding assistants get the real component schema on demand. That is the difference between "AI guesses your component library" and "AI uses your component library correctly."

Want it all already wired up?

Petal Pro is the production Phoenix SaaS boilerplate built on these components. Auth (password + OAuth + passwordless + 2FA), multi-tenancy, Stripe billing, background jobs, the full set. Best reference for real-world composition of petal_components in a working SaaS.

Built on Petal Components
  • βœ“ Phoenix 1.8 + LiveView 1.0
  • βœ“ Stripe billing (subscriptions + one-time)
  • βœ“ Multi-tenant orgs with role-based access
  • βœ“ Oban background jobs and CLAUDE.md AI integration

Try it in your Phoenix project

One install command for the MCP. One prompt to your AI. The agent handles the rest.

claude mcp add petal --transport http https://mcp.petal.build/mcp
install petal_components