gatsby, hexo, next, nuxt, and sapper are frameworks designed to build web applications with a focus on performance, SEO, and content delivery. next and nuxt are full-stack frameworks for React and Vue respectively, offering server-side rendering (SSR) and static site generation (SSG). gatsby is a React-based static site generator known for its GraphQL data layer. hexo is a fast, simple static site generator primarily used for blogging. sapper is the predecessor to SvelteKit, designed for Svelte applications with SSR and SSG capabilities, though it is now in maintenance mode.
These five tools solve similar problems — building fast, SEO-friendly websites — but they take very different approaches depending on your framework preference and project needs. next and nuxt are full-stack frameworks for React and Vue. gatsby is a static site generator for React. hexo is a lightweight static generator for blogs. sapper is the legacy framework for Svelte. Let's look at how they handle real engineering tasks.
next uses the file system to define routes. In the modern App Router, folders represent segments.
// next: app/page.js
export default function Page() {
return <h1>Home</h1>;
}
// app/about/page.js maps to /about
nuxt also uses file-based routing but auto-imports components.
<!-- nuxt: pages/index.vue -->
<template>
<div>Home</div>
</template>
<!-- pages/about.vue maps to /about -->
gatsby creates pages programmatically or via the file system in src/pages.
// gatsby: src/pages/index.js
import React from "react"
export default function Home() {
return <div>Home</div>
}
hexo generates static HTML based on posts and pages, usually without complex routing logic.
# hexo: _config.yml
permalink: :year/:month/:day/:title/
# Routes are derived from post front-matter
sapper uses a routes folder where .svelte files become routes.
<!-- sapper: routes/index.svelte -->
<h1>Home</h1>
<!-- routes/about.svelte maps to /about -->
next uses server components or fetch inside async components in the App Router.
// next: app/page.js
async function getData() {
const res = await fetch('https://api.example.com/data')
return res.json()
}
export default async function Page() {
const data = await getData()
return <main>{data.title}</main>
}
nuxt provides useFetch or useAsyncData composables.
<!-- nuxt: pages/index.vue -->
<script setup>
const { data } = await useFetch('/api/data')
</script>
<template>
<div>{{ data.title }}</div>
</template>
gatsby relies heavily on GraphQL queries at build time for static data.
// gatsby: src/pages/index.js
import { graphql } from "gatsby"
export const query = graphql`{ site { title } }`
export default function Home({ data }) {
return <div>{data.site.title}</div>
}
hexo loads data from markdown front-matter or config files during generation.
# hexo: source/_posts/hello.md
---
title: Hello World
date: 2023-01-01
---
Content here
sapper uses a preload function or load in newer versions to fetch data.
<!-- sapper: routes/index.svelte -->
<script context="module">
export async function preload() {
const res = await this.fetch('/api/data');
return { data: await res.json() };
}
</script>
next supports Static Site Generation (SSG), Server-Side Rendering (SSR), and Client-Side Rendering (CSR) per route.
// next: Force SSR
export const dynamic = 'force-dynamic'
// Or Static
export const dynamic = 'force-static'
nuxt allows hybrid rendering with Nitro engine, mixing static and server routes.
// nuxt: nuxt.config.ts
export default defineNuxtConfig({
nitro: { prerender: { routes: ['/'] } }
})
gatsby is primarily Static Site Generation, though DSG (Deferred Static Generation) exists.
// gatsby: gatsby-node.js
exports.createPages = async ({ actions }) => {
actions.createPage({ path: "/", component: resolve(`./src/pages/index.js`) })
}
hexo is purely Static Site Generation. All HTML is built before deployment.
# hexo: Command line
clean && generate && deploy
# No server-side logic at runtime
sapper supports SSR and SSG (via sapper export).
# sapper: Package.json
"scripts": {
"export": "sapper export"
}
# Creates a static version of the SSR app
next uses next.config.js for build settings.
// next: next.config.js
module.exports = {
images: { domains: ['example.com'] }
}
nuxt uses nuxt.config.ts for a typed configuration experience.
// nuxt: nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/content']
})
gatsby uses gatsby-config.js for plugins and site metadata.
// gatsby: gatsby-config.js
module.exports = {
plugins: [`gatsby-plugin-image`]
}
hexo uses _config.yml for theme and site settings.
# hexo: _config.yml
theme: landscape
deploy:
type: git
sapper uses sapper.config.js for build customization.
// sapper: sapper.config.js
export default {
serviceworker: { enabled: true }
}
next, nuxt, and gatsby are actively maintained with frequent releases.
hexo is stable and maintained, suitable for its niche.
sapper is in maintenance mode. The team recommends moving to SvelteKit.
# sapper: Warning on npm install
# npm WARN deprecated sapper@0.29.3: Please migrate to SvelteKit
Despite different frameworks, they share core goals.
All five generate HTML on the server or at build time for crawlers.
<!-- All output standard HTML -->
<h1>Page Title</h1>
<meta name="description" content="..." />
All focus on speed via code splitting and asset optimization.
// next: next/image
// nuxt: nuxt/image
// gatsby: gatsby-image
// All optimize images automatically
Most use the file system to define URLs, reducing boilerplate.
// next, nuxt, gatsby, sapper
/pages/about.js -> /about
| Feature | next | nuxt | gatsby | hexo | sapper |
|---|---|---|---|---|---|
| Framework | React | Vue | React | None (JS) | Svelte |
| Rendering | Hybrid | Hybrid | Static | Static | SSR/Static |
| Data Layer | Fetch/GraphQL | Composables | GraphQL | Front-matter | Fetch |
| Status | Active | Active | Active | Active | Maintenance |
| Best For | Web Apps | Web Apps | Content Sites | Blogs | Legacy Svelte |
next and nuxt are your go-to choices for modern web applications requiring dynamic features and scalability. They handle the heavy lifting of server configuration and rendering strategies.
gatsby remains a strong contender for content sites where the GraphQL data layer simplifies pulling from multiple sources, though build times can be a trade-off.
hexo is the pragmatic choice for simple blogs where you just want to write markdown and deploy without managing a complex build pipeline.
sapper should be avoided for new work. If you love Svelte, use SvelteKit. If you are stuck on sapper, plan a migration path.
Final Thought: Match the tool to your team's framework expertise and the site's complexity. Don't over-engineer a blog with a full-stack app framework, and don't under-engineer a dashboard with a static generator.
Choose next if you need a flexible React framework that supports both static generation and server-side rendering with minimal setup. It is the industry standard for production React apps, offering robust features like API routes, image optimization, and a strong ecosystem. It fits well for e-commerce, dashboards, and large-scale web applications.
Choose nuxt if your team prefers Vue.js and needs a framework that handles server-side rendering and static generation out of the box. It provides a modular architecture with auto-imports and a powerful state management story. It is excellent for content sites, e-commerce, and apps that require the reactivity of Vue with the SEO benefits of SSR.
Choose gatsby if you are building a content-heavy site like a marketing page or documentation portal that benefits from a unified GraphQL data layer. It is ideal when you need to pull data from multiple sources (CMS, APIs, files) and want a rich plugin ecosystem for image optimization and SEO. However, be aware that build times can grow significantly as the site scales.
Choose hexo if your primary goal is to launch a personal blog or simple documentation site with minimal configuration. It is lightweight and fast, making it perfect for writers who want to focus on content rather than complex application logic. It is not suitable for dynamic web applications requiring user authentication or complex state management.
Do NOT choose sapper for new projects as it is in maintenance mode and superseded by SvelteKit. If you are maintaining a legacy Svelte application built with sapper, continue using it until migration is feasible. For any new Svelte project, evaluate SvelteKit instead for active support and modern features.
Used by some of the world's largest companies, Next.js enables you to create full-stack web applications by extending the latest React features, and integrating powerful Rust-based JavaScript tooling for the fastest builds.
Visit https://nextjs.org/docs to view the full documentation.
The Next.js community can be found on GitHub Discussions where you can ask questions, voice ideas, and share your projects with other people.
To chat with other community members you can join the Next.js Discord server.
Do note that our Code of Conduct applies to all Next.js community channels. Users are highly encouraged to read and adhere to it to avoid repercussions.
Contributions to Next.js are welcome and highly appreciated. However, before you jump right into it, we would like you to review our Contribution Guidelines to make sure you have a smooth experience contributing to Next.js.
We have a list of good first issues that contain bugs that have a relatively limited scope. This is a great place for newcomers and beginners alike to get started, gain experience, and get familiar with our contribution process.
If you believe you have found a security vulnerability in Next.js, we encourage you to responsibly disclose this and NOT open a public issue.
To participate in our Open Source Software Bug Bounty program, please email responsible.disclosure@vercel.com. We will add you to the program and provide further instructions for submitting your report.