Remix SaaS vs Epic Stack 2026: Which to Choose
TL;DR
Epic Stack prioritizes production practices; Remix SaaS prioritizes features. Epic Stack (by Kent C. Dodds) ships with SQLite, comprehensive tests, and Fly.io deployment as an opinionated production template. Remix SaaS (community) ships with PostgreSQL, organizations, and shadcn/ui as a feature-complete starter. Both are free. Your choice depends on whether you value practices (Epic) or features (Remix SaaS) out of the box.
Head-to-Head
| Epic Stack | Remix SaaS | |
|---|---|---|
| Created by | Kent C. Dodds | Community |
| Database | SQLite + Drizzle | PostgreSQL + Prisma |
| Auth | Sessions + TOTP 2FA | Sessions + OAuth |
| Organizations | ❌ | ✅ |
| Testing | Full (Playwright + Vitest + MSW) | Basic |
| Resend + templates | Resend | |
| UI | Custom (no UI lib) | shadcn/ui + Tailwind |
| Deployment | Fly.io (multi-region) | Any Node.js host |
| Documentation | Good | Minimal |
| Maintenance | Active (K.C. Dodds) | Community |
Epic Stack: The Practices First Approach
Epic Stack's core philosophy: ship with the practices that matter before adding features.
// Epic Stack testing approach — every feature tested
// app/routes/settings+/profile.change-password.tsx
import { test, expect } from '@playwright/test';
test('can change password', async ({ page }) => {
const user = await db.insert(users).values({
email: `test-${Date.now()}@example.com`,
passwordHash: await hashPassword('oldpassword'),
}).returning().get();
await page.goto('/login');
await page.fill('[name=email]', user.email);
await page.fill('[name=password]', 'oldpassword');
await page.click('[type=submit]');
await page.goto('/settings/profile');
await page.click('text=Change Password');
await page.fill('[name=currentPassword]', 'oldpassword');
await page.fill('[name=newPassword]', 'newpassword123');
await page.click('[type=submit]');
await expect(page.locator('[data-testid=success]')).toBeVisible();
});
Epic Stack ships with 60+ tests covering auth, profile management, and critical user flows. This is rare — most boilerplates ship with zero tests.
Epic Stack's SQLite Philosophy
The SQLite choice is controversial but defensible:
// SQLite with Litefs for production multi-region
// Drizzle schema definition
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
export const users = sqliteTable('users', {
id: text('id').notNull().primaryKey(),
email: text('email').notNull().unique(),
username: text('username').notNull().unique(),
name: text('name'),
createdAt: integer('created_at', { mode: 'timestamp' })
.notNull()
.defaultNow(),
});
export const passwords = sqliteTable('passwords', {
hash: text('hash').notNull(),
userId: text('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
});
Why SQLite in production?
- Single file = no database server to manage
- Litefs provides multi-region replication on Fly.io
- SQLite handles most SaaS workloads to $1M ARR
- Simpler local development (no Docker needed)
The trade-off:
- Fly.io becomes a deployment dependency
- Multi-writer scenarios are complex (Litefs handles reads)
- PostgreSQL-specific features unavailable
Remix SaaS: Features First Approach
Remix SaaS takes the opposite path — give developers the features they need today:
// Organization management — not in Epic Stack
export async function getOrganizationWithMembers(orgId: string) {
return prisma.organization.findUnique({
where: { id: orgId },
include: {
members: {
include: { user: true },
orderBy: { createdAt: 'asc' },
},
subscription: {
include: { plan: true },
},
},
});
}
// Plan enforcement middleware
export async function requireActivePlan(request: Request) {
const user = await requireUser(request);
const org = await getOrganizationByUserId(user.id);
if (!org?.subscription || !isSubscriptionActive(org.subscription)) {
throw redirect('/pricing?reason=subscription-required');
}
return { user, org };
}
The Key Decision Points
Choose Epic Stack when:
1. Testing is non-negotiable from day one Epic Stack's test suite is genuinely valuable. Bug-free auth flows matter for SaaS.
2. You're deploying to Fly.io Epic Stack's Fly.io integration (Litefs, multi-region) is purpose-built. You'll fight the defaults if deploying elsewhere.
3. You want a reference implementation Kent C. Dodds built Epic Stack as "this is how I'd build a real app." It's opinionated because opinionation is the point.
4. Single-user or per-user SaaS (no organizations) Epic Stack's user-centric model is simpler when you don't need multi-tenancy.
Choose Remix SaaS when:
1. You need organizations now Multi-tenancy is the most-requested feature in any SaaS starter. Remix SaaS ships it; Epic Stack doesn't.
2. You prefer PostgreSQL PostgreSQL is the default for most hosting platforms (Railway, Supabase, Neon, Render). Remix SaaS's Prisma + PostgreSQL is a more standard setup.
3. You want shadcn/ui Remix SaaS ships with the component library most Next.js developers already know.
4. You'll deploy outside Fly.io Remix SaaS is deployment-agnostic. Railway, Render, Heroku, VPS — all work cleanly.
A Middle Path: Epic Stack + Organizations
Some teams start with Epic Stack and add organizations:
// Adding organizations to Epic Stack
// This is ~2 days of work, but well-structured
export const organizations = sqliteTable('organizations', {
id: text('id').notNull().primaryKey(),
name: text('name').notNull(),
slug: text('slug').notNull().unique(),
createdAt: integer('created_at', { mode: 'timestamp' }).notNull().defaultNow(),
});
export const organizationMemberships = sqliteTable('organization_memberships', {
userId: text('user_id').notNull().references(() => users.id),
organizationId: text('organization_id').notNull().references(() => organizations.id),
role: text('role', { enum: ['owner', 'admin', 'member'] }).notNull(),
});
Epic Stack's clean architecture makes additions easier than most boilerplates.
Verdict
Use Epic Stack if: Quality practices > feature completeness. Fly.io deployment. SQLite is acceptable.
Use Remix SaaS if: Feature completeness > testing rigor. PostgreSQL required. Organization support needed.
Use neither if: You're not committed to Remix. Next.js alternatives have more tooling, more tutorials, and more community momentum.
Getting Started
Both are free and publicly available:
# Epic Stack
npx create-epic-app@latest my-app
cd my-app && npm install
# Configure: SESSION_SECRET, DATABASE_URL (SQLite local), RESEND_API_KEY
# Remix SaaS
git clone https://github.com/dev-xo/remix-saas my-app
cd my-app && npm install
cp .env.example .env
# Configure: DATABASE_URL (PostgreSQL), STRIPE_SECRET_KEY, RESEND_API_KEY
Epic Stack's create-epic-app CLI handles initial configuration interactively. Remix SaaS requires manual environment variable setup. Both target developers with existing Remix knowledge — neither is a beginner-friendly quick-start.
Key Takeaways
- Both are free and open source — the cost is time, not money
- Epic Stack prioritizes production practices: 60+ tests, TOTP 2FA, Fly.io multi-region deployment with SQLite + Litefs
- Remix SaaS prioritizes features: organizations, PostgreSQL, shadcn/ui, and a more standard deployment story
- If testing rigor matters from day one and you're comfortable with Fly.io deployment, Epic Stack is the reference implementation
- If you need organizations immediately and prefer PostgreSQL, Remix SaaS is the faster path
- Neither is a good choice if you haven't decided on Remix — Next.js alternatives (T3 Stack, ShipFast) have larger communities and more tutorials
- Both projects are actively maintained in 2026; Epic Stack by Kent C. Dodds' team and Remix SaaS by community contributors — check GitHub activity before committing to either
- Remix's loaders and actions mental model is genuinely different from Next.js App Router — invest a day in Remix fundamentals before committing either project to a deadline
- The right question before choosing either: are you committed to Remix specifically? Remix is a great framework, but the Next.js ecosystem has more boilerplates, tutorials, and community answers — if you're not specifically excited about Remix's loaders/actions model, Next.js starters are safer
The Testing Gap and Why It Matters
The most consequential difference between Epic Stack and Remix SaaS isn't the database or deployment target — it's the testing infrastructure. Epic Stack ships with 60+ tests covering authentication flows, profile management, and critical user paths using a full stack: Playwright for end-to-end browser tests, Vitest for unit tests, and MSW (Mock Service Worker) for mocking external APIs during tests.
Remix SaaS ships with minimal testing. There's a test setup but no substantive test coverage. This matters in ways that aren't obvious during initial development: as the codebase grows and developers who didn't write the original code make changes, untested code breaks silently. Authentication bugs in particular are high-stakes — a broken password reset flow means users can't access their account.
The Epic Stack testing philosophy is that tests should be cheap to write and informative when they fail. Kent C. Dodds' background in testing (he's authored several prominent testing resources in the JavaScript community) is evident in how the tests are structured. They test user behavior, not implementation details, which means they remain useful after refactoring.
If you value testing as a practice and want to inherit a strong testing culture from your boilerplate rather than building it from scratch, Epic Stack is the only free Remix option that provides this. The tradeoff is real: writing tests for new features takes longer upfront, and developers accustomed to untested codebases often find Epic Stack's discipline feels slow initially. The velocity recovers once the patterns become familiar, and the absence of test-induced regressions compounds over time.
Data Loading and the Remix Mental Model
Both starters use Remix's loader/action pattern, but they demonstrate it differently. Epic Stack uses loaders for almost everything — no client-side data fetching with useEffect, no React Query, no external state management. Data flows from loader to component to action back to loader. This is Remix's intended mental model and it's demonstrated consistently throughout Epic Stack.
Remix SaaS is slightly more permissive. Some features use client-side state where Epic Stack would use server state. This makes Remix SaaS feel more familiar to developers coming from Next.js Pages Router but slightly undermines the progressive enhancement that makes Remix distinctive.
For teams specifically choosing Remix for its progressive enhancement and web standards approach, Epic Stack's stricter adherence to the Remix model is a feature. For teams choosing Remix pragmatically (because they like the routing model but aren't ideologically committed to progressive enhancement), Remix SaaS's pragmatic approach is easier to work with.
Migrating Between the Two
Starting with one and switching to the other is rarely worthwhile. The database choice (SQLite vs PostgreSQL), the authentication approach, and the deployment targets are woven into both starters' structure. Teams typically choose based on their first requirements and live with the choice.
The migration path that does make sense: starting with Epic Stack for a personal or simple B2C product and adding organizations when the product grows into B2B territory. Epic Stack's clean architecture — service layer, clearly separated concerns, and comprehensive test coverage — makes it easier to add an organization model than it is to retrofit comprehensive testing into Remix SaaS after the fact. Growing in feature complexity is typically easier from a well-tested, practices-first foundation than the reverse journey of adding tests to untested code.
The choice between them ultimately comes down to how you value the tradeoffs: proven production practices with a higher setup cost (Epic Stack) versus a richer out-of-the-box feature set that moves faster in the first two weeks (Remix SaaS). Neither choice is wrong — they reflect different building philosophies. Both starters have remained current with Remix's ongoing releases in 2025, with Epic Stack notably adding React 19 compatibility and updated testing patterns that reflect the current React ecosystem.
See our full Remix boilerplates roundup for all Remix options including paid alternatives like SaaSrock and Makerkit.
The right choice between these options depends on your specific requirements, team expertise, and production constraints. Test each option with a realistic subset of your use case before committing — what works for one team's workflow may not fit another's.
See our Epic Stack review for the deep-dive on Kent C. Dodds' production stack.
Browse best free SaaS boilerplates including T3 Stack and Next SaaS Starter.
Check out this boilerplate
View Epic Stackon StarterPick →