[{"data":1,"prerenderedAt":221},["ShallowReactive",2],{"navigation":3,"/blog/vue-vs-react-headless-cms":54,"/blog/vue-vs-react-headless-cms-surround":216},[4],{"title":5,"path":6,"stem":7,"children":8,"page":53},"Blog","/blog","blog",[9,13,17,21,25,29,33,37,41,45,49],{"title":10,"path":11,"stem":12},"One Maintenance Session on an Agent-Assisted Client Project","/blog/agent-maintenance-session","blog/agent-maintenance-session",{"title":14,"path":15,"stem":16},"ESLint Without Prettier: One Tool for Formatting and Linting in TypeScript","/blog/eslint-best-practice","blog/eslint-best-practice",{"title":18,"path":19,"stem":20},"Building GoSpendl: A Bitcoin Product Search Engine, End to End","/blog/gospendl-builder-story","blog/gospendl-builder-story",{"title":22,"path":23,"stem":24},"Why Your Startup Should Go Headless CMS from Day One","/blog/headless-cms-startups","blog/headless-cms-startups",{"title":26,"path":27,"stem":28},"How I Built a Token-Efficient Crawler for 900+ Shops with Crawl4AI","/blog/how-i-built-a-token-efficient-crawler","blog/how-i-built-a-token-efficient-crawler",{"title":30,"path":31,"stem":32},"Migrating a Live B2B Platform to AWS Without Stopping the Business","/blog/migrating-live-b2b-platform-aws","blog/migrating-live-b2b-platform-aws",{"title":34,"path":35,"stem":36},"Nuxt 4 WebSockets Are Elegant. Here's Why They Break on Vercel.","/blog/nuxt-websockets-vs-vercel","blog/nuxt-websockets-vs-vercel",{"title":38,"path":39,"stem":40},"Host Your Docker Container on Railway in 5 Minutes (8GB RAM for $5)","/blog/railway-smart-docker-host","blog/railway-smart-docker-host",{"title":42,"path":43,"stem":44},"Supabase vs Custom Auth: What I Recommend for Early-Stage SaaS","/blog/supabase-vs-custom-auth","blog/supabase-vs-custom-auth",{"title":46,"path":47,"stem":48},"Vue vs React: What Vapor Mode Actually Changes","/blog/vue-vs-react-headless-cms","blog/vue-vs-react-headless-cms",{"title":50,"path":51,"stem":52},"How to Migrate WordPress to Strapi Headless CMS (With 1,000+ Posts)","/blog/wordpress-to-strapi-migration","blog/wordpress-to-strapi-migration",false,{"id":55,"title":46,"author":56,"body":60,"date":206,"description":207,"extension":208,"image":209,"meta":210,"minRead":211,"navigation":212,"path":47,"seo":213,"sitemap":214,"stem":48,"__hash__":215},"blog/blog/vue-vs-react-headless-cms.md",{"name":57,"avatar":58},"Niklas Grieger",{"src":59,"alt":57},"/profile.jpg",{"type":61,"value":62,"toc":197},"minimark",[63,68,80,83,86,90,93,96,99,116,119,122,125,129,140,143,147,150,157,167,170,174,177,180],[64,65,67],"h2",{"id":66},"why-react-after-seven-years-of-vue","Why React, after seven years of Vue",[69,70,71,72,79],"p",{},"Every business project I've built in the last seven years has been Vue or Nuxt. Two recent exceptions broke that streak: WPEscape's demo frontends, and ",[73,74,78],"a",{"href":75,"rel":76},"https://kinderleicht-hannover.de/",[77],"nofollow","Kinderleicht",", a client booking site - both in React and Next.js.",[69,81,82],{},"The honest reason is two things, not one deep technical argument: I wanted the learning experience myself, and most people evaluating these kinds of projects are more likely to be running React than Vue. Popularity, not architecture, made the decision - and I say that as someone who's still firmly in the Vue camp.",[69,84,85],{},"That's really what this post is - not a benchmark or a \"which one wins\" argument (for real-world apps, neither does, more on that below). Just what actually felt different switching a Vue-shaped brain over to React for real work, and the one architectural change that's making me rethink the default for my next project.",[64,87,89],{"id":88},"what-vapor-mode-actually-changes","What Vapor Mode actually changes",[69,91,92],{},"This is the part I didn't see coming when I started looking into it, and it's the real reason I'd point someone toward Vue right now if they're starting something new.",[69,94,95],{},"Every mainstream framework has run on the same core idea since 2013: keep a lightweight JavaScript copy of the DOM in memory, diff it against the previous version when state changes, and apply only the minimal set of real DOM updates. React popularized it. Vue adopted it. A decade of framework evolution has mostly been about making that diffing faster and more automatic.",[69,97,98],{},"Vue 3.6 broke from that entirely. Vapor Mode compiles components directly to imperative DOM operations at build time - no virtual DOM, no diffing step, no runtime reconciliation to speed up because there's nothing left to reconcile. It's opt-in per component, and worth being clear-eyed about: it's still early, not yet the recommended default for every production app, and adoption is meant to be gradual rather than all-at-once.",[69,100,101,102,106,107,110,111,115],{},"React's move in the same period was the React Compiler: automatic memoization, removing the need to hand-tune ",[103,104,105],"code",{},"useMemo"," and ",[103,108,109],{},"useCallback",". Genuinely useful, and it closes a real gap. But it's still optimizing ",[112,113,114],"em",{},"inside"," the virtual DOM model - React still diffs, just more efficiently. Nothing on React's current roadmap removes the virtual DOM the way Vapor Mode does.",[117,118],"vapor-vs-vdom-diagram",{},[69,120,121],{},"Independent benchmark runs (js-framework-benchmark, among others) put Vapor Mode meaningfully ahead of React for typical UI workloads - some published numbers put it in the same tier as Solid.js and Svelte, frameworks that were built compiler-first from day one rather than bolting it on later. I'd treat the exact multiples the way I treat any framework benchmark - directionally informative, not gospel - but the architectural story behind the numbers is real, not marketing.",[69,123,124],{},"That's a genuine fork in direction. Vue is testing whether the industry's decade-old assumption - that a virtual DOM is the price of ergonomic reactivity - still needs to be true. React, for now, is making its version of that assumption faster instead of questioning it. One of those is a more interesting bet on where frontend rendering goes next.",[64,126,128],{"id":127},"the-thing-i-still-dont-love-jsx","The thing I still don't love: JSX",[69,130,131,132,135,136,139],{},"Vue separates template and logic into distinct blocks in the same file - ",[103,133,134],{},"\u003Ctemplate>"," for markup, ",[103,137,138],{},"\u003Cscript setup>"," for logic. React's JSX puts them in the same expression: markup and JavaScript/TypeScript interleaved directly.",[69,141,142],{},"I get why people like it - one language, no context-switching, full type-checking on your markup for free. But I find Vue's separation more readable and more maintainable, especially once a component gets past trivial size. When markup is its own block, you can see the shape of what renders without also parsing the logic that produced it. That's a personal preference, not an objective ranking - plenty of very good developers feel the opposite.",[64,144,146],{"id":145},"state-management-more-similar-than-the-ecosystems-suggest","State management: more similar than the ecosystems suggest",[69,148,149],{},"Two comparisons that made the mental model transfer easier than expected:",[69,151,152,156],{},[153,154,155],"strong",{},"Context API is React's provide/inject."," Same problem (pass data down without prop-drilling through every level), same shape of solution, different syntax.",[69,158,159,162,163,166],{},[153,160,161],{},"Pinia is Vue's answer to what React solves with... a lot of different answers."," In Vue, if you need a proper state store, you reach for Pinia. That's not really a decision anymore - it's the default, endorsed by the core team, and there isn't a serious competing option most people reach for instead. In React, the equivalent decision is genuinely open: Zustand, Redux, Jotai, Recoil, plain Context plus ",[103,164,165],{},"useReducer"," - all valid, all with real tradeoffs, and picking one is an actual decision you have to make and justify. Vue's ecosystem converged. React's didn't, not for this.",[69,168,169],{},"Neither is objectively better - a single default lowers decision fatigue, more options serve more use cases. But it's a real, practical difference in what starting a new project feels like.",[64,171,173],{"id":172},"so-which-one-for-a-headless-cms-frontend","So which one, for a headless CMS frontend",[69,175,176],{},"If I'm picking for myself, on a new project, with no external pressure: Vue. The developer experience was already better for me before Vapor Mode existed, and now the framework is also making a real architectural bet on where rendering is heading, instead of just polishing what's already there.",[69,178,179],{},"That's not the full answer for everyone, though, and I'd be overselling it if I pretended otherwise. For real-world CMS-driven sites - fetching from Strapi, Sanity, or Storyblok, rendering content, handling normal amounts of interactivity - both frameworks are fast enough today that raw performance rarely decides the outcome on its own. And if I'm honest about the market reality that actually shaped my own choice for these two projects: more of the people you'll want to reach, hire, or hand a codebase to are on React. That's worth acknowledging even though it's not the technical reason, and even though it's the reason that usually wins.",[69,181,182,183,106,188,193,194],{},"Certificates.dev has certification tracks for both, if you want to go deeper on either: ",[73,184,187],{"href":185,"rel":186},"https://certificates.dev/vuejs?friend=DEVNIK",[77],"Vue",[73,189,192],{"href":190,"rel":191},"https://certificates.dev/react?friend=DEVNIK",[77],"React",". ",[112,195,196],{},"Affiliate links - I'm a partner of certificates.dev.",{"title":198,"searchDepth":199,"depth":199,"links":200},"",2,[201,202,203,204,205],{"id":66,"depth":199,"text":67},{"id":88,"depth":199,"text":89},{"id":127,"depth":199,"text":128},{"id":145,"depth":199,"text":146},{"id":172,"depth":199,"text":173},"2026-08-26T00:00:00.000Z","I've built every business project on Vue and Nuxt for seven years, and two recent ones in React and Next.js instead. Here's what genuinely felt different for headless CMS frontends, and why Vue just walked away from the virtual DOM entirely.","md","/blog/vue-vs-react-hero.png",{},6,true,{"title":46,"description":207},{"loc":47},"0ajEkQvcat9OZb1N6XajJ-OR9xpzuLmi5boDiLJ8Guo",[217,219],{"title":42,"path":43,"stem":44,"description":218,"children":-1},"Every SaaS founder faces the auth question early. Build it yourself or use Supabase? Here's my honest take after building both — and the 3 questions that make the decision easy.",{"title":50,"path":51,"stem":52,"description":220,"children":-1},"Step-by-step guide to migrating a WordPress site with 1,000+ posts and media to a Strapi headless CMS using WPEscape, a purpose-built WordPress to Strapi migration tool.",1787514668167]