Use a framework when your app has 3+ interconnected stateful components, will be maintained by 3+ developers, or needs to ship complex UI over 2+ years. Use vanilla JS for landing pages, widgets, marketing sites, or anything where bundle size and load speed are critical. The deciding factor is state complexity, not project size.
Someone in the kickoff meeting says “let’s use React.” Someone else says plain JavaScript is fine. Both are guessing. Neither has criteria — just vibes and whatever they shipped last.
The problem with the when to use framework vs vanilla javascript debate isn’t that the answer is complicated. It’s that nobody gives you a repeatable way to decide. Every article says “it depends” and leaves you standing there.
Here’s a 5-question test. Run it. By the end, you’ll know which to pick — and you’ll be able to defend that choice in a code review.
The 2026 Landscape Is Not What You Think
If your mental model for this decision was formed before 2024, update it. The calculus shifted.
Vanilla got stronger. Native ES modules work everywhere. The Fetch API replaced XMLHttpRequest years ago. Web Components — Custom Elements, Shadow DOM — have full browser support. CSS nesting landed. The View Transitions API handles animations that used to require a framework. You can build things natively now that needed jQuery or React three years ago.
Frameworks got smarter too. React 19 Server Components reduce the JavaScript you ship to the client. Signals — adopted by Preact, Angular, and SolidJS — make reactivity cheaper. Svelte 5’s runes compile away the runtime entirely.
And here’s a quiet shift: AI coding tools work better with vanilla. Simpler syntax, fewer framework-specific patterns to hallucinate. If you’re using AI-assisted development — and most teams are now — vanilla’s directness is an advantage.
The gap between vanilla and frameworks has narrowed. Which means the javascript framework decision now depends on your project specifics, not on which technology has better marketing.
So what actually drives the decision?
The Cost Nobody Puts in the README
Most framework-vs-vanilla comparisons focus on developer experience at the time of writing. That’s the wrong metric. The real question is total cost of ownership over 6 to 18 months.
Here are the numbers nobody shows you.
Bundle size. A vanilla todo app: roughly 2 KB. The same app in React: 42 KB before you’ve written a single line of business logic. That’s a 20x difference at baseline. If you care about why your site loads slowly, this is where it starts.
Complexity tax. A framework project carries node_modules, build configs, framework-specific abstractions, and opinions about file structure. A vanilla project carries your code. That’s it.
Maintenance cost. Frameworks release major versions. Migrating React 18 to 19 is real work — new APIs, changed defaults, deprecated patterns. Vanilla JavaScript you wrote in 2020 still runs unchanged in every browser today.
But here’s the part the vanilla evangelists skip: frameworks give you patterns. On a 5-person team, React conventions prevent five different approaches to state management. That consistency has real value — especially when someone leaves the team and someone new inherits the code.
The question isn’t which is better. It’s where the framework overhead earns back its cost. That’s what the checklist answers.
The Five-Question Decision Framework
Five yes-or-no questions. Concrete thresholds, not vibes. Score 3 or more “yes” answers and reach for a framework. Score 0 to 2 and start with vanilla — or the hybrid approach in the next section.
1. Does your UI have 3+ components that share and react to the same state?
A form with live validation across fields. A dashboard where filters affect multiple panels simultaneously. A chat interface with presence indicators and real-time updates. If your state lives in one place and flows one direction, vanilla handles it. If state is a web of dependencies, you want a framework’s state management — or you’re going to build one yourself, badly.
2. Will 3+ developers work on this codebase at the same time?
Frameworks enforce conventions. Component structure, data flow patterns, file organization — these are decisions React makes so your team doesn’t have to fight about them. Solo dev or pair? Vanilla’s flexibility is a feature. Three or more people? That flexibility becomes a liability. Without shared conventions, three developers write three architectures.
3. Will this code be actively developed for 2+ years?
Long-lived projects benefit from framework ecosystems: established patterns for routing, authentication, data fetching, testing. A framework is infrastructure for the long haul. Short-lived projects — campaign sites, prototypes, internal tools with a six-month shelf life — never recoup the setup cost. Build vanilla, ship it, move on.
4. Do you need client-side routing, complex forms, or optimistic UI updates?
These are solved problems in frameworks. Building client-side routing in vanilla JavaScript is possible. Building it well — with code splitting, scroll restoration, error boundaries, loading states — means you’re writing your own framework. You’ll just write a worse one.
5. Is this a full client-side application, or server-rendered pages with interactive sprinkles?
Server-rendered content with a few interactive widgets? Vanilla. Maybe Alpine.js or htmx if you want some structure. A full single-page application where the browser handles all routing and rendering? That’s framework territory.
| Question | Vanilla | Framework |
|---|---|---|
| State shared across 3+ components? | No | Yes |
| 3+ concurrent developers? | No | Yes |
| Active development 2+ years? | No | Yes |
| Client routing / complex forms? | No | Yes |
| Full SPA, not server-rendered? | No | Yes |
Here’s the honest part: plenty of projects score 2. Right on the boundary. If that’s you, don’t flip a coin — there’s a third option.
The Hybrid Path Most Teams Miss
The framework-versus-vanilla framing is a false binary. The best answer for grey-area projects is often: both.
Progressive enhancement. Start with vanilla HTML, CSS, and JavaScript. Add a framework component only where interactivity demands it. A marketing site with one interactive pricing calculator doesn’t need React for the entire page — just the calculator. The rest is static markup that loads instantly.
Web Components as the bridge. Custom Elements work in every browser and inside every framework. Build your interactive widgets as Web Components. If you later adopt a framework, they still work — no rewrite. If you don’t, they’re self-contained and portable.
Islands architecture. Astro and Fresh formalize this pattern: server-render the page, hydrate only the interactive “islands.” You get vanilla’s performance with framework developer experience where it actually matters. The rest of the page ships zero JavaScript.
The key insight: the unit of decision isn’t the project. It’s the component. Some parts of your app need a framework. Most don’t. You’re allowed to use both.
But if you’re in the grey area and tempted to “just use React for everything in case we need it later” — that’s the framework overhead you can’t earn back. Start vanilla. Promote to a framework when the complexity earns it.
Make the Call
Next time you’re in that kickoff meeting and someone suggests React, you don’t have to guess.
Run the five questions. If the answer is clear, ship with confidence. If it’s grey, start vanilla and add a framework where the complexity demands it — not where habit suggests it.
The defensible position isn’t “frameworks are bad” or “vanilla is dead.” It’s: “I chose this because of these specific criteria, and here’s when I’d revisit that choice.”
The best technical decisions aren’t about what’s trending. They’re about what’s honest about your project’s actual needs. That’s the whole test.