Editor’s note: I want to extend my sincere thanks to SerpApi, the world’s leading API provider of search data, for sponsoring this article. This content would not be possible without their support. They are a phenomenal friend of the Ruby community, sponsoring conferences, creators, and open source. Be sure to check out their careers page, they are hiring. Since this is an opinion piece, I want to note that their sponsorship is not an endorsement of the views expressed herein, which are mine alone.
As I read through the recent recaps of RubyConf, one statement jumped out at me. Michael Carroll shared that “Matz is having the time of his life” working with AI. DHH had a similar sentiment, stating “for anyone with endless ideas, this agent age is nirvana as those ideas are met with endless execution, endless exploration. I've never had as much fun working with computers as I do right now.” And you know what, I feel the exact same way. This feels like the moment I’ve been waiting for since I started building software, and I see a future for Ruby + AI beyond our wildest expectations, one that might be impossible to imagine right now. But there is a problem we have to address first if we want a future in this era. The one decision that put the entire Ruby ecosystem into a downward spiral.
This is not a doom post. Market capitalization of public Ruby-centric organizations represents a half a trillion dollars of economic value. Stripe, a private company, has an estimated value of $160 billion dollars, and their Ruby codebase served as the case study for Anthropic’s Fable release announcement. Over 40,000 companies use Ruby every day. I was tracking so many new job listings just at the intersection of Ruby and AI for the newsletter that I had to stop including careers opportunities. That’s not to say the job market isn’t completely broken; salaries are depressed, the hiring process is a mess, and many companies don’t even know what they need right now. But the Ruby economy itself is holding strong.
This is not a post about assigning blame or pointing fingers. I’m as responsible for the state we’re in just as much as anyone else. The problem has been staring me in the face for so long I’m ashamed I didn’t realize the issue earlier. This decision, one which I believe was made in good faith and with the best intentions, seemed innocuous at the time. But the effects have been devastating. The first and second order effects are felt every day now. RailsWorld and RubyConf, conferences that used to sell out in minutes, struggle to sell tickets. Meetups feel sparse. Fewer Ruby-backed startups. And according to BuiltWith data, the number of Ruby on Rails sites on the web has dropped from about 950,000 seven years ago to about 570,000 today. You probably saw the Hatchbox announcement this week, which contains a graph unsurprisingly similar to the one I’m about to show you below. But the most important metric I care about, and the reason I’m writing this post, is that the flow of new developers to Ruby has fallen off a cliff.

New developers to Ruby based on Github data
After 15 years of continuous growth, a downward trend of new developers to Ruby started. And that big surge of novices during the first year of the pandemic, I believe both hid and surfaced the core issue. This was a huge missed opportunity for the community to attract new members, since the majority of those users learning to code during the pandemic didn’t stick around. AI is our next big opportunity, but this issue predates AI, one of the most often cited reasons for the decline. Another popular reason mentioned online, politics and community controversies, wasn’t mentioned by any of the developers I surveyed as a reason not to adopt Ruby. And if you thought the Omarchy hype of the past month might result in a bump, it was Ruby’s worst ever: 6 new users, down from a peak of 41,000 in May 2020. I know it hurts to hear that. I know full well that these are not the only issues facing the community. We have to start somewhere, and what I’m about to share with you is by far the biggest issue.
The good news is that it’s a technical issue. And as you know, technical issues can be solved. But how in the world could a simple technical decision be responsible for such a huge downward trajectory? If you haven’t guessed it yet, this is a post about Rails. And I know that Rails doesn’t represent or speak for all of the Ruby community, but I want to highlight the numbers before I make my point. When JetBrains surveyed Ruby developers, 86 percent of them were using Rails in 2021. The 2025 Stack Overflow survey found about 7 percent of professional developers said they use Ruby, and 6.2 percent said they use Rails. Those are two different questions, and they get almost the same answer. Nearly everyone who writes Ruby for a living touches Rails. My best estimate is that up to 90 percent of the people who came to Ruby over the last two decades have done so in large part because of Rails. rails new is the marketing arm for an entire programming language.
You might say does any of this even matter anymore? Won’t AI take all knowledge work? Does the choice of programming language matter when a model writes the code? Nothing I’ve seen so far suggests any of this (and I’m writing this with Fable 5.1’s help, which if you’ve seen tech Twitter this week, is apparently AGI!). Of course, the industry is moving fast and things could change. Deep fakes, rogue AIs, recursive self-improvement are all real, but don’t confuse that for sentience. An LLM is a calculator for known knowledge, and a calculator does not make a good mathematician obsolete. But this is a different kind of calculator, one that can make discoveries by connecting disparate knowledge domains. That’s what I’m counting on. And in general, mass producing a good and making it less expensive, in this case software applications, doesn’t mean the world wants less of it, the world wants more. AI is going to increase the demand for well engineered software, and that software gets built by people who understand and enjoy the language they use. Generated code has to be verified every single time, or you risk the flaws reaching your end users. A well built, reusable software convention is verified once and used countless times. Sounds a lot like Ruby and Rails to me.
Rails is the best framework for the AI era because two decades of conventions are exactly what work best in conjunction with large language models. I’m not going to go in depth into why Rails is the best framework for agentic coding, nearly two years of stories in the newsletter have covered that. I’m going to tell you why it’s the worst. Rails stopped adhering to new conventions a long time ago. Seven years ago Rails ignored the biggest convention in web development of the last decade by making a decision.
The decision not to merge ViewComponent into Rails core.
That statement may have caused a visceral reaction, I know there are a lot of strongly held convictions about the Rails frontend, but I want you to take a pause and consider what I have to say next. In order to understand the premise of this argument, you have to look at this through the eyes of someone building a web application for the first time. Try to remember the first time you ran rails new. Now the case I’m making is complicated and we’ll dive into the technical details. But right now, see this through the eyes of someone just getting started. The start of Rails downward trend coincides with the release of a piece of software that established frontend conventions where Rails had none. I’m guessing in your mind you immediately went to React. But React was released in 2013, and like Node before it, those technologies just accelerated Rails adoption with new developers looking to get started quickly. I’m talking about Tailwind UI. And while Tailwind UI alone doesn’t do anything, it was that unique out of the box experience along with React that started the downward trend. The release of Shadcn UI only accelerated the trend, because the Tailwind UI + React integration surfaced the issues, the Shadcn + React integration perfected it. Components became the convention. Suddenly running rails new and rails scaffold pales in comparison for a new developer running npx shadcn@latest init. The Rails magic was gone.
Rails did not reject components outright. In 2019 it merged a protocol called render_in (the pull request was literally titled "Introduce support for 3rd-party component frameworks") and later extended it to controllers. "Rendering Objects" is a documented Rails path today, give Rails an object that responds to render_in, and it renders. What Rails declined was upstreaming ViewComponent, a GitHub-backed framework where a component is a Ruby class paired with a sidecar template, into core. Joel Hawksley announced the decision in February 2020: "After some conversations with the Rails team," the library "will not be upstreamed into Rails 6.1, but will instead have integrated support".
So the render support was shipped and the components were left to the community. But because no component abstraction was ever officially “sanctioned”, the ecosystem fragmented into competing third-party answers: ViewComponent, Phlex, Inertia, plain partials with presenters, none official, and all with a multitude of opinionated implementations. And because of this fragmentation, Rails never developed a cohesive UI ecosystem of interchangeable components like Shadcn and React. The Rails frontend is a blank slate. A newcomer to Rails gets ERB and no guidance on what comes next. As Brandon Weaver puts it, "Rails gave them the fastest start, then left them there… there's no paved path, and the doctrine treats needing one as a failure of discipline rather than a stage of growth."
An official component API would settle the abstraction question the way Rails settles most questions: with a convention. It would give a component a real object to hang a contract on, such as typed arguments, slots, variants, states, etc., so that tooling, documentation, and increasingly a coding agent all have one shape to reason with. However at this point, we need so much more than an API, Rails needs an official component library. An API is the abstraction, a library is the set of components to bootstrap applications in an instant. Rails never adopted either, but its peers have both.
Laravel has official starter kits that ship a designed, accessible component library as the default getting-started experience: Flux UI, "the official Livewire component library," built by the core team, for the Livewire stack, and shadcn/ui as the default for JS stacks. Laravel has also had Blade components, an abstraction analogous to ViewComponent since 2020. This is not a hypothetical want from the Rails community. Irina Nazarova’s Startup on Rails presentation surveyed Ruby founders on the ecosystem's gaps, and the named gaps included "a shortage of component libraries" and "improved frontend tooling and interactivity." Her larger point hits hard. Rails may be the best stack for agentic software development, and almost nobody building with AI knows it. Chad Fowler's whichlang benchmark ran 210 product builds where the agent was never told which language to use, and the agents chose Ruby zero times. Irina says that is not a capability gap, it is a discoverability gap, because a model reaches for what the corpus argues for, and the Rails view layer doesn’t have strongly established conventions.
Even with agentic coding, we can’t ask new developers to navigate the complexities of the Rails frontend, understand build systems, and evaluate competing component libraries. No amount of improved Hotwire docs is going to fix this. And just because you can “vibe code” a UI, doesn’t mean it’s production ready. Consider the conventions we’re asking veterans and newcomers to understand and build out each time they start a new application:
Markup. The right element for the job, nested the way browsers and assistive tech expect. A div styled as a button looks fine and breaks everything downstream, from focus to form submission to screen readers.
Styling. Every visual state of every control: hover, focus, active, disabled, invalid, loading, selected. Multiply that by variants and sizes and you have hundreds of decisions per app that should be made once.
Theming and design tokens. Colors, radii, spacing, and type expressed as tokens, so dark mode, a brand override, or a redesign is a swap rather than a rewrite. Hardcoded hex values are the reason most Rails apps can never change their look.
Accessibility. ARIA roles, states, and accessible names, focus management, live announcements, contrast. Getting this right is a specialist skill, and getting it wrong excludes real users and creates legal exposure.
Keyboard interaction. Arrow keys in menus and listboxes, Escape to dismiss, Tab trapped inside a dialog and returned on close, typeahead in selects. The WAI-ARIA authoring practices run pages per widget, and nobody rewrites them correctly from memory.
Interactivity and state. Open and close, selection, positioning and collision handling for anything that floats, outside-click dismissal, focus return. This is where most hand-rolled UI is subtly wrong.
Progressive enhancement. Controls that work before JavaScript arrives and degrade gracefully when it fails. A loading state that is just aria-busy plus a disabled attribute needs no script at all, but only if someone designed it that way.
Forms and validation. Labels, hints, required markers, error placement, and the wiring to the Rails form builder so server-side errors land where users look for them.
Internationalization. Every visible string routed through I18n, right-to-left layouts that mirror correctly, locale-aware dates and numbers. The hardcoded "Close" in a dialog is the tell of a UI that was never meant to leave one country.
Responsive behavior. Breakpoints, touch target sizes, and the judgment calls, like a dialog becoming a bottom sheet on a phone, that a component can make once for everyone.
Motion. Enter and exit transitions with consistent timing that honor the reduced-motion preference. Animation is easy to add and hard to make feel like one product.
Cross-browser compatibility. Safari's opinions about the dialog element, popover support, focus-visible behavior, scroll locking on iOS. Each is a bug report waiting for the first user on the browser you did not test.
Hotwire compatibility. Components that survive Turbo Drive cache restores, page morphs, frames, and stream updates without leaking state or initializing twice. The failure modes are invisible until production.
Security. Output escaping, CSRF tokens in forms, refusing javascript: URLs in links, sanitizing anything user-authored. Components are a place these guarantees can be enforced uniformly.
Performance. Server-rendered HTML with no hydration tax, small asset payloads, stable ids so fragment caches and ETags actually hit, no layout shift from late-arriving scripts.
Asset pipeline and build. Importmap or bundler, Tailwind configuration, Stimulus controller registration, CSS layer order. This is the "build system" newcomers get stuck on before they write a single view.
Naming and consistency. The same option means the same thing on every component: variant, size, disabled, label. Consistency is what lets a developer, or an agent, guess the API correctly without opening the docs.
Linting and static checks. Template rules that catch a missing accessible name, a forbidden raw element, or an invalid option before the page ever renders. Catching a mistake as you type it is cheaper than any test.
Testing. Previews, system tests, accessibility assertions, and test helpers that make asserting on a component's behavior a one-liner instead of a Capybara expedition.
Documentation. Every option, slot, and state described next to the code that implements it, so the docs cannot drift. Undocumented UI is re-learned by every person who touches it.
Upgrades and maintenance. Browser changes, dependency bumps, and design refreshes absorbed by the library and delivered as a version bump with a migration path, instead of a project every team runs alone.
Agent legibility. A declared contract that a coding agent can read, generate against, and audit. This is the newest convention, the one Rails has no answer for right now.
Phew… imagine starting out and having to build all that. We have to fix this. What should we do?
ViewComponent is the right starting point. First, it gives you a real object to build a machine-readable contract on (more on why that’s so important later). A ViewComponent is a Ruby class, so typed and validated arguments (via ActiveModel), typed slots (renders_one / renders_many), variants, and states all have a natural home. Second, it is the de-facto component standard, backed by GitHub. They have moved much of the frontend to React, and in my opinion, that was the start of their downfall, as their website got noticeably worse with the shift. GitHub built ViewComponent against thousands of copy-pasted templates, and its own numbers put component unit tests at roughly 25 milliseconds against roughly 6 seconds for the comparable integration tests. The overwhelming majority of Ruby component libraries and code are ViewComponent. And Turbo Stream rendering landed in ViewComponent core, so components can be pushed over the wire. Third, an ERB template is a real HTML document. That makes the entire HTML-aware toolchain apply: Herb, Marco Roth's HTML-and-ERB parser, gives you a real AST, and that AST can run template validation, CSS class-safelist generation, catch hallucinated utilities, and perform styling transformations because everything is parseable markup.
Why not Phlex: I like Phlex, it is genuinely good and the leading Ruby shadcn port, ruby_ui, is built on it. Phlex builds HTML in pure Ruby. No template files, views are Ruby objects that emit markup through method calls. It is genuinely faster, an optional compiler collapses static element calls into buffer appends, and that is real and measurable. Pure-Ruby composition, with no template-and-class split, is cleaner for complex conditional structure. It uses fewer files per component. But Phlex optimizes the machine executing the view; ViewComponent optimizes the machine, and the human, reasoning about the view.
With agentic coding, a library's most precious resource is not microseconds per render, it is an agent's ability to generate, audit, and transform components correctly. And every one of those operations is an operation on visible structure. With Phlex, the markup is implicit, existing only when the Ruby method runs, as a side effect of control flow: a static analyzer or an LLM cannot see the HTML tree without executing the Ruby. Reasoning wants a parseable tree, generating wants to emit the shape the model already knows, auditing wants a source line mapped to a DOM node, transforming wants class attributes it can rewrite statically. ViewComponent gives all four, Phlex gives none of them to an HTML tool chain without executing the view.
And the performance objection can be answered rather than ignored. Phlex's speed has two sources. The first is its runtime, which shaves microseconds per component. The second is a compiler, still opt-in and unfinished as of 2.4, whose job is to fold static element calls and literal attributes back into string appends. That compiler exists only because the template is Ruby, and its payoff, static HTML costing one string append at render time, is exactly what compiled ERB does by construction. Phlex's next step toward speed is to render the way ERB already renders. David Silva highlighted what remains. Phlex "is a different trade: write views as Ruby, and you are back to having no HTML for an HTML-aware tool to read." The template-engine debate "usually turns on ergonomics; the more durable axis is legibility to tools." A ViewComponent-based system feels like The Rails Way.
Why not Inertia: If you keep telling people to use React, they might just use React. And of course, regret that later.
So what now? While we missed the mark on the biggest convention in web development of the last decade, this moment represents the greatest opportunity in Ruby on Rails history. The chance to engineer a core library from the ground up for the AI era, reimagine what’s possible, and deliver the best AI-native frontend ecosystem in the world. But what does AI-native mean and what would that look like for Rails?
AI-native doesn't mean the library writes your views for you. Any model can already do that, and that's part of the problem. It means the library is built so an agent composes from approved pieces inside a system that can check its work. Legible to users, developers, linters, agents, and models, all from the same source. Tool, agent, and model legibility turn out to be the same property.
Imagine running rails new with an AI-native component library. The app has the full catalog every React developer takes for granted: buttons, dialogs, forms, menus, data tables, charts, rendered on the server as HTML they can open and read. It's themed, and switching to another built-in theme is one setting. Every control already handles the keyboard, the screen reader, the phone, dark mode, and the Turbo cache, because that entire list above was solved once and verified before it shipped. It works before the JavaScript arrives, and it looks good.
Then open a coding agent and say "build me a settings page." The agent doesn't guess at Tailwind classes or invent a dropdown from scratch. It reads the catalog through the same registry the docs are generated from, composes the page from real components, and runs a check that parses the ERB and refuses anything hallucinated. A component that doesn't exist. An option that was never declared. A raw hex color. The agent gets the same verdict a CI job gets. The developer reviews Ruby and HTML they can actually read, not a diff of thousands of utility classes.
Underneath this is one idea. Every component declares its own contract, its options, slots, variants, states, and the rules an agent has to follow, and that single declaration is the source for everything else. The documentation. The machine-readable registry. The llms.txt file. The agent skill. The MCP server. The linter. Even the tools an interactive component registers so a browser agent can operate the page. Nothing drifts. A model doesn't have to be told how the library works, the library tells it.
That's also how you close the discoverability gap. A model reaches for what it can find and verify. Give it a component library with clean machine-readable docs, an MCP server, a skill, and an executable check, and Rails becomes the stack an agent can be trusted with, because its output can be checked. Not because we asked, but because the training corpus argues for it.
The rest of the team gets the same contract. A designer's tokens come in from Figma and pass the same contrast gate the components do. A theme can be extracted from any existing site. And you'd be able to measure all of it, agent output with the library against agent output without it, instead of taking anyone's word for it. Verified once, used countless times. The Rails promise, finally extended to the frontend.
And it unlocks Rails’ hidden superpower. Earlier I said AI is going to increase the demand for well engineered software, and that a good convention is verified once and used countless times. Rails already has the shape for that: Engines. Today every engine you mount ships its own look, and your app becomes a patchwork you can’t restyle without rewriting it. But if you build engines on a standard set of components, each one can read the host's tokens and render in the host's theme. Verify it once, mount it everywhere, and one prompt can retheme your entire application, engines included.
It would be a dream to have all of this. An AI-native component API and UI library, built for developer happiness and optimized for agents and AI models, a framework of the future for the Rails frontend.
Introducing Poetry: The AI-native UI Framework for Rails
Poetry is the end result of everything I shared with you, built to cover the 22 conventions I mentioned above. It is an AI-native UI framework for Rails, with layered library choices.
Poetry Core is a Ruby API written on top of ViewComponent for developers and AI. Every component declares its options, slots, variants, states, parts, and Stimulus wiring in one place, and Core serves that single declaration to every surface that needs it, the docs, the registry, the linter, the agent skills, and the MCP server, so nothing breaks and a new AI protocol is just another layer and not a rewrite. It owns the design tokens too, authored once and compiled into a BEM or Tailwind theme behind a contrast gate.
Poetry UI is a shadcn-parity component library, eighty-eight accessible components, nine themes, whole-screen blocks, and a model-bound form builder, that gives you beautiful defaults out of the box and can be constructed agentically, because an agent composes from real components and runs a check that refuses anything hallucinated. Sane defaults, but completely customizable.
Poetry Agent is an AI-native view layer you can add to any application, an MCP server for the agent in your editor, WebMCP tools for the assistant in your user's browser, and AG-UI and A2UI surfaces for agents that render UI live.
Charts, icons, theme extraction, and a SimpleForm bridge ship as opt-in gems, with much more on the way. And the umbrella gem, Poetry, is beginner friendly so you can just install and use. One gem, one generator, and a new developer's first Rails app looks finished.
The inspiration
Poetry did not start from scratch, and the code that influenced it deserves recognition. First, Joel Hawksley and the ViewComponent team, whose work is the foundation under every Poetry component. Vladimir Dementyev's view_component-contrib gave Poetry its preview system and its wrapped helper pattern, and James Fawks's fox_tail gave it the class merger, the attribute handling, and the Stimulus wiring builders that every component runs through. Then there is shadcn. Poetry UI is a shadcn parity library. The component anatomy, the token vocabulary, the themes, the blocks, the charts, and the registry format that lets any shadcn client install a Poetry item all trace back to one person's taste and generosity, and the fact that shadcn/ui is MIT is the reason a Rails port could exist at all. shadcn prefers to be credited simply as shadcn, so that is how the notices read, with my admiration attached. Behind them runs a longer list of influences and derived code, all MIT, ISC, or Apache, every adaptation named file by file in each gem's third party notices. Base UI and Radix Primitives for interaction behavior, Mantine's input mask, react-day-picker's range selection, Adobe's React Aria date model, ReUI, Cloudflare's kumo, the Hotwire Club toolbox, heroicons-rails, simple_form, the agentcn extraction recipe, and Lucide for the icons.
How this sets up Rails for the future
The protocols that let models work with software arrived faster than any framework could absorb them, and most of them are less than two years old. Poetry treats each one as a projection of the same component contract, which is why it can support all of them without the library becoming five libraries. Here is what they are and what Poetry does with each.
llms.txt and Agent Skills are how a model discovers a library. llms.txt is a plain markdown file at the root of a site that tells a model what the site is and where the pages that matter live, and a skill is a folder of instructions an agent loads when a task calls for it. Poetry ships both. The installed gems serve an llms.txt with every component contract in it, the docs site mirrors every page as markdown, and the skills that teach an agent to compose, check, and design with Poetry install into your app with the gems and publish through a discovery index any skills installer can read.
MCP, the Model Context Protocol, is how a model calls tools. Anthropic published it as a standard way for a model to reach a server that offers capabilities, and every serious coding agent now speaks it. Poetry ships an MCP server, ten tools read straight from the live registry with no app boot, so the agent in your editor can compose a screen from vetted blocks, describe any component, and run the same check CI runs before it shows you a diff.
WebMCP turns that around. It is a browser API, proposed by engineers at Google and Microsoft through the W3C, that lets a web page register tools for the assistant your user brought with them. Poetry components declare their own tools, so a tab strip, a dialog, a sheet, a combobox can be operated by the user's agent on the user's behalf, and a form can be declared as a tool in one helper call. The page decides what the assistant may touch, and nothing more.
AG-UI and A2UI are how an agent renders. AG-UI, from CopilotKit, is an event stream between an agent backend and a user interface, the text deltas, tool calls, and state changes a chat needs to show a run as it happens. A2UI, from Google, goes further. The agent describes an interface as a flat list of components bound to a data model, and a client renders it from a catalog it trusts, so the agent never writes HTML. Poetry ships both sides for Rails. An AG-UI client folds an agent's stream into Poetry chat rows over Turbo Streams, and an A2UI renderer turns a surface into real Poetry components, every one of the eighty-eight, validated by rendering, with the buttons in that surface posting back to the agent as the next turn.
That last piece is generative UI, and it is the part I find most exciting. A model that emits schema against a catalog can only produce interfaces the library already knows how to render accessibly and in your theme, and a check can refuse the rest. The interface can grow and change as the conversation does. You get the speed of a model composing screens with the guarantees of a design system, which is a trade nobody has had to make before.
Notice what stayed the same across all of it. The component contract Poetry generates its docs from is the same contract that fills the llms.txt, drives the MCP server, registers the WebMCP tools, and defines the A2UI catalog. When the next protocol arrives, and it will, supporting it means writing one more projection, not a rewrite. That is the bet, and it is the reason I believe Rails, of all frameworks, can become the one whose interfaces a model can discover, build, operate, and render without ever being allowed to guess.
The roadmap
Poetry ships today as the component library and the agent surfaces around it. Everything below is opt in and layered on the same contract, which is what lets me publish a roadmap without the usual promise of a rewrite.
A design workflow and design-kit. Poetry components rendered to HTML artboards for creative direction and review, driven by the same tokens the app uses, so drafting happens on the real material instead of a picture of it. Your designer and your agent look at the same thing.
Figma, both directions. Today Poetry imports Figma and Paper tokens through the contrast gate, extracts a theme from any live site, and translates a design into components through a skill that talks to both tools. Next comes Figma Code Connect, so Dev Mode shows the Poetry helper for a component instead of React, and a reverse push that renders a Poetry component back onto the canvas for review.
Paste registry. Paste a component, a recipe, a block, or a skill and get an immutable URL that installs with one command into any Poetry compatible Rails application. Every paste is checked on the way in and carries its verdict in its metadata, with an explicit unverified tier so provenance stays honest.
Community registry. Anyone publishes a component as a registry item, resolvable by namespace or URL, and because it conforms to the contract, an agent can discover and install it exactly like a core component. A verified badge pipeline feeds a hosted gallery.
Client islands. A bounded escape hatch for the rare widget that genuinely needs client state, mounted through Stimulus with props in and events out and never a client router, so an app never adopts a whole page of JavaScript for a single component.
Better design and taste skill. The skills today prevent bad design by constraining the catalog. The next step is producing good design, which is far more reliable on Poetry's safe catalog than on raw HTML.
Jumpstart Pro installer. Chris Oliver has graciously given me permission to build an installer that replaces views for Jumpstart Pro, the most popular commercial Rails boilerplate, with Poetry components. Poetry native recreations that never touch licensed source. It is built and in review.
I’m also working on an engineering plan that would allow you to install any permissibly licensed component in the shadcn registry as a Poetry-native component. Wish me luck on that one.
RubyLLM x Poetry
RubyLLM is the gateway most Ruby apps use to reach a model, and its generator already scaffolds a working chat, the records, the background job, the Turbo streams, and a set of Tailwind views. The next Poetry release adds an installer that updates RubyLLM’s views with Poetry's chat components. Messages arrive in a transcript that keeps its place while the model streams, each reply morphs into its row instead of appending a node per token, tool calls show as activity lines a reader can follow, and the composer, the markers, and the error states are the same components the rest of your app uses. Your chat interface looks like the rest of your product.
The installer also ships an "evolvable" mode, and that is the part I have been building toward this whole essay. In evolvable mode the chat is a workspace. The model gets tools for your data and tools for your interface, and instead of answering with paragraphs it answers with screens. Ask about a customer and a profile card appears. Ask for a breakdown and a chart lands beside it. Refine the question and the surface you are looking at changes in place rather than piling up. The chat starts center stage on an empty canvas, docks to the corner once the first surface lands, and every button inside a surface posts back to the model as the next turn, so the interface asks questions on your behalf. None of it is HTML from a model. The model emits a description against Poetry's catalog, the app validates it by rendering it, and only real components reach the page, in your theme, accessible by construction, with the whole workspace persisted as an event log so it survives a reload.
No launch is complete without a killer demo: Poetry in Motion is a public reference app, a bank operations analyst over a synthetic dataset of fifty thousand customers and a million transactions, built on RubyLLM and Poetry with the dataset shipped in the repo. Clone it, add a model key, and ask it for an overview of the bank. The installer is derived directly from it, so what you see there is what your own app gets.
Processing
Look, this library is early, and I need the community’s help now. It was built with an agentic engineering workflow, and I’m constantly reviewing the code. Since I do advocate for Ruby, AI, and agentic coding, I wanted to share how I built this library, because it can sometimes be hard to get a sense of an optimal workflow with the industry moving so fast. This is what worked for me:
It was generated from 230 pages of prompts
My coding agent has access to my personal knowledge vault, with thousands of pages of notes and research on ViewComponent and the Rails frontend
The coding agent has access to a structured database containing an archive of everything referenced in the Ruby AI Newsletter, along with every Ruby AI gem
I attempted this project on Opus 4.5 and 4.8, Fable 5 was the first that produced acceptable results and I have been maxing it out since its release
The core code is based on a ViewComponent library I wrote, but was unable to secure the licensing right for the front end assets I wanted to use
There were few parallel agents or loops used, every decision was me, Claude, the knowledge vault, and the AskUserQuestionTool. If something is wrong here, it’s my fault, not AI’s. But I want to hear from you. Questions, criticism, feedback, test out the libraries and let me know what breaks: [email protected]
It’s time to bring back the Ruby and Rails magic.
When you don’t create things, you become defined by your tastes rather than your ability. Your tastes only narrow & exclude people. So create.
_why the lucky stiff
September 7th: Article was updated to remove DHH quote incorrectly attributed to the ViewComponent upstream decision, replaced with Joel Hawksley quote. Updated the Phlex analysis and the David Silva comment to reflect the most recent version of his post.