Skip to main content
Back to Blog
Comparisons
3 min read
March 21, 2026

Remix vs Next.js: Full-Stack React Frameworks Compared

Remix focuses on web standards and progressive enhancement. Next.js focuses on React-first full-stack development. Compare their approaches to routing, data, and forms.

Ryel Banfield

Founder & Lead Developer

Both Remix and Next.js are full-stack React frameworks. Next.js has the adoption lead. Remix has loyal advocates who prefer its web-standards approach. Understanding the architectural differences helps you choose.

Philosophy

Next.js: React-first. Extends React with server rendering, routing, and data fetching. Server Components, server actions, and streaming are core to the architecture.

Remix: Web-standards-first. Uses the web platform (Request/Response, FormData, HTTP caching) as the foundation. Progressive enhancement means forms work without JavaScript.

Data Loading

Next.js (App Router)

// app/posts/page.tsx (Server Component)
export default async function PostsPage() {
  const posts = await db.post.findMany() // runs on server
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

Data fetching happens directly in Server Components. No special API. Just async/await.

Remix

// app/routes/posts.tsx
export async function loader() {
  const posts = await db.post.findMany()
  return json(posts)
}

export default function PostsPage() {
  const posts = useLoaderData<typeof loader>()
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

Data loading is explicit via loader functions. Data is passed to components via useLoaderData.

Form Handling

Next.js Server Actions

// app/posts/new/page.tsx
async function createPost(formData: FormData) {
  'use server'
  await db.post.create({
    data: {
      title: formData.get('title') as string,
      content: formData.get('content') as string,
    },
  })
  redirect('/posts')
}

export default function NewPost() {
  return (
    <form action={createPost}>
      <input name="title" />
      <textarea name="content" />
      <button type="submit">Create</button>
    </form>
  )
}

Remix Actions

// app/routes/posts.new.tsx
export async function action({ request }: ActionFunctionArgs) {
  const formData = await request.formData()
  await db.post.create({
    data: {
      title: formData.get('title') as string,
      content: formData.get('content') as string,
    },
  })
  return redirect('/posts')
}

export default function NewPost() {
  return (
    <Form method="post">
      <input name="title" />
      <textarea name="content" />
      <button type="submit">Create</button>
    </Form>
  )
}

Both approaches use progressive enhancement (forms work without JS). Remix's action pattern is more explicit about the Request/Response cycle.

Routing

Next.js

  • File-based routing in app/ directory
  • Folders = route segments
  • page.tsx, layout.tsx, loading.tsx, error.tsx conventions
  • Parallel routes (@modal)
  • Intercepting routes ((.)photo/[id])
  • Route groups ((marketing), (app))

Remix

  • File-based routing in app/routes/
  • Flat file routing (posts._index.tsx, posts.$id.tsx)
  • Nested routing with <Outlet />
  • URL-based nested layouts
  • Resource routes for non-UI endpoints

Both support nested layouts and dynamic routes. Next.js has more routing features (parallel routes, intercepting routes).

Feature Comparison

FeatureNext.jsRemix
Server ComponentsYes (default)No (loaders instead)
StreamingYes (Suspense)Yes
Static generationYes (SSG, ISR)Limited
Image optimizationnext/image (built-in)Manual or third-party
MiddlewareYesCustom server
Edge renderingYes (edge runtime)Yes (adapters)
Error boundariesError.tsx conventionErrorBoundary export
Optimistic UIuseOptimistic hookuseFetcher
PrefetchingLink componentLink prefetch attribute
DeploymentVercel-optimized, any Node hostAny Node host, Cloudflare, Deno

Ecosystem and Adoption

MetricNext.jsRemix
npm weekly downloads7M+400K+
GitHub stars130K+30K+
Companies usingVercel, Netflix, TikTok, NotionShopify, NASA, Sentry
Job postings15,000+500+
Community sizeVery largeGrowing
BackingVercelShopify

Next.js has 15-20x the adoption of Remix.

Performance

For equivalent applications:

MetricNext.jsRemix
FCP0.6-1.2s0.6-1.0s
TTI1.0-2.0s0.8-1.5s
JS bundle (typical)80-150 KB60-100 KB
Waterfall requestsMinimal (Server Components)Minimal (parallel loaders)

Remix tends to ship slightly less JavaScript because it does not ship a Server Components runtime. The difference is small in practice.

When to Choose Next.js

  1. Server Components are important for your architecture
  2. Static generation (blogs, marketing sites, docs)
  3. Vercel deployment (optimized experience)
  4. Larger ecosystem (more libraries, tutorials, examples)
  5. Image optimization is critical
  6. Hiring (more developers know Next.js)

When to Choose Remix

  1. Progressive enhancement is a requirement (form submissions without JS)
  2. Web standards approach appeals to your team
  3. Cloudflare Workers deployment (better Remix adapter)
  4. Data-heavy applications (nested loaders parallelize data fetching)
  5. Smaller bundle size matters
  6. Shopify ecosystem (Remix is Shopify's recommended framework)

Our Choice

We use Next.js for all client projects. The Server Components architecture, ecosystem size, image optimization, and Vercel deployment give us the best foundation for shipping production applications. Remix is a well-designed framework, and we respect its web-standards approach, but Next.js's practical advantages make it our default.

Contact us to build your application with Next.js.

RemixNext.jsReactframeworkcomparison

Ready to Start Your Project?

RCB Software builds world-class websites and applications for businesses worldwide.

Get in Touch

Related Articles