Epic Stack Review 2026: Kent C. Dodds' Remix Starter
TL;DR
Epic Stack is the most opinionated, best-documented free boilerplate. Kent C. Dodds' philosophy shows: the stack prioritizes simplicity, testing, and deployment. It starts with SQLite (not PostgreSQL), uses Fly.io (not Vercel), and ships with Vitest + Playwright fully configured. Excellent for learning Remix deeply; less suited for developers who need to swap opinionated choices.
What You Get (Free)
npx create-epic-app@latest
Core stack:
- Remix (latest)
- TypeScript (strict)
- SQLite (development) → Postgres/LiteFS (production)
- Fly.io deployment
- Auth: Custom (email + password + passkeys + OAuth)
- Email: Mailgun or Resend
- UI: Radix UI + Tailwind
- Testing: Vitest + Playwright + MSW
- Monitoring: Sentry + Grafana
The SQLite Approach
The most surprising choice: Epic Stack starts with SQLite in development.
// prisma/schema.prisma — SQLite in dev
datasource db {
provider = "sqlite"
url = env("DATABASE_URL") // file:./dev.db locally
}
// env.server.ts — runtime validation
const schema = z.object({
DATABASE_URL: z.string().url(),
// For Fly.io: litefs:///litefs/app.db (distributed SQLite)
// For production: postgres://...
});
The reasoning: SQLite is simpler, faster to set up, and sufficient for most apps until you need horizontal scaling. LiteFS (Fly.io's distributed SQLite) handles production scaling. If/when you need PostgreSQL, the migration is straightforward.
This is pragmatic, not naive. Kent has explained the reasoning extensively and the numbers support it.
Testing is First-Class
Unlike every other boilerplate, Epic Stack's tests run out of the box:
npm run test # Vitest unit tests
npm run test:e2e # Playwright E2E tests
// All of this works without setup
import { test, expect } from '@playwright/test';
test('user can register and log in', async ({ page }) => {
const email = `test-${Date.now()}@example.com`;
await page.goto('/');
await page.getByRole('link', { name: 'Sign up' }).click();
await page.getByLabel('Email').fill(email);
await page.getByLabel('Password').fill('SecurePassword123!');
await page.getByRole('button', { name: 'Create account' }).click();
await expect(page).toHaveURL('/dashboard');
await expect(page.getByText('Welcome')).toBeVisible();
});
This is genuinely rare. Most boilerplates ship test configs but no working tests.
The Authentication System
Epic Stack's auth is custom — not NextAuth or Clerk. This is by design: Kent wants you to understand what's happening.
// app/utils/auth.server.ts — custom auth utilities
import { createCookieSessionStorage, redirect } from '@remix-run/node';
const sessionStorage = createCookieSessionStorage({
cookie: {
name: '__session',
httpOnly: true,
path: '/',
sameSite: 'lax',
secrets: [process.env.SESSION_SECRET!],
secure: process.env.NODE_ENV === 'production',
},
});
export async function requireUserId(request: Request): Promise<string> {
const userId = await getUserId(request);
if (!userId) {
throw redirect('/login');
}
return userId;
}
Passkeys (WebAuthn) support is included — rare in 2026 boilerplates.
Fly.io Deployment
Epic Stack is optimized for Fly.io, not Vercel:
# fly.toml
app = "your-app-name"
primary_region = "iad"
[build]
[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = true
auto_start_machines = true
[[vm]]
memory = "1gb"
cpu_kind = "shared"
cpus = 1
fly launch # Single command deploys to Fly.io
fly deploy # Updates
Fly.io's persistent VMs are more appropriate for Remix (server-rendered, stateful) than Vercel's serverless model.
The Not-So-Good
1. Remix Only — No Next.js Option
If your team is Next.js, Epic Stack teaches you Remix patterns that don't transfer directly. The investment is Framework-specific.
2. Fly.io Not Vercel
Most SaaS developers default to Vercel. Fly.io is excellent but requires learning (fly CLI, regions, machines). The deployment story is more complex.
3. No Billing Out of the Box
Epic Stack doesn't include Stripe. You add it yourself. For a product-focused boilerplate, this is intentional but annoying.
4. SQLite Concerns for Team Databases
Sharing a SQLite database in a team isn't as smooth as Postgres. Neon's branching for dev environments is more practical for teams.
Who Should Use Epic Stack
Good fit:
- Developers learning Remix who want a well-structured reference
- Teams already committed to Remix
- Products where testing is a first-class requirement
- Developers who want to understand every part of their stack
Bad fit:
- Next.js teams (significant context switch)
- Founders who need billing on day one
- Teams who prefer Vercel over Fly.io
- Solo founders who need the fastest possible time to market
Final Verdict
Rating: 4/5
Epic Stack is the best-architected free boilerplate. The testing setup, deployment documentation, and code quality are excellent. The Remix + SQLite + Fly.io opinions are strong — great if they align with your preferences, limiting if they don't.
Compare Epic Stack with alternatives on StarterPick.
Check out this boilerplate
View Epic Stack on StarterPick →