Shadcn-style Phoenix components that AI assistants can actually use.
Live docs · MCP server · Rules for AI tools · vs shadcn
Petal Components gives Phoenix LiveView apps a shadcn-style set of HEEx components: buttons, forms, modals, tables, cards, and more. They are built with Tailwind v4 and work in live or dead views.
The companion piece is a hosted MCP server at mcp.petal.build that exposes every component's real schema to AI coding tools. Install it once and Claude Code, Cursor, Codex, and Windsurf reach for the existing components instead of inventing raw Tailwind markup from training data.
If you have used shadcn in React, you already know the shape. Same idea, composable primitives, you own the patterns, AI tools read the schema and call it correctly. We just write HEEx, not JSX.
# 1. Install the MCP server once
claude mcp add petal --transport http https://mcp.petal.build/mcpThen in any Phoenix project:
2. Tell your AI: "install petal_components"
The agent calls get_install_instructions on the MCP, applies the changes to your mix.exs, runs mix deps.get, patches assets/css/app.css, and adds use PetalComponents to your web module. Works in umbrella apps and standard Phoenix projects. The AI handles project shape variance the install would otherwise have to special-case.
Cursor, Windsurf, Continue, Codex, and Cline have their own MCP install commands - see https://petal.build/petal-components for snippets per tool.
If you'd rather install yourself, in mix.exs:
def deps do
[
{:petal_components, "~> 3.2"}
]
endIn assets/css/app.css:
@import "tailwindcss";
@source "../deps/petal_components/**/*.*ex";
@import "../deps/petal_components/assets/default.css";In your MyAppWeb module:
def html do
quote do
use PetalComponents
# ... your other imports
end
endRun mix deps.get, then mix compile to verify.
If you are a Cursor, Claude Code, Codex, Continue, Windsurf, or Cline user (or you maintain one of those tools), drop rules.md into your rules system. It is the canonical instruction set:
- Always reach for an existing petal_components tag before hand-rolling HEEx
- The component naming map (HEEx tag form, module path, CSS class prefix)
- How to discover components via the MCP
- Common patterns (form-in-card, modal-with-form, table-with-actions)
- When in doubt: call
list_components, thenget_component
You can also fetch it at https://petal.build/petal-components/rules.md.
30+ components covering the patterns a real Phoenix app needs. The MCP server is always the canonical list - call list_components for the live inventory. Highlights:
Layout & content: <.container>, <.card>, <.h1>, <.p>, <.accordion>, <.tabs>, <.stepper>, <.skeleton>
Forms: <.field>, <.text_input>, <.select>, <.checkbox>, <.radio_group>, <.switch>, <.textarea>, <.date_input>, <.file_input> (full list in lib/petal_components/form.ex)
Actions: <.button>, <.button_group>, <.dropdown>, <.menu>, <.user_dropdown_menu>
Feedback: <.alert>, <.modal>, <.slide_over>, <.progress>, <.spinner>, <.rating>
Data display: <.table>, <.pagination>, <.breadcrumbs>, <.badge>, <.avatar>, <.marquee>, <.icon>, <.link>
A visual grid is at https://petal.build/components. A live playground is at https://petal-components-demo.fly.dev.
<.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 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 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><.button loading={@saving} phx-click="save">Save</.button>If you like the shadcn workflow in React, this is the Phoenix version of that idea:
- Same philosophy: composable primitives, you own the patterns, no monolithic theme system to fight.
- Same AI-tool integration: an MCP server so the agent reads the real schema instead of hallucinating attrs.
- Different runtime: HEEx, not JSX. Tailwind v4, not Tailwind 3 + CSS variables. Works in LiveView and dead views.
- Different distribution: a Hex package, not a CLI that copies files into your repo. Update with
mix deps.update.
Full comparison with code samples side by side: https://petal.build/petal-components/vs-shadcn.
petal_pro is the production SaaS boilerplate built on petal_components - auth, multi-tenancy, Stripe billing, background jobs, the full set. It is the best reference for real-world composition of these components.
Standalone dev server, no umbrella needed:
git clone https://github.com/petalframework/petal_components.git
cd petal_components
mix deps.get
mix tailwind.install
iex -S mix run dev.exsPlayground at http://localhost:4000 with every component rendered. Live reload on edits to lib/.
Tests:
mix testSuggest a component on the public roadmap. PRs welcome - clone the repo, run the dev server above, and submit.
There is also a Phoenix umbrella app with petal_components as a submodule alongside a boilerplate Phoenix app for integrated testing.
- petal-components-mcp - the MCP server. Source for the schema introspector and the TypeScript MCP service.
- petal_boilerplate - a fresh Phoenix install with petal_components wired up.
- Figma UI kit - official Figma kit for designing against petal_components.
- VSCode snippets - 65+ snippets for the components.
MIT.
