What a “tech stack” really includes
When people talk about a tech stack they usually mean a front-end framework and a back-end language. In practice, a production web application rests on several layers, and each one is a separate decision:
- Front end: what runs in the browser, and how HTML reaches it.
- Back end: the language, runtime and framework that hold business logic and expose APIs.
- Data: the primary database, plus any cache, search index or file storage.
- Hosting and infrastructure: where the application runs, and how much of it is managed for you.
- Supporting services: authentication, email, payments, monitoring and logging.
- Delivery tooling: version control, automated tests, build and deployment pipelines.
The choices interact. A server-rendered front end needs a server; a serverless back end shapes how you connect to a database; a small team may favour one language end to end. Decide the layers together, but in a sensible order.
Start from requirements, not trends
The right stack follows from what the application has to do and who will look after it. Before comparing frameworks, write down:
- The kind of experience. A content-led site, a dashboard-heavy internal tool and a real-time collaborative editor need very different front ends.
- The shape of the data. Highly relational records (orders, invoices, users and permissions) point one way; large volumes of loosely structured events point another.
- Integrations. Payment gateways, ERPs, identity providers and government APIs often come with official SDKs in some languages and not others.
- Non-functional needs. Expected traffic and peaks, availability, data residency, privacy and accessibility obligations.
- The team that will maintain it. Skills you have, skills you can hire, and who will own the system in three years.
A useful cross-check is the AWS Well-Architected Framework, which groups architectural concerns into six pillars: operational excellence, security, reliability, performance efficiency, cost optimisation and sustainability. The pillars are written for AWS but the questions apply to any platform. If a candidate stack makes one of those pillars hard to satisfy, find out before you commit.
Front end: decide how pages are rendered first
The most consequential front-end decision is not which framework you use, but where HTML is produced. Google’s Rendering on the Web guide describes the main options:
| Approach | What happens | Typical fit |
|---|---|---|
| Static rendering | HTML is generated at build time and can be served from a CDN | Marketing sites, documentation, blogs |
| Server-side rendering (SSR) | The server builds HTML for each request | Personalised or frequently changing pages |
| Client-side rendering (CSR) | JavaScript in the browser fetches data and builds the page | Highly interactive tools behind a login |
| SSR with hydration | Server HTML is sent, then made interactive in the browser | Apps that need both fast first paint and rich interaction |
The guide’s authors note that client-side rendering tends to grow the JavaScript bundle as an application grows, which hurts responsiveness, and that full hydration effectively makes you pay for rendering twice. Their overall advice is to favour static or server rendering, mix approaches page by page where that helps, and ship as little JavaScript as the experience allows.
Framework choice then follows. React’s own documentation now recommends starting new apps with a framework such as Next.js or React Router, and suggests building your own set-up with a build tool such as Vite mainly when existing frameworks do not suit your constraints, or when you want to learn the basics. Angular, Vue and Svelte (with their respective meta-frameworks) are equally mainstream choices. The differences between them matter less than consistency: pick one, agree conventions, and avoid mixing several in one product.
Back end: language, runtime and framework
Popularity is not a reason on its own, but it does affect hiring, documentation and the number of maintained libraries. In the Stack Overflow Developer Survey 2025, JavaScript was the most used language among all respondents (66%), followed by HTML/CSS, SQL and Python; among professional developers, TypeScript was used by 48.8%. Node.js (48.7%) and React (44.7%) led the web frameworks and technologies category.
Mainstream back-end options and where each tends to be chosen:
- Node.js with TypeScript (Express, NestJS, or a full-stack framework): one language across browser and server; strong for API-heavy and real-time work.
- Python (Django, FastAPI, Flask): fast to build with, and a natural fit when the product leans on data processing or machine learning.
- Java or Kotlin (Spring Boot): common in large organisations with long-lived systems and strict integration needs.
- C# (ASP.NET Core): a strong option where the organisation already runs Microsoft tooling.
- PHP (Laravel, or WordPress for content-led sites): a large ecosystem and widely available hosting.
- Go: small, fast services and infrastructure tooling.
All of these can build reliable systems. The deciding factors are usually the team’s skills, the integrations you need, and how well the framework handles the boring essentials: authentication, validation, database migrations, background jobs and testing.
Data: match the database to the data
For most business applications a relational database is the sensible default. Transactions, constraints and joins protect data integrity in ways that are tedious to rebuild by hand. PostgreSQL was the most used database in the 2025 survey at 55.6%, ahead of MySQL, SQLite, Microsoft SQL Server and Redis.
Add other stores only when a specific need justifies them:
- A cache or key-value store for sessions, rate limiting and hot data.
- A search engine when users need full-text search, filtering and relevance ranking.
- A document database when records genuinely vary in structure and are read as whole documents.
- Object storage for files, images and backups, rather than putting them in the database.
Every extra store is another thing to secure, back up, monitor and upgrade.
Support lifecycles are part of the decision
Every runtime and database has a support window, after which security fixes stop. Check it before you start, and plan upgrades into the budget.
- Node.js: the project’s release page states that production applications should use only Active LTS or Maintenance LTS releases, and that LTS lines typically receive critical bug fixes for 30 months in total. It also notes a change in cadence: from Node.js 27, every major version is planned to become an LTS release after its Current phase.
- Python: each feature release is supported for about five years. From Python 3.13, that is roughly two years of bug-fix releases followed by security fixes only.
- PostgreSQL: each major version is supported for five years, new major versions arrive about once a year, and minor releases with fixes come out at least every three months. The project recommends always running the latest minor release of your major version.
A stack built on versions near the end of their support window starts life with an upgrade already due.
Dependencies are part of your stack too
Modern web applications pull in hundreds of open-source packages. The OWASP Top 10:2025 lists Software Supply Chain Failures as A03, reflecting how much risk now sits in third-party code and build pipelines. Practical controls:
- Prefer well-maintained libraries with active releases and a clear security policy.
- Commit lockfiles so builds are reproducible.
- Run automated dependency and vulnerability scanning in the pipeline.
- Remove packages you no longer use, and question every new one.
Architecture: start simple and design for change
A modular monolith (one deployable application with clear internal boundaries) is a reasonable starting point for most new products. Martin Fowler’s essay on sacrificial architecture argues that early versions of a system may well be replaced as it grows, and that good modularity is what makes replacing parts practical. He quotes Google’s Jeff Dean on designing for roughly ten times current needs while planning a rewrite before a hundred times, and observes that microservices add complexity early that a monolith avoids.
On hosting, the main trade-off is control versus operational effort. Managed platforms and managed databases remove patching and failover work; self-managed servers give more control at the cost of more operations. For most teams, managed services are the better default unless there is a specific reason to run things yourself.
A practical decision checklist
Before you commit to a stack, confirm that:
- The rendering approach suits each major part of the application.
- Official SDKs or well-maintained libraries exist for every critical integration.
- Each runtime, framework and database version has years of support remaining.
- The team can build, test, deploy and debug it today, or can hire for it.
- Authentication, authorisation, validation and logging are handled by mature components, not custom code.
- Hosting meets your availability, data residency and budget needs.
- There is a dependency management and upgrade plan, not just a build plan.
A stack chosen this way will rarely be the most fashionable, but it will be easier to staff, secure and keep running, and that is what matters over the life of a product.
Sources
- AWS Well-Architected Framework: The pillars of the framework
- web.dev: Rendering on the Web
- React: Creating a React App
- Stack Overflow Developer Survey 2025: Technology
- Node.js: Previous releases
- Python Developer’s Guide: Status of Python versions
- PostgreSQL: Versioning policy
- OWASP Top 10:2025
- Martin Fowler: Sacrificial Architecture