Josef Strzibny (@strzibnyj) asked on X: "What stack should I use in my next vibe coded project?" with three options — Tanstack Start, React + Inertia + Rails, and Nuxt. I replied with a summary of an experiment I'd just run, and he said "I would love to read a write up if you ever make it." This is that write-up.
A disclaimer up front: This isn't controlled science. It's one developer riffing with Claude Code on a side project, running the same spec through different stacks to see what happens. Sample size of one. Your results may differ. But the patterns I saw were stark enough to be worth sharing.
My Background
I've been writing Rails since 2005–2006, back when it was still pre-release. Twenty-two years. I picked up Vue.js around 2018 and have been using it for about eight years — first with Quasar framework on Rails API backends, then Nuxt for the last two major projects.
In 2022, I tried going all-in on Rails with Hotwire and Turbo for the frontend of a new app. I wanted to see if I could stay in the Rails ecosystem for everything. I got 3–4 months in, using ViewComponent and the Stimulus/Turbo stack, and found I was writing so much JavaScript by hand for a complex application. Coming from Quasar — which gives you a massive component library out of the box — I knew I wasn't going to hit the UI quality I was aiming for, and I wasn't going to make my deadline. So I stopped, spent a solid month doing 12–14 hour days, and converted the entire frontend back to Quasar. That was my best serious attempt at Hotwire for a production app.
More recently, I've been noticing that LLMs fumble a lot with Nuxt. I didn't know if the problem was LLMs in general, something Vue-specific, or something Nuxt-specific. Nuxt doesn't have many good open-source reference projects, the documentation has gaps, and it can be genuinely hard to find good information on it.
So I've been looking for an opportunity to try a different frontend stack. A personal side project felt like the right place to experiment — low stakes, no deadline, just me and the AI seeing what works.
The Setup
I'm building a home inventory app. The core workflow is a capture mode: point your phone at an item, AI identifies it, you confirm it into inventory. Camera viewfinder, AI suggestion card, voice commands, barcode scanning, container switching — a real-time interactive UI that would stress-test any framework.
Instead of guessing which stack would work best with AI assistance, I ran an experiment: have Claude Code (Opus 4.5) build the exact same capture mode UI in multiple frameworks, using the same spec each time. I wanted to see which stack an AI agent actually produces the best code in, not which one has the nicest docs or the biggest community.
The Five Prototypes
1. Static HTML/JS — Vanilla everything. Zero dependencies. The baseline.
2. React + shadcn/ui — Modern SPA. TypeScript, Radix primitives, Lucide icons, Vite.
3. Rails + Hotwire — Server-rendered with Stimulus controllers. No JS build pipeline.
4. Rails + Inertia + Vue 3 — Vue components with Rails routing. No separate API.
5. Rails + Inertia + React — Same Inertia setup, swapped Vue for React.
Each prototype got the same brief: camera viewfinder, AI suggestion card with auto-confirm timer, voice commands, HID barcode scanning, container picker, settings modal, help sheet. Same feature set, same design language.
The Results
React SPA, Hotwire, and Inertia + React all reached functional on the first pass with excellent polish. The agent used proper component libraries (shadcn/ui or maquina), real icons (Lucide or SVGs), and clean CSS architecture. Zero runtime errors across all three.
Inertia + Vue was a different story. It took three-plus passes and still didn't match the others. The agent hand-rolled components instead of using the component library. It used emoji characters for icons. The CSS was broken. Multiple runtime errors. I gave up — it wasn't shippable.
The React prototype was polished from the first pass. Spacing, component structure, icon usage, CSS — all correct. Claude essentially one-shot it.
Hotwire was a surprise — and I say that as someone who doesn't enjoy working in it. I find Stimulus cognitively difficult to follow: which data attribute is the controller, which is the target, which is the action? It's not aesthetically pleasing to read or write. I love the component model of Vue and React — everything self-contained in one file. Vue's single-file components (SFCs) are genuinely beautiful to me. What I do love about Hotwire is Turbo Streams — the live broadcasting from Rails, having your app feel reactive without a JavaScript framework. But wiring it all up myself? I found it confusing, and Rails documentation has never been its strongest suit.
So I didn't expect the Hotwire prototype to impress me. But Claude produced excellent quality because it was mostly writing Ruby and HTML, which it knows extremely well. The Stimulus controllers for camera, voice, and barcode were clean and well-separated. The tedious parts I'd normally have to write by hand? The agent just did them.
Vue was bad. Not "needs some polish" bad. The agent hand-rolled fake toggle switches instead of using shadcn-vue components that were explicitly in the plan. It used emoji characters for icons. It missed the Tailwind v4 @theme configuration entirely so CSS variable utilities didn't work. Multiple runtime errors from sloppy template ref management. It took three-plus passes of corrections and it still didn't match the others. Elements were off-center, alignment was wrong in ways I couldn't get it to fix. I just gave up. It wasn't shippable — I'd have been hand-tweaking CSS indefinitely. I never had that problem with any of the other prototypes.
The Controlled Experiment
The Vue result bugged me. Was it an Inertia problem or a Vue problem? The architecture was sound — Inertia's model of passing props from Rails controllers to frontend components is elegant. So I ran a control: same Inertia backend, same Rails controllers, same routes — just swap Vue for React.
The result was instant and definitive. The React + Inertia prototype was excellent on the first pass. I ported the standalone React prototype's components almost verbatim — only two files needed minor adjustments for a field name difference. Zero runtime errors. Clean console.
Same architecture. Same backend code. The only variable was the frontend framework. Vue was the problem.
Why This Happens
Here's what I think is going on: training data density. React + shadcn/ui is almost certainly the most represented frontend stack in current LLM training data. The agent has seen so many examples of shadcn components, Tailwind utilities, and Lucide icons used together that it just knows what polished output looks like in that stack.
Vue 3 Composition API + shadcn-vue has meaningfully less representation. The agent knew Vue's APIs but lacked the patterns for polished results. It defaulted to hand-rolling components because it didn't have strong enough examples of shadcn-vue composition burned in. This matches what I've been seeing with Nuxt on my last two projects — the LLMs consistently struggle more with the Vue ecosystem, and now I have a better sense of why.
Rails/Hotwire performed well for a different reason. Ruby on Rails has 20 years of convention-driven, heavily-documented patterns. Stimulus controllers are thin JavaScript wrappers — most of the work is Ruby and HTML, which the agent excels at. The agent's strength in Ruby compensated for Hotwire being more niche.
One thing worth noting: I ran all five prototypes completely vanilla. No CLAUDE.md instructions, no custom skills, no framework-specific prompts or guidance. I didn't want the agent competing with different sets of instructions — I wanted to see what the LLM does out of the box with just a spec.
I think that actually makes it a better experiment. Someone could reasonably say "well, of course Vue would do better if you gave the agent proper guidance." And they're right — I know from experience that the right CLAUDE.md, skills, and documentation context can dramatically improve agent output in any stack. But the fact that it produced excellent results in React, Hotwire, and Inertia+React without any of that, while Vue still struggled? That tells you something about the baseline. And the baseline only gets better when you add guidance on top.
What This Means for Stack Choice
If you're picking a stack for AI-assisted development, framework features and ecosystem aren't the only variables anymore. You need to consider how well the AI produces code in that stack.
Historically you'd pick a framework based on: does it solve my problem, does my team know it, is the ecosystem healthy? Now there's a fourth question: does the AI write good code in it?
For the current generation of LLMs, the answer is roughly:
React + shadcn/ui gets the best agent output. Path of least resistance if you're letting AI write most of your frontend. Rails and Ruby are excellent too, for different reasons — 20 years of conventions give the agent a lot to work with. Vue 3 the agent knows, but it doesn't produce polished results. You'll spend more time correcting. Newer or niche stacks, your mileage will vary.
But There's a Catch
I went with Hotwire anyway. I didn't want to.
The agent writes excellent React, but I don't know React — and honestly, I don't love JSX either. I'm a Vue SFC person aesthetically. But I have 22 years of Rails experience, and when something breaks at 11pm, I need to understand the stack well enough to debug it myself. More importantly: when the AI is writing most of the code, the most critical job left is reviewing it. I'll maintain it with the help of the AI too — but only the human can truly review what's being produced. If I can't read the code and judge whether it's correct, the AI's output quality doesn't matter.
Here's the irony: I tried Hotwire seriously in 2022 and bailed after months because I couldn't match what Quasar gave me in Vue. I don't find it aesthetically pleasing. I don't enjoy reading data-controller and data-action attributes. I didn't want this outcome.
But the AI changes that equation. The parts of Hotwire that frustrated me, writing all those Stimulus controllers and wiring up data attributes by hand, are exactly the parts the agent handles well. It produces clean, well-separated controllers without complaint. The gap that sent me back to Quasar in 2022 is the gap that AI fills in 2026.
For a solo developer leaning heavily on AI, the framework the agent excels at matters more than it used to. But it doesn't eliminate the need for your own expertise in the stack. "The AI writes great React" is less useful if you can't review the output or debug it when something goes wrong.
The sweet spot is a stack where both you and the AI are strong. For this project, that looks like Rails + Hotwire — I'm not abandoning Vue entirely. I'm still using Nuxt for my main business product and it's working fine; we're getting through it. But this was an experiment about testing new waters on a side project, and the results pointed somewhere I didn't expect.
For someone who knows React, the sweet spot would be React + Inertia + Rails (or React + whatever backend). The worst combination is a stack where the AI is weak and you're relying on it heavily — that was my Vue experience in this experiment.
The Takeaway
Framework choice for vibe-coded projects isn't just about the framework anymore. You need to weigh what you know (because you're still debugging and reviewing it), what the AI writes well (because it's doing most of the typing), and what actually solves your problem (because architecture still matters).
Back to Josef's original question — Tanstack Start vs React + Inertia + Rails vs Nuxt: I'd bet React + Inertia + Rails produces the best agent output of those three, and the Inertia architecture is genuinely good (our prototype proved it). But if you know Nuxt/Vue deeply and can fill in the gaps the AI leaves, that changes the calculus.
Test it yourself. Have the AI build the same UI in two stacks. The difference might surprise you.