Knowledge baseTechnical GuidesThis article

Choosing Your Stack in 2026

Stack debates waste enormous amounts of time. Here is the framework we actually use: not what is theoretically best, but what produces working software fastest for the type of problem you are solving.

Every technology choice is a trade-off between productivity, flexibility, and maintenance burden. The right choice depends almost entirely on context: what you are building, how fast you need it, and what you already know well.

What follows is the decision framework we use. It reflects choices made across dozens of projects, not abstract preferences.

Frontend: Next.js vs. plain React vs. vanilla

Use Next.js when you need routing, SEO, and a clear project structure out of the box. For anything that will be publicly accessible and indexed, Next.js is the default. The App Router with static export works well for marketing sites. Server components work well for data-heavy pages that do not require complex client-side state.

Use plain React (Vite) when you are building a single-page application with no SEO requirements. Admin dashboards, internal tools, authenticated apps where crawlability does not matter. Vite starts faster, the build is simpler, and you do not need to think about the server/client boundary.

Use vanilla HTML and JavaScript when the project is a simple marketing page with minimal interaction. The overhead of a full framework is not justified for a five-page static site with a contact form.

Database: SQLite vs. Postgres vs. Supabase

SQLite is underused. For applications with a single server and moderate write volume, SQLite is simpler, faster for reads, and requires no infrastructure. The hi-kaizen.com site has no database at all. Several of our service APIs run on SQLite with no operational burden.

Use Postgres when you need concurrent writes from multiple processes, advanced query features, or connection pooling for high traffic. Postgres is correct for production SaaS products with meaningful write volume or complex relational queries.

Use Supabase when you want Postgres plus auth, realtime subscriptions, and file storage with minimal setup. Supabase is excellent for prototypes that need to scale into production without infrastructure work. The trade-off is vendor dependency. If Supabase ever changes pricing or availability, migration is non-trivial.

Styling: Tailwind vs. CSS modules vs. plain CSS

Tailwind 4 is our default for anything with a custom design. The utility-class approach pairs well with component-based frameworks and makes AI-assisted development faster because the agent can express design intent directly in markup without context-switching to a stylesheet.

CSS modules are appropriate when working inside an existing codebase that already uses them, or when the design system is highly constrained and custom CSS makes the intent clearer.

Plain CSS is correct for small sites where Tailwind's build process is unnecessary overhead. A ten-page static site does not need a build pipeline.

API: Express vs. Next.js API routes vs. edge functions

Express 5 for standalone services. When we build a focused API service with its own database and deployment, Express is the right choice. It is lightweight, well-understood by AI agents, and has no framework magic to work around.

Next.js API routes for co-located server logic in a Next.js project. When the frontend and backend are tightly coupled and deployed together, keeping the API in the same project simplifies the workflow.

Edge functions (Cloudflare Workers) when latency matters and the logic is simple. For things like form handling, webhook processing, or simple data lookups at the edge. Not for complex stateful operations.

Deployment: Cloudflare vs. Vercel vs. self-hosted

Cloudflare Pages for static sites. Free, fast, global CDN, zero configuration. This site is deployed there. It deploys on every push to main and has 99.9% uptime without any work from us.

Vercel for Next.js projects that use server components or API routes. The integration is seamless and the developer experience is excellent.

Self-hosted (VPS) for services that need persistent state, long running processes, or cost-effective scaling. A small Hetzner or Digital Ocean instance running Express and SQLite handles thousands of requests per day at a fraction of the cost of serverless equivalents.

The decision principle

Pick the simplest option that satisfies your requirements, not the most capable option that could theoretically satisfy future requirements. You can always add complexity later. Removing unnecessary complexity from an existing system is expensive.

The best stack is the one that lets you ship the first version in the least time, with the least operational overhead, while keeping the path to scaling clear if the product warrants it.

Read next