Every few months someone asks me the same question: "which JavaScript framework should I actually learn?" This time I'm answering it with an actual ranking instead of just vibes. I scored all 18 tools below on five criteria that matter for different reasons:
- Latency - how fast the app feels to a real user: bundle size, hydration cost, time-to-interactive
- Robustness - how well it holds up in production, at scale, with edge cases and real traffic
- Batteries-included - how much comes built in (routing, forms, SSR, DI, tooling) versus how much you have to assemble yourself
- Stability - how settled the API is, how often breaking changes hit you, how safe it is to build a 5-year project on
- Industry demand - how many real job postings and production teams are actually using it right now
Each tool gets a score from 1 to 5 on each criterion, and the composite is a simple average of all five. Where two tools tied, I broke the tie using industry demand first, then robustness.
I'm splitting the list into two groups, because they're not really competing with each other:
- UI Libraries - React, Vue, Svelte, SolidJS, and similar. These give you components and reactivity, nothing more. No built-in routing, no SSR, no deployment story.
- Frameworks - Angular (a full self-contained framework) and the meta-frameworks that sit on top of a UI library (Next.js on React, Nuxt on Vue, SvelteKit on Svelte, and so on). These add routing, SSR, and a deployment story.
The composite ranking itself hasn't changed at all - within each group below, the order is exactly the same relative order as before. I've just stopped interleaving the two categories so it's a fairer, cleaner comparison: UI libraries against UI libraries, frameworks against frameworks.
Within UI Libraries, the composite order works out to: React, Vue, Preact, Svelte, Lit, Alpine.js, HTMX, SolidJS, Qwik. Within Frameworks, it's: Next.js, Angular, Astro, Nuxt, Remix/React Router v7, SvelteKit, TanStack Start, SolidStart, QwikCity. That's the order both parts below follow.
Worth calling out immediately: latency winners are not composite winners. SolidJS and Qwik score at or near the top on raw speed but land at the bottom of their group, because industry demand and robustness pull them down hard - same story with SolidStart and QwikCity in the frameworks group. If raw performance is your only criterion, skip straight to those sections. If you want the best all-around bet, start from the top of each group instead.
Part 1: UI Libraries (Ranked)
1. React
React sits at number one in this group, not because it's weak anywhere, but because "batteries-included" genuinely scores low - plain React gives you a rendering model and nothing else. You bring your own router, your own state library, your own everything. What pulls it to the top is the highest industry demand score on this entire list and near-max robustness.
What React actually gives you is a component model built around one core idea: your UI is a function of your state. React 19 shipped the React Compiler, which automatically memoizes components and values for you instead of making you sprinkle useMemo and useCallback everywhere by hand.
Why reach for React:
- The ecosystem is unmatched - almost any problem you hit already has a well-maintained library for it
- Hiring is easiest here - more developers know React than any other library on this list
- The React Compiler (React 19+) handles a lot of the manual performance tuning you used to have to do by hand
- Pairs with any framework in Part 2 - Next.js, TanStack Start, Remix all build on it
When to use it - example projects:
- A SaaS dashboard that a team of 5+ engineers will maintain for years
- A startup product where you'll need to hire React developers quickly as you grow
- Any project where a client or company specifically asks for React because their existing team already knows it
When to skip it:
- A small marketing site or landing page - the build tooling is overkill for a few static sections
- A weekend project or hackathon prototype - you'll spend more time on setup than on the idea itself
2. Vue
Vue ties React on composite score, trading a bit of industry demand for better out-of-the-box coherence. The Composition API in Vue 3 gives you hooks-like ergonomics without some of React's sharper edges - reactivity in Vue is based on proxies, so you don't run into the same "why didn't this re-render" confusion nearly as often.
Single-file components - the .vue files with template, script, and style all in one place - are genuinely pleasant to work in. Vue's ecosystem isn't as sprawling as React's, but it's more coherent: the official router, Pinia, and Nuxt are all maintained by the same core team.
Why reach for Vue:
- The Composition API gives you React-hook-like power without React's sharper edges (stale closures, dependency arrays)
- Single-file components keep template, logic, and styles in one readable file
- The official tooling is coherent - router, Pinia (state), and Nuxt (framework) are built by the same team
- Easier ramp-up for developers coming from a more traditional HTML/CSS background
When to use it - example projects:
- An internal admin panel built by a small, mixed frontend/backend team
- A content-driven site using Nuxt for SSR and SEO
- A team that tried React, found the mental model frustrating, and wants something equally modern but more approachable
When to skip it:
- A project where you specifically need the largest possible hiring pool
- A codebase that will lean heavily on third-party React-only libraries you can't easily replace
3. Preact
Preact scores surprisingly well on composite - it maxes out stability (the API surface barely changes) and scores near-top on latency, even though industry demand is modest since most teams treat it as a React swap-in rather than a primary choice.
Preact exists to answer one question: "I want React's API, but I don't want React's file size." It's a 3KB alternative that implements most of the React API - same hooks, same component model, same JSX - but with a dramatically smaller runtime.
Why reach for Preact:
- Roughly 3KB - a fraction of React's runtime size
- Near drop-in compatibility with the React API via
preact/compat - Same hooks, same JSX, same component model - no new mental model to learn
- Directly improves Core Web Vitals scores on pages measured for SEO and conversion
When to use it - example projects:
- A marketing landing page where every Lighthouse point affects ad spend or SEO ranking
- An e-commerce product page where load speed directly affects sales
- Any project where you'd normally reach for React but the bundle size budget is tight
When to skip it:
- A large, long-lived application - some advanced React libraries don't play perfectly with Preact's compatibility layer
- A team that wants the absolute widest ecosystem support without edge-case compatibility issues
4. Svelte
Svelte lands mid-table mostly because "batteries-included" is intentionally low at the library level (that's what SvelteKit in Part 2 is for) and the Svelte 5 runes rewrite briefly dented its stability score. Instead of shipping a runtime library that diffs a virtual DOM, Svelte is a compiler - it turns your component code into plain, highly optimized JavaScript at build time.
Svelte 5 introduced "runes" - $state(), $derived(), $effect() - bringing the same fine-grained, no-virtual-DOM update model SolidJS uses. In real numbers, Svelte 5 renders large lists several times faster than Vue and ships noticeably smaller bundles than React.
Why reach for Svelte:
- It's a compiler, not a runtime library - a lot of the work React/Vue do in the browser, Svelte does ahead of time at build
- Noticeably less boilerplate for the same functionality
- Svelte 5's runes bring the same fine-grained, no-virtual-DOM update model SolidJS uses
- Smaller bundles and faster renders than most of this list
When to use it - example projects:
- A content-heavy blog or marketing site where page load speed directly affects conversions
- A team that's tired of React's boilerplate and wants the fastest "aha, this just makes sense" learning curve
- A performance-first product where every kilobyte of JS ships to real users on slow connections
When to skip it:
- A project that depends on third-party UI libraries that don't have a Svelte version
- A team that specifically needs the largest hiring pool of available developers
5. Lit
Lit ties Svelte on composite score through a completely different profile - it maxes out stability (built on native web standards that don't change) but scores the lowest batteries-included rating on this whole list, since it deliberately provides nothing beyond component definition.
Lit is Google's answer to "what if we built UI components using actual browser standards instead of a framework-specific abstraction?" It's a thin layer on top of native Web Components - a component you build in Lit is a real custom HTML element that works in literally any framework, or no framework at all.
Why reach for Lit:
- Built on native Web Components - the browser's own standard, not a framework-specific abstraction
- A Lit component works in any framework, or no framework at all
- No vendor lock-in - components you build today will still work regardless of what framework your team picks next
- Lightweight compared to shipping a full framework just to render a few shared components
When to use it - example projects:
- A cross-team design system shared between teams on React, Angular, and Vue simultaneously
- A browser extension where you don't want to bundle an entire framework runtime
- A component library meant to be published and consumed outside your own codebase
When to skip it:
- A typical single-team application - you'll miss the higher-level conveniences (routing, state patterns) dedicated frameworks provide
6. Alpine.js
Alpine maxes out the latency score (nothing loads faster than "no build step at all") but scores the lowest possible batteries-included rating on purpose - it was never meant to replace a full framework, only to add sprinkles of interactivity.
Alpine is the tool I reach for when React, Vue, or Svelte would genuinely be overkill. You add attributes directly to your markup (x-data, x-show, x-on:click), and Alpine wires up the behavior right there in the HTML - no build step, no bundler, no component tree.
Why reach for Alpine.js:
- No build step, no bundler, no component tree - you write behavior directly as HTML attributes
- Feels like modern jQuery - reactive data-binding without manual DOM manipulation
- Adds interactivity to server-rendered pages without pulling in an entire frontend framework
- Extremely small footprint for what it does
When to use it - example projects:
- A Django, Laravel, or Rails app that just needs a dropdown, modal, or filter to feel interactive
- A small business site with no existing frontend build pipeline
- Any project where the backend does the heavy lifting and the frontend only needs light "sprinkles"
When to skip it:
- A complex client-side application with deep component hierarchies and significant client-only state
- Anything that will eventually need real component composition and reusable logic across dozens of views
7. HTMX
HTMX has almost the identical profile to Alpine.js - excellent latency, deliberately minimal batteries-included, modest demand - and edges out SolidJS on composite purely on robustness, since server-driven HTML swapping has fewer moving parts to break than a full client-side reactivity engine.
HTMX's whole idea is that you can get most of what feels like a modern single-page app by letting your server return small chunks of HTML that HTMX swaps into the page, triggered by attributes on your existing markup. There's no client-side state to manage, no virtual DOM, no build step.
Why reach for HTMX:
- No client-side state to manage - your server stays the single source of truth
- No virtual DOM, no build step - just attributes on existing HTML
- UI logic lives once, in your server templates - instead of duplicated across a backend API and a frontend framework
- Dramatically simpler mental model for anything that's fundamentally a CRUD interface
When to use it - example projects:
- An internal admin panel or back-office tool where speed of development matters more than rich interactivity
- A content management interface that's mostly forms, tables, and lists
- Any server-rendered app where a full SPA framework would be solving a problem you don't actually have
When to skip it:
- A design tool, game, or highly interactive app with complex client-only state
- An offline-capable app that needs to function without round-tripping to the server
8. SolidJS
SolidJS has the best raw performance profile of any pure UI library on this list, but it lands here because industry demand and batteries-included are both genuinely low - you're buying into an architecture, not a job market.
SolidJS looks almost identical to React at a glance - same JSX, similar hooks-style APIs - but underneath, it works completely differently. Solid doesn't re-render components. Independent benchmarks routinely show Solid running around 70% faster than React on the same workload, with bundle sizes under 20KB.
Why reach for SolidJS:
- No virtual DOM at all - Solid builds a reactive graph once and updates only the exact DOM nodes tied to a changed value
- ~70% faster than React in independent benchmarks, with bundles typically under 20KB
- Familiar JSX syntax - if you already know React, the learning curve is small
- No wasted re-renders on large, frequently updating lists
When to use it - example projects:
- A real-time trading or analytics dashboard with constantly updating numbers
- A data visualization tool rendering thousands of rows or points at once
- A team that already knows React's JSX and wants a lower-overhead alternative without relearning syntax
When to skip it:
- A project where hiring pool size or long-term ecosystem stability matters more than raw performance
- A team unwilling to bet on a smaller community for library support
9. Qwik
Qwik lands last in this group, and it's worth explaining why, since it has the same top latency score as SolidJS. Robustness, stability, and industry demand are all the lowest on this list - it's the newest architectural idea here, and that novelty is exactly what makes it both compelling and risky.
Qwik takes a genuinely different approach to JavaScript hydration cost. Qwik's whole premise is "resumability" - the server sends HTML that's already interactive-looking, and Qwik only loads the JavaScript for a specific piece of the page the moment the user actually interacts with it. It's past the experimental stage - Qwik and its framework QwikCity (Part 2) are genuinely production-ready.
Why reach for Qwik:
- Resumability instead of hydration - the browser resumes exactly where the server left off
- Near-instant time-to-interactive, even on huge, complex pages
- JavaScript loads only for the piece of the page the user actually touches
- Production-ready - already used in real, performance-critical products
When to use it - example projects:
- A large e-commerce catalog with thousands of products where every millisecond of load time affects conversion
- A content or media site that needs to stay fast despite being huge and complex
- Any project where Core Web Vitals and SEO are the top priority, above developer familiarity
When to skip it:
- A team that wants a well-trodden path with abundant tutorials, Stack Overflow answers, and hiring options
- A project timeline that doesn't allow for the learning curve of a genuinely different mental model
Part 2: Frameworks - Full & Meta-Frameworks (Ranked)
These add routing, SSR, and a deployment story on top of a UI library (or, in Angular's case, are self-contained from the start).
1. Next.js
Built on React
Next.js tops this group because it's the rare tool that scores well on almost everything at once. Plain React gives you components; Next.js gives you an application - file-based routing, server-side rendering, static generation, image optimization, and (with the App Router) React Server Components, which let parts of your UI render entirely on the server and never ship their JavaScript to the browser at all.
The App Router's server components model is genuinely a different way of thinking about a React app - some components run only on the server, some run on the client, and Next.js handles the boundary between them. It's powerful, but it's also the single biggest source of confusion for developers moving from plain React.
Why reach for Next.js:
- The most mature React framework - the largest ecosystem, the most tutorials, the deepest hiring pool
- React Server Components let you ship less JavaScript by rendering parts of the UI entirely on the server
- File-based routing, image optimization, and built-in SEO tooling out of the box
- Deploys cleanly to Vercel (its creator) but also runs on most other hosts and self-hosted Node servers
When to use it - example projects:
- A public-facing marketing or e-commerce site that needs strong SEO and fast initial loads
- A content platform mixing static pages, server-rendered pages, and client interactivity
- Any team hiring React developers who expect to work with a modern framework, not plain React + Vite
When to skip it:
- A pure internal tool behind a login wall with no SEO need - a plain React + Vite SPA is simpler
- A team not ready to learn the Server Components vs Client Components mental split
2. Angular
Self-contained full framework
Angular scores near the top because it maxes out robustness and batteries-included - the two criteria that matter most once a codebase and team both grow past a certain size. Yes, it has a steeper learning curve than anything else on this list. Yes, TypeScript is effectively mandatory, and the dependency injection system takes real time to understand. But for genuinely large systems, that opinionated structure stops being a burden and starts being the thing that keeps the codebase from turning into chaos.
Angular gives you everything out of the box: routing, forms, HTTP client, dependency injection, testing utilities, a CLI that scaffolds everything for you. Angular has also quietly gone through its biggest internal overhaul in years - signals are now the default reactivity model, zoneless change detection is production-ready (Google itself runs it on Google Fonts), and the "Angular is slow and old-fashioned" reputation is increasingly outdated.
Why reach for Angular:
- Everything ships in the box - routing, forms, HTTP client, dependency injection, testing, CLI scaffolding
- Enforced structure means every Angular app looks roughly the same, which pays off hugely in large teams
- Signals are now the default reactivity model, combined with zoneless change detection
- TypeScript-first by design, which catches a lot of bugs before they ship
When to use it - example projects:
- An enterprise dashboard or banking application with dozens of engineers touching the same codebase
- A long-lived internal system where new hires need to onboard fast using established conventions
- Any project where consistency across the team matters more than developer freedom
When to skip it:
- A solo project or small team - the ceremony and ramp-up time aren't worth it
- Anything where you want to move fast without a structured setup process
3. Astro
Framework-agnostic
Astro takes a genuinely different stance from every other framework in this group: most pages should ship zero JavaScript by default. That single decision is why it maxes out the latency score and lands this high overall despite having a smaller hiring market than Next.js or Angular. Astro renders your components to static HTML at build time, and only "hydrates" the specific interactive pieces you explicitly mark - a technique called the islands architecture.
What makes Astro unusual is that it's not tied to one UI library. You can drop React components, Vue components, Svelte components, and plain HTML all into the same Astro project, each hydrated independently, each only when needed. This very blog is built on Astro, which should tell you where I land on it for content-heavy sites.
Why reach for Astro:
- Zero JavaScript by default - the islands architecture only hydrates what's explicitly marked interactive
- Framework-agnostic - mix React, Vue, Svelte, or plain HTML components in the same project
- Best-in-class for content sites - blogs, marketing pages, documentation, portfolios
- Excellent built-in SEO and Core Web Vitals scores with almost no manual tuning
When to use it - example projects:
- A blog or marketing site where most content is static and only a few widgets need interactivity
- A documentation site that needs to load instantly and rank well in search
- A team that wants to use components from multiple UI libraries in one project without picking a single one
When to skip it:
- A highly interactive, app-like product (a dashboard, an editor, a real-time collaboration tool) - use Next.js, TanStack Start, or plain React/Vue instead
- A team that wants a single, unified component model rather than mixing libraries
4. Nuxt
Built on Vue
Nuxt is Vue's answer to Next.js, and it scores just below it mostly on industry demand - it's just as capable, just less widely hired for. Nuxt gives you file-based routing, auto-imports, and a hybrid rendering model - you can mix static generation, server-side rendering, and client-only rendering on a per-route basis in the same app.
The thing I appreciate most about Nuxt is Nitro, its server engine, which lets the same Nuxt app deploy to Node, Vercel, Cloudflare Workers, Deno, or a plain static host with almost no configuration changes.
Why reach for Nuxt:
- Auto-imports eliminate a huge amount of boilerplate import statements
- Nitro's deploy-anywhere model - the same app runs on Node, Vercel, Cloudflare Workers, or a static host
- Hybrid rendering per route - mix SSG, SSR, and client-only rendering in the same app
- Maintained by the same core team as Vue itself, so the two stay well aligned
When to use it - example projects:
- Any Vue team building something that needs SSR/SEO - this is the natural default, the same way Next.js is for React
- A project that needs to deploy across multiple hosting environments without rewriting server code
- A content site or e-commerce store built with Vue that needs strong SEO
When to skip it:
- Teams not already using Vue - there's no reason to adopt Nuxt without first choosing Vue
- Projects needing the absolute largest framework ecosystem (Next.js still wins there)
5. Remix (now React Router v7)
Built on React
Remix built its reputation on a simple idea: use web platform fundamentals instead of fighting them. Forms submit via actual HTML forms and the Fetch API, and the whole framework is built around progressive enhancement - your app should work even if JavaScript fails to load.
Remix has since merged into React Router v7, which cost it a bit on the stability score during the transition, but the underlying philosophy - nested routing with per-route data loading - carries over either way.
Why reach for Remix / React Router v7:
- Progressive enhancement by default - your app degrades gracefully instead of showing a blank page without JS
- Nested routing with per-route data loading keeps data-fetching logic close to the route that needs it
- Built on web standards (Fetch API, HTML forms) rather than framework-specific abstractions
- A gentler mental model than Server Components if you want SSR without the Next.js App Router's complexity
When to use it - example projects:
- A form-heavy application (checkout flows, multi-step wizards) that benefits from real HTML form semantics
- A team that wants SSR and nested routing without adopting React Server Components
- Products that need to work reasonably well even on flaky connections or with JS disabled
When to skip it:
- A team already deep into the Next.js App Router and Server Components ecosystem - switching philosophies mid-project is costly
- Projects that specifically want React Server Components, which Remix/React Router doesn't use the same way
6. SvelteKit
Built on Svelte
SvelteKit scores well on batteries-included and latency but loses ground on industry demand compared to the frameworks above it. It's Svelte's own official framework, built by the same core team, giving you file-based routing, server-side rendering, static generation, and API routes, plus load functions that fetch data for a page before it renders.
Because Svelte itself is a compiler, SvelteKit inherits that same "less code, smaller output" advantage at the framework level. Adapters let the same SvelteKit app deploy to Node, Vercel, Cloudflare Pages, Netlify, or as a fully static site.
Why reach for SvelteKit:
- Built by the same team as Svelte, so the two stay tightly aligned as both evolve
- Adapter system lets one app target Node, Vercel, Cloudflare, Netlify, or static hosting with minimal config changes
- Inherits Svelte's small-bundle, low-boilerplate philosophy at the full application level
loadfunctions give you a clean, colocated way to fetch data per route
When to use it - example projects:
- Any Svelte team building a real production site that needs SSR, routing, and SEO
- A content site or small SaaS product where bundle size and load speed matter as much as features
- Teams that want flexible deployment targets without committing to one hosting platform
When to skip it:
- Teams not already committed to Svelte - there's no reason to adopt SvelteKit without choosing Svelte first
- Projects needing the deepest third-party ecosystem and hiring pool, where Next.js is still the safer bet
7. TanStack Start (+ Router & Query)
Built on React
TanStack Start scores well on batteries-included and latency but takes a real hit on stability and industry demand simply because it's the newest framework on this list. The team behind it built TanStack Query (formerly React Query) and TanStack Router - already the de facto standard for data fetching and type-safe routing in a huge number of serious React apps.
What sets this apart from Next.js is the type-safety obsession. TanStack Router gives you fully typed routes, typed search params, and typed loaders - if you get a route path wrong, TypeScript catches it at compile time.
Why reach for TanStack Start:
- Best-in-class type safety for routes, search params, and data loaders
- Built on TanStack Query, already the standard for server-state caching in serious React apps
- Framework-agnostic roots - the router and query libraries work standalone even if you don't adopt the full Start framework
- Not tied to any single hosting platform the way Next.js leans toward Vercel
When to use it - example projects:
- A data-heavy internal dashboard with lots of client-server data synchronization
- A team that already uses TanStack Query and wants the same philosophy extended to routing and SSR
- Projects where type safety across the entire data flow is a hard requirement
When to skip it:
- Teams that want the most battle-tested, widely documented option - it's newer than Next.js and the ecosystem is still growing
- Simple content sites where you don't need this level of type-safe data plumbing
8. SolidStart
Built on SolidJS
SolidStart carries Solid's excellent latency profile into full server-rendered applications, but stability and industry demand are both still low simply because the ecosystem is young.
SolidStart adds file-based routing, SSR, streaming, and server functions on top of Solid's already-fast reactive core. Because Solid doesn't re-render on state changes the way React does, a SolidStart app's server-rendered HTML hydrates into an interactive page with less client-side work than an equivalent Next.js app doing the same job.
Why reach for SolidStart:
- Extends Solid's no-virtual-DOM performance model to full server-rendered applications, not just components
- File-based routing and server functions with the same fine-grained reactivity Solid is known for
- Smaller runtime overhead on hydration compared to virtual-DOM-based frameworks
- A natural next step if you've already chosen Solid for its raw performance
When to use it - example projects:
- A performance-critical SSR application - a real-time dashboard or data-heavy tool that also needs SEO or a fast first load
- A team that picked SolidJS specifically for performance and now needs routing and SSR to match
- Products where hydration cost is a measured, real concern, not just a theoretical one
When to skip it:
- Teams not already using SolidJS - there's no reason to start here without choosing Solid first
- Projects that need a large, mature ecosystem of plugins, adapters, and community examples - it's still comparatively young
9. QwikCity
Built on Qwik
QwikCity ties SolidStart almost exactly - same excellent latency, same low robustness and demand scores that come with being a young ecosystem. It's where Qwik's resumability idea becomes a full application rather than just a component-level trick, adding file-based routing, layouts, and server-side data loading while preserving the core promise that the browser never re-executes work the server already did.
Why reach for QwikCity:
- Extends resumability to full-page routing and layouts, not just individual components
- File-based routing with server-side data loading, similar shape to Next.js or SvelteKit conventions
- Keeps time-to-interactive near-instant even as an application grows to hundreds of routes
- Built by the same team as Qwik, so the resumability model stays consistent end to end
When to use it - example projects:
- A large multi-page e-commerce platform where page count and load speed both matter at scale
- A content platform with thousands of pages that still needs fast navigation between them
- Teams that already adopted Qwik for a component-level win and now need the same benefit at the routing level
When to skip it:
- Teams wanting a well-documented, widely adopted path - the ecosystem here is the youngest of the frameworks on this list
- Projects with a short timeline that can't absorb the learning curve of resumability at both the component and routing level
So Which One Should You Actually Learn?
For a UI library: React is still the safest single investment - highest demand, near-max robustness, and it pairs with every framework in Part 2. Vue is a near-identical composite score if you want a more coherent official ecosystem in exchange for a smaller hiring pool.
For a framework: the composite ranking points straight at Next.js - the best all-around combination of demand, robustness, and batteries-included tooling, and that combination is what actually gets you hired and keeps a production app maintainable for years. If your project is fundamentally content, not an app, Astro is a near-tie with Next.js and will usually produce a faster result for that specific job.
If you're chasing the absolute lowest latency number regardless of ecosystem size, the bottom of each table - SolidJS and Qwik in Part 1, SolidStart and QwikCity in Part 2 - is where you'll find it. Just go in knowing you're trading job-market safety and ecosystem maturity for raw speed.
And if you're building something genuinely large with a big team that needs enforced structure over developer freedom, don't let Angular's position below Next.js fool you - it's a near-tie, and for the specific case of a large enterprise codebase, it may well be the better call.
There isn't a single correct answer here. There's only the answer that matches what you're actually building, who's going to maintain it, and how long it needs to last.