AI-Assisted Development
RapidRailsUI publishes four machine-readable surfaces so Cursor, Claude Code, ChatGPT, and any other agent can generate correct component code on the first try — no guessing at syntax.
AI-Facing Resources
Three static files, ranked by how much context budget they cost. Point an agent at whichever fits the task — all three are always current with the live docs site.
| File | Size | Use it when... |
|---|---|---|
| llms.txt | ~1,300 lines | Default choice. One-line-per-component index, argument-order and color conventions, form builder pattern. Enough for most single-component requests. |
| llms-full.txt | ~19,000 lines | llms.txt's one-liner isn't enough detail — full params, slots, variants, and copy-paste examples per component, one ## ComponentName section each. |
| llms-mini.txt | ~60 lines | Tight context budget. A single table (complexity, param/slot counts, AI-friendliness score) for a first pass over "which component do I need" before loading detail. |
Starting point for most prompts: "Using RapidRailsUI (read https://rapidrails.cc/llms.txt first), build a <thing>." That's the whole setup step — no MCP server, no config file, no copy-paste into a system prompt required for tools that can fetch a URL.
Content Negotiation
Every /docs/<component> page — all 37, including newer ones like
/docs/carousel
and
/docs/kanban
— serves three
representations of the same content depending on the request's Accept header. No
.json/.md extension needed; it's pure header negotiation.
| Accept header | Response |
|---|---|
| text/html | The rendered docs page (default for browsers). |
| application/json (or */*) | Structured schema for that one component: params, slots, gotchas, related components/compositions — the same data the schema YAMLs hold, pre-merged. |
| text/markdown (or text/plain) | The matching ## ComponentName section of llms-full.txt, as plain Markdown. |
# Plain curl sends "Accept: */*" by default, which matches JSON first —
# no -H flag needed to get structured data:
curl -s https://rapidrails.cc/docs/card | jq
# Explicit JSON (same result as above, spelled out):
curl -s https://rapidrails.cc/docs/tabs -H "Accept: application/json" | jq
# Markdown — the llms-full.txt section for one component, nothing else:
curl -s https://rapidrails.cc/docs/carousel -H "Accept: text/markdown"
# HTML — the actual rendered page (what a browser gets):
curl -s https://rapidrails.cc/docs/kanban -H "Accept: text/html"
Two aggregate JSON endpoints sit alongside the per-component negotiation:
GET /api/schema.json— every component's schema in one response. Large; use it for a one-shot "load everything" pull, not per-request.GET /api/schema/components/<name>.json— one component, same shape as the per-page JSON negotiation.
The Installed Gem: Your Version-True Fallback
This site always documents the latest gem release. If your app's Gemfile.lock
pins an older rapid_rails_ui, the hosted docs can describe params or behavior your installed
version doesn't have yet. Every component ships its own USAGE.md right next to
component.rb inside the gem — that file is exact for whatever version is actually installed.
# Locate every component's USAGE.md in the installed gem:
find "$(bundle show rapid_rails_ui)" -name USAGE.md
# Or jump straight to one component:
cat "$(bundle show rapid_rails_ui)/app/components/rapid_rails_ui/card/USAGE.md"
Tell your agent to prefer this when versions might disagree: "Before using
rui_<component>, check
$(bundle show rapid_rails_ui)/app/components/rapid_rails_ui/<component>/USAGE.md in
this repo's installed gem — it's authoritative for our pinned version, even if it differs from
rapidrails.cc."
Schema YAMLs for Advanced Agents
The JSON content negotiation above is a per-component merge of five machine-readable YAML files, shipped
inside the gem at lib/rapid_rails_ui/schema/. An agent working directly in your codebase
(rather than fetching from rapidrails.cc) can read these directly for the same data, offline:
| File | Purpose |
|---|---|
| manifest.yml | Per-component metadata: helper name, complexity, param/slot counts, form-builder support, AI-usability score. |
| slots.yml | Every renders_one/renders_many slot per component, with an example with_* call. |
| gotchas.yml | Non-obvious param interactions that silently fail — e.g. a plain rui_button inside form_with renders type="button" and never submits; use f.rui_button or type: :submit. |
| families.yml | Decision trees for choosing between similar components — e.g. "filter table rows" points to rui_live_search, not rui_combobox. |
| compositions.yml | Multi-component recipes no single component covers — e.g. "author byline" = rui_avatar + rui_text, with the exact ERB. |
A sixth file, relationships.yml, is auto-derived from the five above (which components
compose with which, which are commonly confused) and merged into the per-component JSON automatically —
you don't need to read it separately.
Signature sheet
Since v0.90.0 the same folder holds signatures.txt: every rui_* helper on one line
with each keyword it accepts, its default, the allowed values where the set is closed, and its slots. About
23KB, against 55KB for llms.txt. Point an agent at it when it only needs to know which keywords
a helper takes. Deprecated keywords are left out, and long value sets are shortened without dropping a value
(xl2..xl10).
signatures-full.txt has the same lines plus short descriptions for the most used helpers. Use it
when the agent also needs to know what a helper is for. bin/rails rui:signature reads this one.
bin/rails "rui:signature[badge]"
bin/rails "rui:signature[colors]"
bin/rails rui:signature
Prompt Recipes
Four copy-paste starting points. Each is a full request you can hand to Cursor or Claude Code as-is — adjust the specifics, keep the "read llms.txt first" instruction and the component names.
1. Pricing section with rui_card
Using RapidRailsUI (read https://rapidrails.cc/llms.txt first), build a pricing
section with 3 rui_card tiers: Starter, Pro, Enterprise. Each card needs:
- an icon slot (with_icon) matching the tier
- a header slot (with_header) with the tier name
- a checklist (with_list / with_item) of 4 features
- a footer CTA (with_footer) linking to /signup
Highlight the Pro tier with variant: :elevated and color: :primary; leave the
other two at their defaults.
Iterate: if the agent reaches for a plain <div> or invents a
rui_pricing_card that doesn't exist, it didn't actually load llms.txt — re-paste the URL,
or point it straight at https://rapidrails.cc/docs/card with
Accept: text/markdown for the canonical slot API.
2. Tabbed section with rui_tabs
Using RapidRailsUI (see https://rapidrails.cc/docs/tabs — fetch it with
Accept: text/markdown for the full spec), build a rui_tabs component with 3
tabs: Overview, Pricing, FAQ. Use variant: :spaced, deep_link: true so the
URL hash tracks the active tab, and give the Pricing tab a badge: "New".
Iterate: ask for changes in plain language — "make it vertical with
tablist_position: :end" or "switch to :pills and make Overview active by default." A correctly-primed
agent edits only the with_tab calls that changed, not the whole block.
3. Form with automatic server-error display
Using RapidRailsUI form builder methods (f.rui_input, f.rui_select,
f.rui_textarea) inside form_with(model: @user), build a form for name, email,
and a bio textarea. Do not add manual error-checking code — f.rui_* methods
already detect @user.errors[:field] automatically and render the inline
error styling and message on their own.
Iterate: if the agent adds its own
<% if @user.errors[:email].any? %> wrapper around a field, that's the tell it
missed the automatic-detection convention. Point it at the "Errors" section of
rui_input's USAGE.md and ask it to delete the manual check.
4. Dashboard with rui_stat + rui_table
Using RapidRailsUI (read https://rapidrails.cc/llms.txt), build a dashboard
section: 3 rui_stat cards in a row (Total Sales, Active Listings, Conversion
Rate), each with a change: indicator (e.g. change: "+8%"), followed by a
rui_table(sortable: true) showing the 5 most recent listings with sortable
Name, Status, and Created columns.
Iterate: table and link are the two lowest AI-friendliness scores in
llms-mini.txt
— expect at least one follow-up round for column config. Ask the agent to check
rui_table's USAGE.md before guessing at a column option a second time.
Using Your AI Tool
Setup is the same idea everywhere: get the tool to fetch or read llms.txt, then prompt as
usual. Specifics per tool:
@ → Add docs → paste https://rapidrails.cc/llms.txt. Cursor
indexes it once; re-add the URL after a RapidRailsUI upgrade if @docs still generates old syntax
(it caches).
No setup step — just reference the URL in your prompt (see the recipes above). Claude Code fetches it live on each session, so there's no stale-cache failure mode to debug.
Paste the file's contents directly into the first message instead of the URL:
curl -s https://rapidrails.cc/llms.txt | pbcopy
# Paste into the chat, then ask your question
Use llms-full.txt instead for a specific component's full detail — it's larger, so only
paste it when llms.txt's one-liner genuinely isn't enough.
Any client that speaks MCP can wire up an llms-txt-mcp server pointed at the same URLs
(llms.txt, llms-full.txt) to auto-fetch context per conversation instead of
re-pasting it — see that project's own setup docs for the exact config shape for your client.
Troubleshooting
Agent invents a component or wrong argument order
It's working from stale training data instead of the docs. Re-paste the llms.txt URL, or for a single
stubborn component, fetch its exact section directly:
curl -s https://rapidrails.cc/docs/<component> -H "Accept: text/markdown" and paste
that instead — smaller, harder to ignore.
Cursor's @docs won't pick up a new release
Remove and re-add the llms.txt URL in @docs, or restart Cursor — it caches fetched docs
content and doesn't re-poll on every message.
JSON/Markdown negotiation returns HTML or 404s
Double-check the Accept header spelling (application/json, not
json) and that the component name matches the URL path exactly (e.g.
/docs/button_to, not /docs/button-to). A 404 on the Markdown format for a
real component means that component's section is missing from llms-full.txt — worth a bug report.
For Stimulus/JS-side issues (controllers not firing, esbuild collisions, etc.) — those aren't AI-specific; see the dedicated Troubleshooting page .