Next.js vs Remix Boilerplate 2026: Data Loading, Layouts, and Deploy Targets
The Framework Fork You Can't Undo
Picking a boilerplate locks you into far more than a component library. It locks you into a data fetching model, a mental model for routing, and a deployment target that shapes your infrastructure costs for years.
Next.js and Remix both run React. Both support server rendering. Both have mature boilerplate ecosystems with polished starter kits. They solve the same problem — building full-stack web apps with React — but they solve it in fundamentally different ways.
Next.js chose React Server Components and a cache-first architecture. Remix chose a loader/action model built on web standards (Request, Response, FormData). These decisions cascade through every architectural choice you make after day one.
This comparison focuses on what matters for boilerplate selection: data loading patterns, nested layout handling, deploy targets, and the available starter ecosystem for each framework.
TL;DR
Next.js boilerplates (Shipfast, Supastarter, Makerkit, T3 Stack) benefit from the richest commercial SaaS starter ecosystem in any framework. The App Router's React Server Components enable per-component data fetching without prop drilling, and Vercel's deployment platform gives you ISR, edge functions, and CDN caching with zero configuration. Choose Next.js if you want the widest choice of commercial starters, the most mature ecosystem, and tight Vercel integration.
Remix boilerplates (Epic Stack, Remix SaaS, remix-indie-stack) use a loader/action model that eliminates most data waterfall problems by co-locating route data requirements. Remix runs on Fly.io, Cloudflare Workers, and any Node.js environment equally well. Choose Remix if you value predictable data loading, progressive enhancement, and flexibility to deploy anywhere without a Vercel dependency.
Key Takeaways
- Remix loaders eliminate request waterfalls by design. Every nested route declares its own loader that runs in parallel. A page with five nested routes fetches all data concurrently — no component waiting for a parent's data before fetching its own.
- Next.js has 10x more commercial SaaS starters. Shipfast, Supastarter, Makerkit, Bedrock, Next SaaS Starter, SaaSBold, and dozens more are purpose-built for Next.js. The Remix commercial ecosystem is significantly smaller.
- The Epic Stack is the definitive Remix boilerplate. Kent C. Dodds' Epic Stack is the Remix community's agreed-on gold standard: SQLite/Turso, Fly.io, full-stack TypeScript, Playwright testing, and first-class progressive enhancement.
- Next.js App Router layouts are file-system-based.
layout.tsxat any directory level wraps all routes beneath it. Remix outlets are data-aware — parent routes can pass data to child routes through theuseLoaderDatapattern. - Deploy targets diverge meaningfully. Next.js is Vercel-optimized (ISR, edge middleware, image optimization). Remix targets multi-region deployments on Fly.io and edge runtimes on Cloudflare Workers — running closer to the user without a proprietary CDN layer.
- Caching models are opposite. Next.js defaults to aggressive caching (ISR, RSC cache,
cache()function). Remix defaults to no caching — pages are fresh on every request unless you explicitly add cache headers.
The Contenders
Next.js App Router Boilerplates
The Next.js boilerplate ecosystem in 2026 is the largest in any framework:
- Shipfast ($199) — lean monolith, NextAuth, Stripe, Resend, landing page, MDX blog. Target: solo founders.
- Supastarter ($299+) — Turborepo monorepo, better-auth, 5 payment providers, multi-tenancy, i18n, admin panel. Target: B2B SaaS teams.
- Makerkit ($149+) — multi-tenancy, Supabase, Stripe, clean architecture. Target: developers who want structure.
- T3 Stack (free) — tRPC, Prisma, NextAuth, Tailwind. Zero business logic, maximum type safety.
- Next SaaS Starter (free, shadcn) — shadcn/ui, Drizzle, Stripe, Postgres. Official-adjacent starter template.
All Next.js boilerplates run on Vercel with full feature support, including ISR, edge middleware, and server actions.
Remix Boilerplates
The Remix ecosystem is smaller but tightly curated:
- Epic Stack (free, Kent C. Dodds) — SQLite/Turso, Fly.io, full-stack TypeScript, Playwright, MSW, Cookie-based auth. The community gold standard.
- Remix SaaS (free, Luigi Minardi) — Supabase, Stripe, shadcn/ui, Fly.io, transactional email. Closest Remix equivalent to Shipfast.
- remix-indie-stack (free, Remix official) — SQLite, Fly.io, Tailwind, basic auth. Minimal starting point.
No Remix boilerplate has reached Shipfast-scale commercial polish. The Epic Stack is the most complete, but it remains community-maintained, not a commercial product.
Data Loading Patterns
This is the deepest architectural difference between the two frameworks.
Next.js: React Server Components + fetch
The App Router uses React Server Components (RSC) to fetch data at the component level:
// app/dashboard/page.tsx — Server Component
async function DashboardPage() {
const [user, projects, notifications] = await Promise.all([
getUser(),
getProjects(),
getNotifications(),
]);
return (
<DashboardLayout>
<UserCard user={user} />
<ProjectList projects={projects} />
<NotificationFeed notifications={notifications} />
</DashboardLayout>
);
}
Data fetching is co-located with components. Using Promise.all prevents waterfalls. The cache() function deduplicates identical requests across the render tree.
The challenge: if a child component needs data that a parent didn't fetch in parallel, you get a waterfall:
// Waterfall risk with nested server components
async function ParentComponent() {
const user = await getUser(); // first fetch
return <ChildComponent userId={user.id} />; // second fetch blocked by first
}
async function ChildComponent({ userId }: { userId: string }) {
const projects = await getProjects(userId); // blocked by parent
return <ProjectList projects={projects} />;
}
Next.js 15 addresses this with Suspense boundaries and parallel data fetching patterns, but it requires explicit discipline to avoid.
Remix: Loader/Action Model
Remix attaches a loader function to every route. Before rendering any part of the route tree, Remix fetches all matching loaders in parallel:
// routes/dashboard.tsx — root loader
export async function loader({ request }: LoaderFunctionArgs) {
const user = await getUser(request);
return json({ user });
}
// routes/dashboard.projects.tsx — nested loader
export async function loader({ request }: LoaderFunctionArgs) {
const projects = await getProjects(request);
return json({ projects });
}
// routes/dashboard.notifications.tsx — nested loader
export async function loader({ request }: LoaderFunctionArgs) {
const notifications = await getNotifications(request);
return json({ notifications });
}
All three loaders run concurrently. By the time the components render, all data is available. There is no waterfall risk — the route tree's data requirements are fully declared before rendering begins.
Benchmarks from Remix documentation show that parallel loaders can reduce total data fetch time by 40–60% compared to sequential component-level fetching in complex nested route trees.
Action Handling
Remix uses form actions as the primary mutation primitive:
// routes/projects.new.tsx
export async function action({ request }: ActionFunctionArgs) {
const formData = await request.formData();
const name = formData.get("name") as string;
const project = await createProject({ name });
return redirect(`/projects/${project.id}`);
}
export default function NewProject() {
return (
<Form method="post">
<input name="name" />
<button type="submit">Create</button>
</Form>
);
}
The action + loader pattern creates a request/response cycle that works without JavaScript (progressive enhancement). Next.js Server Actions provide similar functionality, but the Remix pattern is more explicit about the request lifecycle.
Nested Layouts
Next.js: File-System Layouts
App Router layouts are defined by layout.tsx files at any directory level:
app/
├── layout.tsx # Root layout (html, body)
├── (marketing)/
│ ├── layout.tsx # Marketing layout (nav, footer)
│ └── page.tsx
├── (dashboard)/
│ ├── layout.tsx # Dashboard layout (sidebar, header)
│ ├── page.tsx
│ └── projects/
│ ├── layout.tsx # Projects layout (breadcrumb)
│ └── page.tsx
Layouts at each level wrap all nested routes. They persist across navigation — a sidebar component defined in (dashboard)/layout.tsx keeps its state when navigating between dashboard pages.
Limitation: Next.js layouts cannot access route-level loader data. If your layout needs to render user information, it fetches it independently from child page data. There is no built-in mechanism to pass loader results from a layout to nested pages.
Remix: Outlet-Based Nesting
Remix routes nest via <Outlet /> components:
// routes/dashboard.tsx — renders the shell
export default function Dashboard() {
const { user } = useLoaderData<typeof loader>();
return (
<div className="dashboard">
<Sidebar user={user} />
<main>
<Outlet />
</main>
</div>
);
}
The parent route's loader data is available to the parent layout component. Child route data is available to child components. This creates a clear data ownership boundary — the sidebar knows about the user (from the parent loader), and the projects list knows about projects (from the child loader).
Key advantage: Remix's nested outlets make it easier to reason about which component owns which data. There is no ambiguity about whether a component's data is fresh or cached.
Deploy Targets
Next.js: Vercel-First, Adapters Available
Next.js is developed by Vercel. Its advanced features have deep Vercel platform integration:
- ISR (Incremental Static Regeneration) — re-generates pages in the background at intervals
- Edge Middleware — runs at Vercel's edge network, before the origin
- Image Optimization — automatic WebP/AVIF conversion, resizing, lazy loading
- Partial Prerendering — static shell with dynamic holes (experimental)
All of these features work out of the box on Vercel. Running Next.js on other platforms (AWS, GCP, Fly.io) requires adapters and loses some features: image optimization requires a custom image service, and ISR behavior depends on the adapter.
For most SaaS boilerplates, this is fine — Vercel's free tier and $20/month Pro plan cover most indie and small business workloads.
Remix: Platform-Agnostic by Design
Remix was built with a specific philosophy: run on standard web server APIs (Request/Response), not framework-specific adapters.
Remix has first-class support for:
- Fly.io — recommended for Epic Stack deployments, multi-region out of the box
- Cloudflare Workers — edge deployment, minimal cold starts, global distribution
- AWS Lambda — serverless functions
- Express — traditional Node.js server
- Vercel — supported, but not optimized like Next.js
The Epic Stack deploys to Fly.io by default, with multi-region SQLite via LiteFS/Turso. A database replica runs in each Fly.io region — reads hit the nearest replica, writes route to the primary. This architecture gives sub-100ms database reads globally without a connection pooler.
| Deploy Target | Next.js | Remix |
|---|---|---|
| Vercel | First-class | Supported |
| Cloudflare Workers | Limited | First-class |
| Fly.io | Supported | First-class (Epic Stack) |
| AWS Lambda | Via adapter | Via adapter |
| Node.js server | Via adapter | First-class |
| ISR | Yes (Vercel-native) | Manual cache headers |
Head-to-Head Comparison
| Feature | Next.js Boilerplates | Remix Boilerplates |
|---|---|---|
| Commercial starters available | 10+ (Shipfast, Supastarter, Makerkit…) | 1-2 (limited) |
| Best free starter | T3 Stack, Next SaaS Starter | Epic Stack |
| Data loading model | RSC + fetch + cache() | Route loaders (parallel) |
| Waterfall risk | Moderate (requires discipline) | Low (structural prevention) |
| Nested layout data | Independent per-layer | Shared via useLoaderData |
| Caching default | Aggressive (ISR, RSC cache) | None (fresh on every request) |
| Mutation model | Server Actions | Forms + Actions |
| Progressive enhancement | Partial (Server Actions) | First-class (Forms) |
| Primary deploy target | Vercel | Fly.io / Cloudflare |
| Multi-region database | Via Neon / PlanetScale | Turso/LiteFS on Fly.io |
| Auth ecosystem | NextAuth (mature) | Remix Auth (smaller) |
| Testing defaults | Variable (Jest or Vitest) | Playwright + Vitest (Epic Stack) |
| TypeScript strictness | Varies by starter | Strict (Epic Stack default) |
Which Should You Choose?
Choose Next.js If:
- You want a commercial SaaS boilerplate. Shipfast, Supastarter, and Makerkit are years ahead of anything available for Remix. If you want auth + billing + email + admin panel in a single purchase, Next.js is the only realistic choice.
- You are deploying to Vercel. If Vercel's platform features (ISR, image optimization, analytics, edge functions) are important to your product, Next.js is the only framework that uses them natively.
- Your team knows Next.js. The hiring market, tutorials, documentation, and Stack Overflow coverage for Next.js dwarfs Remix. Learning costs matter.
- You need a large component ecosystem. shadcn/ui, Radix, Chakra UI, and most SaaS UI kits document their Next.js integration first.
Choose Remix If:
- You want structural waterfall prevention. Remix's loader model makes it architecturally harder to accidentally create sequential data fetches. For complex, data-heavy dashboards, this matters.
- You need to deploy to Cloudflare Workers or Fly.io. Remix's platform-agnostic design is a real advantage if your deployment requirements go beyond Vercel.
- Progressive enhancement matters. If your users are on unreliable networks or you value forms that work without JavaScript, Remix's form-first model is genuinely better.
- You want the Epic Stack's testing rigor. Playwright, MSW, Vitest, TypeScript strict mode, and Docker-based local dev are defaults in the Epic Stack — a standard most Next.js boilerplates don't match.
The Bottom Line
Next.js wins on ecosystem depth. If you are picking a foundation for a SaaS product and want commercial starter support, auth libraries, UI component integrations, and Vercel's deployment platform, Next.js is the default choice in 2026. See our T3 Stack vs Next.js SaaS Starters comparison for a deep dive into the most popular Next.js foundation options.
Remix wins on architectural clarity. The loader/action model produces fewer waterfall bugs, the outlet-based nesting makes data ownership explicit, and the platform-agnostic runtime gives you genuine deployment flexibility. The best Remix boilerplates have matured significantly — the Epic Stack remains the strongest free full-stack starter in either ecosystem.
Most developers building their first SaaS should start with Next.js — the starter ecosystem support is too important to sacrifice. Teams building their second or third product, who have been burned by Next.js data fetching complexity, often find Remix's predictability worth the ecosystem trade-off.
For UI component decisions that affect both frameworks, see our shadcn/ui vs Chakra UI comparison to understand which component library fits your team's workflow best.
Methodology & Sources
- Remix loader concurrency model: remix.run/docs/en/main/route/loader
- Next.js App Router data fetching patterns: nextjs.org/docs/app/building-your-application/data-fetching
- Epic Stack repository: github.com/epicweb-dev/epic-stack
- Remix SaaS repository: github.com/dev-xo/remix-saas
- Waterfall reduction figures: derived from Remix documentation examples comparing sequential vs parallel loader execution in nested route trees
Check out this boilerplate
View Next.json StarterPick →