HTML / CSS

EpicStack by Gaz

Kent C. Dodds published his Epic Stack — his opinionated set of tools for starting a new project. It's excellent. Go read it.

15 Oct 2023

EpicStack by Gaz

Kent C. Dodds published his Epic Stack — his opinionated set of tools for starting a new project. It's excellent. Go read it.

It got me thinking: what would my stack look like? Not what's trendiest. What I'd actually choose if I needed to ship a product. Here's the list, with reasoning for each pick.

Framework: NextJS

Not using all the experimental App Router features yet. But NextJS has earned my trust through stability. More importantly, most developers already know it. That matters when you're building a team. Familiarity speeds up onboarding and collaboration.

Hosting: Fly.io or AWS ECS

For smaller projects, Fly.io. I use it for projects like Mockland.dev and the experience is smooth. For larger-scale apps with complex infrastructure needs, AWS ECS. Both are battle-tested.

Database: Postgres

Kent C uses SQLite and LiteFS. Interesting choice. But I've run Postgres in production for years and never regretted it. It scales, it's reliable, and every developer knows it. I'll take boring and dependable over novel and unproven.

Monitoring: Grafana

Fly.io provides Grafana out of the box. I'm not actively watching dashboards daily, but having monitoring available when something goes wrong is worth the zero setup cost.

CI/CD: GitHub Actions

Easy to set up. Works reliably. The ecosystem of pre-built actions is massive. I've never hit a wall with it.

Auth: JWT with PassportJS

Old-fashioned? Sure. But it's simple, well-documented, and I've never had it fail me. For scaled projects with enterprise requirements, I'd switch to Auth0 or Okta. For most projects, PassportJS is enough.

Transactional Email: Sendinblue (Brevo)

The free tier covers most hobby projects. The paid tiers are reasonable. API is clean. No complaints.

Forms: Formik

Simple, elegant, and widely known. Developers pick it up quickly, which speeds up the team.

ORM: Prisma

Used it. Enjoyed it. Much better than Sequelize. Prisma with NextJS API routes is a great combo for projects where the backend logic isn't too complex. When it gets complex, I pull the backend into a separate Fastify service.

Permissions: Role-based

Start with simple roles (admin, user, viewer). Expand to fine-grained permissions only when the business requires it. Over-engineering permissions early is a time sink.

Image Hosting: Cloudinary

Upload an image, get a URL back, save it to your database. Cloudinary handles resizing, optimization, and CDN delivery. Free tier is generous. For heavy uploads, S3 is always an option.

Caching: Redis (backend) + Cloudflare (frontend)

For API response caching, Redis via something like fastify-caching. For frontend asset caching, Cloudflare. This combination handles most caching needs without complexity.

Styling: EmotionJS or ChakraUI

I'm not a Tailwind fan for large projects. Adding utility classes to fix styling issues feels like a patch, not a solution. Component-based styling with EmotionJS keeps the codebase clean. ChakraUI is a solid component library built on the same principles.

E2E Testing: Cypress

Cypress works. Playwright is also good — I haven't seen enough of a difference to justify switching. Pick one and invest in your test suite.

Request Mocking: MSW

Mock Service Worker. No doubt about this one. It intercepts requests at the network level, works in tests and during development. Nothing else comes close.

Unit Testing: Jest + Testing Library

Still the most solid combination. Vitest is a good alternative if you want faster test execution.

Code Quality: Prettier + ESLint + TypeScript

Non-negotiable. Prettier for formatting. ESLint for linting. TypeScript for static types. These are table stakes.

Validation: Zod

Runtime schema validation. If you adopt it early in a project, it's fantastic. In practice, most projects are too rushed at the start to set up Zod properly. But when you do, it pays for itself.

Error Monitoring: DataDog

My alternative to Sentry. I find DataDog gives me more flexibility and options for tracing, logging, and alerting in one platform.

Payments: PayPal

Works fine. Stripe is also good. I've used PayPal without issues. Don't overthink this one.

Analytics: Google Analytics

Simple. Universal. And one of the search engines is already processing your data anyway, so you have one fewer integration to worry about.

The Honest Disclaimer

Some of these picks are controversial. Some will age poorly. That's the nature of tech stacks — they're snapshots of judgment at a point in time. The important thing is having a considered opinion and being willing to update it as you learn.