Skip to content
Lab Twelve
← Field Notes
8 min read

Choosing a Stack: Next.js, Python, Rust, or Go

A polyglot guide to picking the right stack for your app. When Next.js fits, when Python and FastAPI win, when Rust or Go earn their keep, and why the stack should serve the build instead of your resume.

By Brian, founder-engineer at Lab Twelve.

The right stack is the one that fits the build, not the one on the engineer's resume. Most web apps want Next.js and Postgres. Data and AI workloads want Python and FastAPI. Latency-critical or concurrency-heavy services want Go. A narrow set of performance-sensitive components want Rust. Lab Twelve is polyglot on purpose because forcing every problem into one favorite language is how good products get slow, expensive, or both.

This post is the practical version of an architecture decision. It is not a benchmark war. It is how to match a tool to a job so the build is cheaper to ship and easier to live with.

Start with the build, not the language

Before you name a language, name the workload. Stacks are answers to questions, and the question comes first:

  • Is this mostly screens, forms, and content? That is a web app concern.
  • Is this mostly data transformation, ML inference, or scientific work? That is a Python concern.
  • Is this a high-throughput service where p99 latency and memory matter? That is a Go or Rust concern.
  • Is this a one-page marketing site with a form? You may not need a backend at all.

Picking language first and bending the build to fit is the most common architecture mistake I see. It produces a Python web frontend that fights its own framework, or a Rust CRUD app that takes three times as long to write for no user-visible benefit. Match the tool to the job and the estimate drops.

When Next.js is the right call

Next.js is the default for most apps Lab Twelve ships, and the default exists for a reason. When your product is screens, navigation, forms, auth, and a database behind it, the App Router gives you server rendering, routing, and a React frontend in one coherent system. SEO works because pages render on the server. The marketing site and the product can share components and a design system.

Reach for Next.js when:

  • The product is user-facing screens with CRUD behind them.
  • SEO and fast first paint matter (marketing, content, commerce).
  • You want one codebase for frontend and backend API routes.
  • The team will iterate on UI frequently after launch.

This covers the bulk of the published tiers: launch pages, micro apps, business apps, and most MVPs. A booking tool, a client portal, an internal approval dashboard. These are Next.js shaped, and pricing reflects that the path is well-worn. See where each tier lands in the 2026 cost guide.

When Python and FastAPI win

The moment your build has a serious data or AI core, Python earns its place. The ecosystem for machine learning, data processing, and scientific computing has no real competition, and FastAPI gives you a clean, typed, async HTTP layer on top of it.

Reach for Python and FastAPI when:

  • You are running model inference, embeddings, or an LLM pipeline as a core feature.
  • You need pandas, NumPy, or the data science toolchain.
  • You are building an API consumed by other services more than by a browser.
  • The heavy logic is computation, not presentation.

A common and correct pattern is Next.js for the product surface and a FastAPI service for the AI or data work behind it. The browser talks to Next.js; Next.js talks to a Python service that does the inference. Each tool does what it is best at. That split is an architecture decision, and it is exactly the kind of thing the understand and architect phases exist to settle before code.

A Next.js front with a Python brain is not complexity for its own sake. It is two tools each doing the one thing it is best at.

Brian, Lab Twelve

When Go earns its keep

Go is the answer when you need a service that is fast, concurrent, and boring in the best sense. It compiles to a single binary, handles thousands of concurrent connections without ceremony, and deploys with almost no runtime baggage.

Reach for Go when:

  • You are building a high-throughput API or a real-time service.
  • You need predictable latency under concurrent load.
  • You want a small, fast-starting deployable for a microservice.
  • The logic is straightforward but the volume is high.

Go is rarely the right choice for the whole product, and almost never for the UI. It shines as a focused service: a webhook ingester, a notification fan-out, a proxy, a job runner that has to keep up. If a Node or Python service is buckling under connection count, Go is often the surgical fix.

When Rust is worth the cost

Rust is the sharpest tool in the box and the most expensive to wield. You buy memory safety without a garbage collector and performance at the metal. You pay in development time, because the compiler is strict and the language is dense.

Reach for Rust when:

  • A specific component is genuinely performance-critical and profiling proves it.
  • You need to avoid garbage collection pauses entirely.
  • You are writing something that runs at huge scale where small inefficiencies compound into real money.
  • WebAssembly or systems-level work is on the table.

For a founder MVP, Rust is usually the wrong call for the whole app. The right call is Rust for the one hot component that needs it, wrapped in a service the rest of the system talks to. Reaching for Rust everywhere because it is fast is the mirror image of reaching for Python everywhere because it is familiar. Both ignore the build.

A decision table

| Your build is mostly... | Strong default | Why | |-------------------------|----------------|-----| | User screens, forms, CRUD, content | Next.js + Postgres | SEO, one codebase, fast UI iteration | | ML inference, data pipelines, AI core | Python + FastAPI | Unmatched data and ML ecosystem | | High-throughput or real-time service | Go | Concurrency, predictable latency, tiny deploy | | A proven performance-critical hot path | Rust | Memory safety, no GC pauses, raw speed | | One marketing page with a form | Next.js (or static) | No backend needed; ship in days |

The table gives defaults, not laws. A real architecture often combines two of these: a Next.js product with a Python service, or a Go ingester feeding a Next.js dashboard. Polyglot does not mean chaotic. It means each boundary is drawn where the workload changes.

The cost of choosing wrong

Choosing the wrong stack does not always crash. More often it just taxes you quietly. A web app written in a language with no good frontend story takes longer to build every screen. A data-heavy feature bolted onto a runtime with a weak data ecosystem fights you on every transformation. A simple CRUD app written in Rust ships in triple the time for zero user benefit.

Every one of those taxes shows up in your invoice, your timeline, or your maintenance burden. Matching the tool to the job is not a luxury. It is the cheapest decision you make, and it is made in the architecture phase before a line of code is committed.

How Lab Twelve decides for your build

When you run your app through the scope chat at /start, the scope determines the stack, not the other way around. The understanding phase surfaces whether your build is screen-heavy, data-heavy, or throughput-heavy. The architecture phase picks the tools that fit. You do not have to know the difference between FastAPI and Go to get the right one. You have to describe the build honestly. The polyglot choice is our job.

That is the value of one architect-engineer over a single-language shop: the recommendation is not biased by what the team happens to know. The stack serves your product.

The honest take

Stack debates are mostly identity, not engineering. People defend the language they learned first. The professional move is to forget your preferences and ask what the build needs. Next.js for most apps. Python when there is a data or AI brain. Go for throughput. Rust for the rare hot path. Combine them at the seams where the workload changes, and refuse to combine them anywhere else.

If you have a build and you are not sure what it should run on, that is exactly what the scope chat is for. Describe it at /start, and the architecture comes back with the price. Compare tiers on pricing.

Get a fixed quote in one conversation

Describe your build and get a fixed quote before you pay.

Start an AI scope →

Related

Ready to scope your app?

Describe your build and get a fixed quote before you pay.

Start an AI scope