Home/Blog

How to Choose a Tech Stack for Your Startup

A decision framework for a startup tech stack: which choices are hard to reverse, default stacks by product type, a one-week spike and an ADR template.

How to Choose a Tech Stack for Your Startup

Choose the stack your team already ships fastest in, built from boring, widely hired technology: for most web products that means TypeScript or Python, a mainstream full-stack framework, PostgreSQL and a managed hosting platform. Spend your care on the few decisions that are expensive to reverse (the database and data model, the primary backend language, identity and the tenancy model) and treat everything else as replaceable. Decide within a week, prove the choice with a spike that deploys to production, and write the decision down.

Key takeaways

  • Fluency beats theoretical fit. A language the team ships in today is worth more than a better-benchmarked one it is still learning.
  • Rank decisions by the cost of reversing them. The database, tenancy model, primary language and identity provider deserve real analysis; the CSS library does not.
  • PostgreSQL is the right default database for most startups. Add specialized stores when a measured need appears, not before.
  • Start on a managed platform. Kubernetes, multi-region and service meshes solve problems you do not have yet, and they cost you on-call time from day one.
  • Prove the choice with a one-week spike that covers auth, migrations, a background job, a deploy and error tracking, then record it in an ADR.

Rank decisions by how expensive they are to reverse

Most stack debates spend equal energy on every layer. That is backwards. A few decisions are nearly permanent; most can be changed in a sprint.

DecisionCost to change laterWhyHow much care
Database and data modelVery highData migration, dual writes, every query touchedThe most
Tenancy model (shared tables, schema per tenant, database per tenant)Very highAffects every query, index, backup and support toolHigh
Primary backend languageHighEffectively a rewrite plus a hiring changeHigh
Identity provider and user modelHighUser IDs everywhere, SSO connections, and some providers will not export password hashes, which forces resetsHigh
Frontend frameworkMediumUsually migratable route by routeMedium
Hosting platformLow to mediumContainers move easily; proprietary platform features do notMedium
Email, analytics, queue, cache vendorsLowReplaceable if wrapped behind an interfaceLow
Component library and CSS approachLowCosmetic, incrementalLeast

If you are debating Tailwind for a week and picked your tenancy model in an afternoon, swap those time budgets.

Six questions that decide most of the stack

1. What does the team already ship in? Not "know", ship: deploy, debug at 2 a.m., profile. A team of Python engineers will reach production faster with Django or FastAPI than with a framework they are learning, whatever the benchmarks say.

2. What shape is the product? A CRUD-heavy B2B dashboard, a realtime collaborative editor, an AI product built around model calls, a mobile-first consumer app and a data-intensive analytics tool have different hard parts. Pick technology for the hard part, and accept a mainstream default everywhere else.

3. Where will you hire for the next eighteen months? Look at real job listings and candidate supply in the cities or time zones you recruit from. A niche language narrows the pool and lengthens every search, and the one person who knows it becomes a key-person risk.

4. What must it integrate with? List the third parties that are core to the product: payments, identity, your LLM provider, email, the domain APIs your customers use. Check that each has a maintained first-party SDK in your language. Writing your own client for a payments API is not a good use of a startup's first month.

5. What compliance constraints apply? Data residency, HIPAA, SOC 2 or PCI scope push you toward managed services that offer the right agreements and audit logs, and toward a cloud region you can name in a security questionnaire.

6. What is the realistic load in year one? Be honest. Most B2B products in their first year serve traffic that one PostgreSQL instance and a few application containers handle comfortably. Optimize for change speed, and keep a clear path to scale.

A weighted scoring worksheet

When two options are close, score them. The point is not the arithmetic. Writing the weights forces the team to agree on what matters before arguing about frameworks.

Illustration: a three-person team with deep Python experience is building a B2B workflow product with one ML-backed feature. They compare full-stack TypeScript with a Python backend plus a React frontend. Scores run from 1 (poor) to 5 (excellent).

CriterionWeightTypeScript full stackPython backend + React
Team fluency3025
Hiring pool where they recruit1554
SDKs for their integrations1545
Fit for the hard part (the ML feature)2035
Operational simplicity1043
Reversibility if wrong1033
Weighted score (sum of weight × score, divided by 100)3.254.45

The Python option wins on fluency and fit, even though full-stack TypeScript would be a fine default for a team without that background. Change the team and the answer changes. That is the point.

Default stacks by product type

Use these as starting points, not prescriptions.

Product typeDefault stackWhyWatch out for
B2B SaaS and dashboardsTypeScript, Next.js or React with a separate API, PostgreSQL, a managed PaaSOne language, shared types, large hiring poolKeep business logic in plain server modules, not scattered through UI components
AI-centered productPython (FastAPI) for model and retrieval work, TypeScript frontend, PostgreSQL with pgvectorPython's ML and data ecosystemTwo toolchains. Keep one typed API contract between them
Realtime collaborationTypeScript or Elixir for the realtime layer, PostgreSQL, WebSocketsConnection-heavy workloads suit an event loop or the BEAMPresence and reconnect logic are the hard part, not the framework
Mobile-first consumerReact Native with Expo for a TypeScript team, native Swift and Kotlin for heavy device integrationShared code with the web for a TS teamStore review cycles slow every fix; use feature flags and over-the-air updates where allowed
Data-intensive analyticsPython, PostgreSQL for transactions, ClickHouse or a warehouse for analyticsSeparate transactional and analytical load earlyAnalytics queries on the primary database will hurt the product
Regulated (fintech, health)Mainstream language your team knows (Java or Kotlin, Go, TypeScript, Python), PostgreSQL, one major cloudAuditors and security questionnaires favor the well-trodden pathAudit logging, encryption and access reviews are features, not afterthoughts
Developer tools, agents and CLIsGo or RustSingle static binary, no runtime to installCross-compilation and code signing need CI work up front

The last row is personal. We wrote Trinetra, our server monitor, in Go and Braid, our download manager, in Rust, because both ship to machines we do not control, where a single binary with no runtime is worth a slower development pace.

Frontend choices

Next.js is the strongest default for products that need SEO, marketing pages and an app in one codebase, with a large ecosystem and hiring pool. The cost is complexity at the server and client boundary. Keep data access on the server and treat client components as the exception.

React Router v7, which absorbed Remix's framework features, suits teams that like web platform primitives: forms, HTTP caching, progressive enhancement.

SvelteKit produces small bundles and is pleasant to write. The ecosystem and hiring pool are smaller than React's.

A plain React single-page app built with Vite is often the right call for a complex tool behind a login, where SEO does not matter and the interface behaves more like a desktop app than a website.

Backend languages compared

LanguageStrengthsCostsChoose it when
TypeScript on Node.jsOne language end to end, shared types, huge ecosystemCPU-bound work blocks the event loop; dependency sprawl needs disciplineWeb SaaS with a JavaScript-fluent team
PythonUnmatched ML and data libraries; FastAPI and Django are matureSlower for CPU-bound work; free-threaded builds exist but are not the default; packaging needs a tool like uvAI and data products
GoStatic binaries, simple concurrency, low memory, fast buildsMore verbose; fewer batteries-included web frameworksInfrastructure, high-concurrency APIs, CLIs
Java or KotlinMature JVM, strong typing, deep enterprise librariesHeavier frameworks and runtimeFintech, enterprise integrations, JVM-fluent teams
Ruby on RailsVery fast path from idea to CRUD in productionSmaller hiring pool in many markets; needs performance work at scaleRails-fluent founders building CRUD SaaS
ElixirRealtime and fault tolerance on the BEAM; Phoenix LiveViewSmall hiring poolRealtime products with Elixir-fluent founders
RustPerformance and memory safety without a garbage collectorSlow to write; steep learning curvePerformance or safety is the product

Database: start with PostgreSQL

PostgreSQL covers relational data, JSON documents (jsonb), full-text search, geospatial queries (PostGIS) and vector similarity search (pgvector) in one system you can back up, replicate and reason about. Every major cloud runs it as a managed service, as do Supabase and Neon. Our database selection guide goes deeper on when something else is warranted.

Add other stores when you can point at a measured need:

  • Redis or Valkey for caching, rate limiting, sessions and simple queues.
  • A search engine (OpenSearch, Meilisearch, Typesense) when PostgreSQL full-text ranking or typo tolerance is not good enough for users.
  • ClickHouse or a warehouse when analytical queries start competing with product traffic.
  • A document database only when the data really is document-shaped and you rarely join across it.

Two rules that save rewrites: store timestamps in UTC with a time zone-aware type, and store money as integer minor units or a fixed-point decimal, never as a float.

Infrastructure by stage

Before product-market fit: a managed platform such as Vercel, Render, Railway or Fly.io, or one cloud's managed container service (Google Cloud Run, AWS ECS on Fargate, Azure Container Apps). Managed PostgreSQL with point-in-time recovery. One region. CI deploys on merge.

After product-market fit: move to one major cloud when you need private networking, compliance controls or pricing the platform cannot match. Describe it in infrastructure as code (Terraform, OpenTofu or Pulumi) from the first resource. Run containers on a managed service before considering Kubernetes; our comparison of Kubernetes and serverless covers the trade-offs.

Prove it with a one-week spike

A slide comparing frameworks proves nothing. A spike that reaches production proves most of it. Give one or two engineers a week and this list:

  • Sign-up and login through the chosen identity provider, with one role check enforced on the server
  • One table created by a migration that CI applies, then a second migration that alters it
  • One flow from UI to database and back, with server-side validation
  • One background job with retries and a visible failure state
  • One call to the most critical third-party API (payments, LLM, email)
  • A deploy from CI to a production-like environment, and a rollback that you actually performed
  • Error tracking receiving a deliberate exception with a readable stack trace
  • One integration test running in CI against a real database

If any item costs a day of fighting the framework, take that seriously. It will cost a day every month for years.

Write the decision down

Record the choice as an Architecture Decision Record so the next engineer, investor or acquirer can see why it was made and when to revisit it. Decision records are one of the first things evaluators ask for in technical due diligence.

## ADR-001: Primary application stack
 
Status: Accepted, 2026-10-04
 
Context: Three engineers, strongest in Python. B2B workflow product with one
ML-backed feature. EU customers expected in year one.
 
Decision: Python (FastAPI) API, React frontend built with Vite, PostgreSQL
(managed, EU region), deployed as containers on a managed service.
 
Options considered: Full-stack TypeScript with Next.js; Django monolith.
 
Consequences: Two toolchains. API contract defined in OpenAPI and types
generated for the frontend. Background jobs need a separate worker process.
 
Revisit if: the team becomes mostly TypeScript engineers, or the frontend
needs server rendering for SEO.

What goes wrong in production

These are stack-related failures that reach the pager, usually months after the decision was made.

Serverless functions exhaust database connections. Each function instance opens its own connection, and a traffic spike opens hundreds. Use a connection pooler (PgBouncer or your provider's pooler) from the first deploy.

Edge runtimes surprise you. Code that runs fine in Node.js fails at the edge because a database driver or a Node API is not available there. Keep data access in the regular server runtime unless you have a reason not to.

The ORM hides N+1 queries. A page that runs one query per row is fast with fifty rows and times out with fifty thousand. Log query counts per request in development and fail tests that exceed a budget.

Slow work runs inside the request. Sending email or calling an LLM inside the signup handler couples your page latency to someone else's API. Many serverless platforms also stop work after the response is sent. Put it on a queue.

Two languages drift apart. Validation rules and models get duplicated between a TypeScript frontend and a Python backend and then disagree. Generate types from one schema, such as an OpenAPI document.

The niche language owner leaves. The service written in the language only one engineer knows becomes untouchable. If you choose something unusual, make sure at least two people can ship and debug it.

Floats in money columns. Rounding errors show up as invoices that are off by a cent, which finance will notice before you do.

Frequently Asked Questions

What is the best tech stack for a startup?

The best stack is the one your team already ships quickly in, built from mainstream technology with a large hiring pool. For most web products that means TypeScript or Python, a full-stack framework such as Next.js or Django, PostgreSQL and a managed hosting platform. Technology choice matters far less than how fast the team can ship and fix things.

Should a startup use microservices?

Almost never at the start. A well-structured monolith with clear module boundaries is faster to build, easier to debug and cheaper to run for a small team. Extract a service later when a module needs independent scaling, a different deploy cadence or a separate owning team.

Is Python or Node.js better for a startup backend?

Choose the one your team is fluent in. Python is the stronger choice when machine learning or data processing is central to the product, while Node.js with TypeScript lets a web team use one language and share types across frontend and backend. Both run large production systems.

When should a startup move from a PaaS to AWS, GCP or Azure?

Move when the platform blocks something you need: private networking, specific compliance controls, data residency, or pricing that no longer fits your usage. Moving earlier adds infrastructure work and on-call surface without a matching benefit. When you do move, define everything in infrastructure as code from the start.

Does the tech stack matter to investors?

Investors rarely care which framework you chose, but technical due diligence does check whether the choice fits the team and the product. They look for mainstream, maintainable technology, a team that can explain its decisions, and no key-person risk from a niche language. A documented decision record helps.

Need help choosing your stack?

We are senior engineers who build production systems and keep running them after launch: if we built it, we are on the pager. We can pressure-test your stack against your product and team, run the spike with you, or take an existing prototype to production on a foundation you will not have to rewrite.