It's so easy to build a website that it's never been harder.
Whether you're new to the JavaScript ecosystem or a seasoned veteran, you know how diverse the "getting started" landscape has become. There are dozens of frameworks and "meta-frameworks" available to spin up your next project, each catering to different needs and team communication styles.
This post makes sense of the madness! Here's my field guide to the meta-framework-iverse.
First, what's a meta-framework?
As the name implies, a meta-framework is a system one level above that stitches multiple frameworks together.
React is a great frame of reference. We'll ignore the whole debate on whether React is a "library" or a "framework" for now, since many refer to React as a UI "framework" these days. This framework is built for an important task: taking a blob of data or "state," and rendering an interface to the screen to interact with that state. This leaves a whole host of web development needs unaccounted for, including:
- routing for pages and page layouts across your site
- styling those interfaces with CSS
- creating backend servers and/or serverless functions to persist data
...and so on. Sure, some developers prefer to cobble together different libraries and frameworks to fill in these gaps (the MERN stack was the go-to back in the 2010s). But others would prefer an all-in-one solution to make some or all of these decisions for you.
Enter meta-frameworks. You may have heard names like Next.js, Nuxt, and Angular come to dominate this category. Each of these address common concerns like routing, layouts, serverless backends, and CSS bundling with out-of-the-box solutions.
So, with all these options... which meta-framework do we start with?
TL;DR
So, you want a quick answer on which meta-framework to choose. Here’s my watered-down snapshot of the meta-framework buffet:
- If you want the all-rounder pick with a huge user base: pick Next.js.
- If you're building a content-focused site, use Astro.
- If you're coming from react-router or a different backend language, use Remix.
- If you don't like React, try Nuxt and SvelteKit.
- If you think
useEffect()
is confusing, but you do like JSX, try SolidStart.
☝️ And if you want to know the “why” behind these answers, read on!
Next.js is dominating the space
If this is a popularity contest, Next.js is the runaway pageant queen. Its npm installation numbers have exploded in recent years. Backed by the venture-funded hosting platform Vercel, Next.js has the resources to crank up these numbers even further 📈
Source: NPM Trends https://npmtrends.com/next.
This isn't too surprising, reviewing React's history. Next.js was among the first meta-frameworks built around the tool, with some clear innovations early on:
- Every file you create is a "route" on your website. No need for MVC patterns or hand-rolled react-router configs.
- Every page can fetch server-side data. This makes the distance from database to UI feel shorter.
- All pages are server-rendered. This populates each page with content before React mounts to appease the Google search gods.
Since then, Next.js has further closed the gap between backend and frontend. By including JS-based API routes in your project, you can whip up serverless functions to handle user requests and fetch from a database, no infra team needed. As you might imagine, the Vercel hosting platform makes Next.js deployment simple as well.
So should you use it? If you're sold on full-stack JavaScript, Next.js' broad usage means expansive documentation and community libraries.
Still, Next.js shines best on moderately complex web apps. Its blend of frontend heft with backend power makes Next.js too complex for static blogs or documentation states, yet not complex enough for client-heavy dashboards. E-commerce is the sweet spot worth using as an anchor.
Visit the Next.js docs to get started 🚀
Old vs. new Next.js
"I miss the old Next.js. That pages/about
Next.js."
There's a reason Next.js' package description is simply "The React Framework." It’s the closest project to the React core team, with Vercel hiring Sebastian Markbage, among others, to "support the future of React."
This made Next.js the right proving ground for React's future: React on the server or React Server Components. This lets developers use React as a server-templating language and embed interactive components with just JavaScript™ imports.
Though exciting, server components come with entirely new routing and caching systems. This divides Next.js' previous API, the Pages Router, from their current API, the App Router. As of 2024, the App Router is still proving new full-stack concepts like server actions and form state handling. The primitives are there, but the patterns and best practices are lacking.
This makes your choice of flavor pretty simple:
- If you're new to React and need a stable foundation, stick with the Pages Router.
- If you're an experienced React developer ready to learn new patterns, try the App Router.
Extended learning
You may have found that you can't really learn React server components without learning Next.js. If you aren't afraid to get your hands dirty, this "RSCs from scratch" guide explains how to scaffold your own server without a framework!
Next.js vs. the Vite meta-framework explosion
Up until 2018, there were relatively few JavaScript meta-frameworks to choose from. This wasn't from a lack of ideas. Really, it was the complexity of building a JS meta-framework that held innovation back.
That all changed when the Vite nation attacked (yes, Avatar reference). Though not a featured "meta-framework" like Next.js, Vite underpins new meta-frameworks like Astro, Remix, and SvelteKit.
So, what is Vite? Vite is a website bundler for your JavaScript, CSS, static assets... anything you use for a website. I'll quote my first article on Vite to break this down:
Remember Apple’s original value proposition for the iPhone?
“An iPod, a phone, an Internet communicator…”? I see Vite as a similar proposition, as it bundles three related tools into one:
- A JavaScript bundler: webpack, Rollup, etc
- A dev server: Express, Browsersync, etc.
- An asset manager for styles, images, and more via Sass and Gulp or Grunt
Source article on the LogRocket Blog
☝️ That "dev server" piece is the biggest departure from tools like Webpack and Rollup. By tapping into your browser, Vite can smartly wait for you to visit a route (say, your /about
page) and transform resources that page requests on-the-fly. This means only building what you see, cutting 30-second Webpack refreshes to 100ms hot reloading.
By handling development and production flows, Vite became the toolkit to build new meta-frameworks. This came with good news and bad news.
The good news: there are more JavaScript frameworks than ever!
Bad news: there are more JavaScript frameworks than ever 😓
Let's explore the best frameworks Vite has to offer.
Remix is the framework for app developers
Next.js may be the React Framework, but there is the other React framework: Remix. This meta-framework is built by the dynamic duo behind react-router, one of the first (and most popular) solutions to routing in React. Building this library gave Ryan and Michael a deep perspective on React for dynamic apps.
Their homepage shows the killer use case for Remix: dashboards. Its nested routing system inspired Next.js' own App Router and offers powerful levers for parallel data fetching.
Example from Remix's nested routing explainer.
By focusing on server-driven apps, Remix also leans heavily on the web platform:
- cache headers to keep requests cheap and fast
- form handlers to embrace form actions over complex client form libraries
- Request and Response objects to interact with server endpoints
The freedom to use the MDN docs instead of a Stack Overflow post on Next.js internals makes Remix a great choice for backend-focused developers across languages. It's also the framework of choice for React educator Kent C Dodds, who praises Remix for teaching transferrable skills.
Remix is the create-react-app migration path
Remix has had a target demographic in mind since day 1: existing react-router users. Chances are, your old create-react-app is using react-router for every client-side request. With this router’s complexity, migrating to a server-rendered, MDN-doc-driven site is no easy task.
Remix has taken strides in 2024 to shrink the gap. SPA mode lets you port your client-side apps to Remix's data-fetching upgrades and a modern JavaScript bundler (Vite). Then, when the need arises, you can flip on server rendering across your application.
Follow the Getting Started guide to try yourself 🚀
Astro is the framework for content sites
Astro is a meta-framework that takes flexibility to the extreme. At first glance, Astro has a limited scope: content-rich websites.
Astro is easily the best solution in this class, offering bespoke solutions for rendering and managing content. Its MDX and Markdoc integrations combine Markdown with client interactivity using any tool you choose: React, Vue, Svelte, Solid, plain web components, etc.
Content often includes metadata as well. Say, a list of post authors, an image banner with built-in optimization, or a generated URL slug. Astro covers all of these use cases and more with Content Collections. This tool brings "type-safe frontmatter" to your Markdown, letting you define a shared schema across related entries and even model relationships between entries. It's the closest you've seen to a database that lives in a .md
file.
As for documentation sites, Astro offers a dedicated theme called Starlight. We could walk through the feature set and its fraction of a carbon footprint compared to Docusaurus, but this quote from Rachel Nabors says it best:
The Astro team has EVOLVED how docs can be done, and you can get it all out of the box with Starlight.
From here, Astro is broadening its use cases to server-driven applications. Astro offers similar selling points to Remix, relying on web-standard Request and Response objects and even web-standard view transitions for client routing. Astro is also uniquely flexible to any component library, offering plug-and-play with React, Vue, Svelte, and more.
This example shows a bare index.astro
route that mixes server templating with client components:
---
// static text with zero clientside JS
import HeroBanner from '../components/HeroBanner.astro'
// dynamic nav bar written in Vue
import NavBar from '../components/NavBar.vue'
// dynamic image carousel from a helper package
// Might be React, Vue, Svelte, etc
import ImageCarousel from 'fancy-image-carousel-package'
---
<html lang="en">
...
<Hero />
<!--ship JavaScript for screen sizes 600px and below-->
<NavBar client:media="(max-width: 600px)" />
<!--ship JavaScript when the carousel scrolls into view-->
<ImageCarousel client:visible />
...
</html>
Visit astro.new to try yourself 🚀
Nuxt 3 takes code generation to the extreme
Nuxt was the first "Next.js but for X" to hit the scene. It started with a simple goal: match the server rendering advantage of Next.js, but using Vue components instead of React.
Since then, Nuxt has found a few unique benefits over Next that the Vite bundler help make possible:
- All project components and layouts are global. This means all your
.vue
snippets are available in your routes without import statements. - Fetch requests have superpowers. Nuxt supplies data helpers like
useFetch
to manage transforming JSON responses, auto-wiring refresh buttons, managing error states, and more.
Try in the online playground 🚀
React vs. Vue
There are many nuances to choosing the right component framework, so I encourage you to try both before picking a side. Astro is an excellent stomping ground for playing with each!
Still, to give an imperfect-anecdotal overview: React suits those with backend programming or JS-heavy backgrounds, while Vue suits backgrounds in HTML and CSS, design, or old-school JS libraries like Angular 1.x. If you want to fight me on this, my Twitter handle is @bholmesdev.
SvelteKit enhances web apps
SvelteKit is another Vite-powered meta-framework worth trying out, this time trading React components for Svelte.
SvelteKit brings some major advantages over Next:
- Bundles are much smaller on average. Even with SvelteKit's comparable feature set, a SvelteKit app tends to undercut Next.js by a wide margin. This comes down to Svelte's diminutive size per-component compared to React. I recommend Rich Harris' "Rethinking Reactivity" talk to understand the benefits here.
- Deployment is simplified with adapters. This lets you install a helper for your favorite hosting platform (Vercel, Netlify, etc.) and hit "deploy," with no added config necessary. This model has inspired players like Astro and Remix as well.
There are also the advantages of Svelte itself over React, including built-in solutions to scoped styling and page transitions or animations.
Check out Prismic’s Svelte and SvelteKit Guide to learn more 📚
React vs. Svelte
Just take "React vs. Vue" and replace Vue with Svelte 😉
Solid Start offers a solid start
Solid Start is yet another Vite-powered meta-framework, now trading React components for SolidJS. This project is pre-1.0 as of 2024, so I won't dig into the feature-set too deeply. The short version: SolidJS feels like React, without the infinite loops or bloated bundle sizes. They are also borrowing RSC conventions like server actions to close the language barrier. If this sounds exciting, try the beta!
React vs. SolidJS
React and SolidJS are pretty similar in their intended audiences since both are component-based frameworks written in JSX. The real SolidJS benefits come from a) performance gains, and b) a simpler mental model for state management. I recommend Solid's own framework comparison guide for more.
Stay on Top of New Tools, Frameworks, and More
Research shows that we learn better by doing. Dive into a monthly tutorial with the Optimized Dev Newsletter that helps you decide which new web dev tools are worth adding to your stack.
Conclusions
We've covered a lot of ground in the meta-framework space. I hope you take away some major themes:
- The web platform is getting good. This is making meta-frameworks faster, simpler, and increasingly similar to each other with common tooling like Vite.
- Next.js is king, but others are filling the gaps. Astro found a gap in content-heavy sites, and Remix found a gap for existing react-router users. I expect more use cases to be filled from here.
- We're going back to the server. Remix and Next.js are showing how powerful our apps can be if we trade static site generation for cache-laden servers. With the concept of "adapters" that SvelteKit introduced, deployment to these servers and serverless functions has never been easier.
So, what do I pick?
I won't pretend there's a "silver bullet" in the meta-framework space that'll suit everyone's needs. So, I encourage you to bookmark that TL;DR we kicked off with for a snapshot of the options that I’m comfortable recommending.
That said, if you're a weekend hacker who sat through this massive blog post, try all of them before deciding 🙃