Consulting
How to Choose a Tech Stack: Criteria That Outlive the Hype
A stack is a five-year commitment usually made in a single call. Here is the order the decisions should be taken in, the criteria that carry real weight, working stacks for six project archetypes and what a wrong choice costs.
In short
A stack is chosen on weighted criteria, not popularity: hiring market 20%, load profile and existing team experience 15% each, timeline, budget, ecosystem maturity and data residency rules 10% each. Decide in this order: data and back end first, front end second, infrastructure third. For roughly 80% of commercial projects the working base is PostgreSQL with Node.js or Python underneath React.
A stack is a business decision with a three to five year horizon
A technology stack outlives the team that picked it. A commercial product typically runs five to seven years before a full rewrite, developers rotate off the project every eighteen months or so, and the technology decision is usually made in a single call by people who will not be paying for its consequences. So the right question is never "which is better" but "who will we be able to hire in three years, what will their hour cost, and who takes the project over if the current team leaves at once".
The decision locks in three cost lines at once. First, hiring: the gap in market rates between stacks at the same seniority level runs 30% to 50%, and it multiplies by headcount and years. Second, maintenance: how much time goes into dependency upgrades, patching vulnerabilities and staying compatible with new runtime versions. Third, handover: if the product ever needs to move to another vendor or an in-house team, an exotic stack turns into a discount on the value of your asset.
Fashion is the worst available criterion because it refreshes faster than a project pays back. Every eighteen months something arrives billed as the killer of the previous thing, and three years later it is either mainstream or quietly gone, taking the projects that bet on it with it. The practical filter is simple: anything under three years old has no mature ecosystem, no hiring market and nobody who has run it in production under real load. That is not a ban, it is a risk you should be choosing deliberately.
A word on who makes the call. The contractor is not a neutral party: any agency proposes the stack it currently has free developers for, and that is ordinary economics rather than a conspiracy. Veltos.Tech is no exception, and the correct client response is to ask for a justification framed in your business terms rather than our resourcing: how many specialists exist on the market, what happens to the project if the vendor changes, which parts are replaceable. If the answer never leaves the territory of "this is what we are good at", you are not the one making the decision.
The right order: back end, then front end, then infrastructure
The classic founder mistake opens with "we are building it on Next.js". That answers a question about page rendering, not about where the data lives, who computes the business logic, how permissions work or what happens to the database at ten million rows. The front-end framework is the most visible and the most easily replaced part of the system, so starting there means subordinating everything else to the shortest-lived decision in the project.
The working sequence is: data model and load profile, then back end, then front end, then infrastructure and operations. The database schema is the longest-lived part of a product. The interface will be rewritten two or three times over the project lifetime, while the tables you designed at the start survive every one of those rewrites. That is why an hour spent on the data model is cheaper than a week spent arguing about frameworks.
The load profile drives the rest. Read-heavy and write-light workloads can live on caching and replicas in almost any language. Many concurrent connections with little computation play to the strengths of Node.js and Go. Heavy calculation, reporting and data processing favour Python or Java. Strict money transactions call for a relational database and a mature ecosystem with no experiments. If nobody on the project can answer "how many requests per second do you expect in a year" even to the nearest order of magnitude, the stack choice is premature and discovery comes first.
Infrastructure comes last in order but not last in time. Containerisation, environment layout, migrations and CI need to be settled before the first line of product code, or six months later you own a system that only deploys on one specific developer laptop. For Russian projects data residency belongs in this same bucket: personal data of Russian citizens has to sit in a primary database hosted inside the country, and that constrains cloud choices harder than any technical argument does.
- Answer four questions first: what data, how much of it, who reads it and how often, and which operations must be transactional.
- The database choice matters more than the language: swapping a runtime is far cheaper than migrating a ten-million-row schema.
- The front-end framework is a reversible decision. If the argument about it has taken more than a day, you are debating the wrong layer.
- Put Docker, migrations and CI in during week one. Later it costs four times as much and always gets postponed.
Selection criteria and what each one weighs
A technology argument runs forever until weights enter it. The trick that makes it finite: list the criteria, assign each a percentage weight, take two or three real candidate stacks and score each on a five-point scale. Then compute the weighted sum and the decision stops being a question of who talks loudest. The important part is setting the weights before you look at the candidates, otherwise the table becomes a justification for a choice already made.
The heaviest criterion is the hiring market, and it is the one most often skipped. On the Russian market the difference between stacks shows up not only in CV volume but in time to fill: a mid-level role on a mainstream stack closes in two to four weeks, a rare one stretches across quarters, and the candidate you eventually find costs above market because they know how rare they are. For a product meant to be developed over several years that is direct money and a direct risk of stalling.
Second heaviest is the experience of the team you already have. A stack the team knows beats a theoretically better but unfamiliar one almost every time: the learning curve eats the first three or four months, and beginner mistakes in an unfamiliar technology are discovered in production. There is one exception, which is when the familiar stack physically cannot do the job, for instance when a PHP team is handed real-time event stream processing.
Data residency rules deserve to be treated as a hard constraint on the option set rather than a formality. If the product collects personal data from Russian users, foreign managed services are out for the primary database, part of the SaaS analytics toolkit is out, and the storage and logging model has to be designed up front rather than "brought into compliance later". Retrofitting compliance after launch usually means a data migration and a rewrite of the access layer, which is months of work with zero new user-facing features.
| Criterion | Weight | The question to ask | Red flag |
|---|---|---|---|
| Hiring market and cost of a specialist | 20% | How many weeks to fill a mid-level role and at what rate | One person in the team knows the stack |
| Load profile and data shape | 15% | RPS in a year, read or write heavy, transactional or not | "We will figure it out as we go" |
| Experience of the current team | 15% | How many projects the team shipped on this stack | Everyone will learn it on the job |
| Time to first release | 10% | What comes out of the box: admin, auth, payments | Half the basic plumbing gets written from scratch |
| Twelve-month budget | 10% | Build plus licences plus hosting plus support | Only the build was costed |
| Ecosystem maturity | 10% | Are there libraries for your integrations and payment providers | A key library has not been updated in two years |
| Data residency and personal data rules | 10% | Where the personal data database physically sits | Primary database in a foreign cloud |
| Three-year scaling plan | 5% | What breaks first at ten times the load | Architecture sized exactly for today |
| Who supports the project in three years | 5% | Can another team take the code over without a rewrite | A homegrown framework with no documentation |
Reference stacks for six project archetypes
What follows is not dogma but a set of working reference points: combinations assembled hundreds of times, with predictable maintenance costs and no hiring problems attached. Deviating from them is fine and often necessary, but the deviation should be said out loud: "we are not taking the standard option because this specific requirement breaks it". If the reason will not form into a sentence, take the standard option.
For a content or corporate site the decisive criterion is publishing speed and editor comfort, not architectural elegance. A headless CMS behind Next.js with pre-rendered pages gives excellent Core Web Vitals and a usable admin without building one. On the Russian market, where accounting-system integration and vendor familiarity matter, a mainstream commercial CMS stays a rational choice regardless of what engineering circles say about it.
For SaaS and web applications the choice almost always narrows to NestJS on TypeScript or Django on Python over PostgreSQL. NestJS wins when one team writes both ends and shared typing matters. Django wins when you need a ready admin, permissions out of the box and a fast first version. Both give predictable hiring and both comfortably carry a product to several hundred thousand users without anything exotic.
High-load services are the one category where language genuinely decides. Go on the hot path gives predictable memory use and latency, ClickHouse handles event analytics, and a broker like Kafka or NATS decouples the components. But you should only enter that architecture once the load is confirmed by measurement. Premature microservices and message brokers are the most expensive available way to slow down a product nobody has asked for yet.
| Project type | Back end and data | Front end | Infrastructure |
|---|---|---|---|
| Content and corporate site | Headless CMS (Strapi, Directus) or a commercial CMS, PostgreSQL | Next.js on React, static generation plus ISR | VPS in country, Nginx, Docker, CDN |
| Online store | A commercial CMS or Medusa/Saleor on PostgreSQL, queued ERP sync | Native CMS theme, or Next.js for the storefront | Docker Compose, Redis, S3-compatible storage |
| SaaS and web application | NestJS (TypeScript) or Django, PostgreSQL, Redis | React with TypeScript, TanStack Query | Docker, GitLab CI, S3, Sentry |
| High-load service | Go on the hot path, PostgreSQL with replicas, Kafka or NATS, ClickHouse | React, a thin client with no heavy logic | Kubernetes, autoscaling, Prometheus and Grafana |
| Internal system and portal | Django or Spring Boot, PostgreSQL, ERP and directory integration | A ready admin (Django Admin, Refine) instead of a custom UI | On-prem or VPS inside the corporate perimeter, LDAP SSO |
| Mobile app with a back end | FastAPI or NestJS, PostgreSQL, push via FCM and APNs | Flutter or React Native, native Swift and Kotlin when UX demands it | Managed database, object storage, feature flags, event analytics |
Front end: React, Vue, Angular or Svelte
Start with the uncomfortable fact: framework benchmarks barely apply to your project. The rendering speed difference between modern React, Vue, Angular and Svelte on a real commercial site is smaller than the effect of one uncompressed hero image or one extra analytics script. Choosing a front end by benchmark is optimising a variable that sits three decimal places down in your equation.
React leads Russian front-end vacancy volume by a wide margin, Vue holds a solid second place, Angular and Svelte sit noticeably lower. For a client that translates into a simple rule: on React you will find a replacement for any departing developer, and you will find them quickly. The flip side is that React imposes nothing, so architecture quality depends entirely on team discipline, and a bad React project looks worse than a bad Angular one. Next.js partly closes that gap by supplying structure and routing.
Vue is noticeably kinder to a small team and to people arriving from markup work: a lower entry barrier, better documentation, template syntax closer to plain HTML. Nuxt covers the same ground Next.js does. Angular is the only one of the four that imposes an architecture, and that is precisely its virtue in large corporate systems with long lifecycles and constant developer rotation: a newcomer opens an unfamiliar Angular project and immediately knows where everything lives. On a small project the same strictness is dead weight.
Svelte offers the best developer experience and the smallest bundles, but its hiring market is thin and niche libraries are scarcer. The sensible cases for it are a team already working in it, or a product where bundle size is genuinely critical, such as an embeddable widget. The closing rule is simple: if you already have a front-end developer, take the stack they know. If you have no team and are hiring from scratch, take React, because what you are buying is not a framework but the depth of the labour market.
- With a team, their experience decides. Without one, the hiring market decides, and that means React.
- A large corporate system with rotating staff and a five-year-plus horizon is a genuine argument for Angular.
- A small team without a dedicated architect will write cleaner code in Vue than in React.
- Svelte should follow a specific reason, not a benchmark chart.
Back end: Node, Python, Go, PHP or Java
Node.js with NestJS shines where there are many concurrent connections and little heavy computation: API gateways, chat, real time, and the layer between a front end and several internal services. The main practical benefit is one language across the project, with model types declared once and reused on both sides, which genuinely saves hours of contract negotiation. The main drawback is that synchronous heavy computation blocks the event loop, so bulk data processing has to move into separate workers.
Python splits into two different tools. Django is batteries included: ORM, migrations, permissions and a ready admin panel that makes an internal system come together weeks faster than on any other stack. FastAPI is a light asynchronous framework for APIs and services around machine learning, and it is the one ecosystem entrance into ML without adapters in between. If the product will ever touch models, having Python in the stack saves an entire integration layer.
Go is chosen for predictability: stable memory use, low latency under load, deployment as a single binary with no runtime or dependencies to install. It is the right tool for services that must hold traffic and run for years without surprises. The price is slower prototyping, fewer ready solutions for routine needs such as admin panels, and more expensive hiring. Picking Go for a CRUD project with ten daily users is paying for a property that will never be used.
PHP has a worse reputation than it deserves. Modern Laravel is a mature and fast framework, and on the Russian market PHP offers the deepest and cheapest hiring pool plus an enormous base of ready e-commerce solutions. Java and Kotlin with Spring are corporate territory: strict typing, mature integration tooling, long lifecycles and predictable support. The price is the highest developer cost and the slowest start, which is why Spring on a startup MVP is nearly always a mistake.
- Node.js and NestJS: real time, API gateways, typing shared with the front end.
- Django: internal systems and anything where a ready admin saves weeks.
- FastAPI: APIs and ML-adjacent services, the light entrance to the machine learning ecosystem.
- Go: services with proven load and real latency requirements.
- PHP and Laravel: e-commerce, constrained budgets, fast and affordable hiring.
- Java, Kotlin and Spring: corporate systems on a seven to ten year horizon with hard integration requirements.
The cost of a wrong choice and how to keep a stack replaceable
A wrong stack rarely looks like a catastrophe. It looks like everything slowly getting more expensive. Scenario one is the rewrite: the product hits a limit of the technology and the team returns with an estimate equal to 60% to 100% of the original build cost. The important part is that you pay twice, because the old version keeps serving live customers while the new one is written, and that overlap is rarely shorter than six months.
Scenario two, the quiet one, is the hiring dead end. The product works, nothing is on fire, but every vacancy takes three months to fill, every new developer costs a third above market, and a single person going on holiday stops releases. Because nothing is technically broken the decision gets deferred for years while the cost of ownership creeps up. The problem is usually discovered on the day that one person resigns.
Scenario three is vendor lock-in. It arrives not only through proprietary licensed CMS platforms but through cloud backend services whose SDKs grow into the business logic: auth, storage, functions and queues all tied to one supplier, until migration costs as much as a rewrite. For Russian projects there is an added availability risk around foreign services that stopped being theoretical several years ago.
Replaceability is a property of how the code is written, not of the technology. One rule carries most of the weight: business logic must not know which framework calls it or which storage sits underneath. Calls to external services hide behind your own interface, data access goes through repositories rather than ORM calls scattered through controllers, the environment is described in Docker and infrastructure files, and the schema lives in migrations rather than in somebody memory. A project built that way swaps any single layer in weeks instead of quarters.
- No third-party SDKs in the domain layer, only behind an interface you own.
- Standard protocols over proprietary ones: SQL, the S3 API, OpenAPI, SMTP.
- The database schema lives in migrations in the repository, not in manual production edits.
- Docker and described infrastructure: a clean deploy should take an hour, not a week.
- Repository, domain, credentials and licences registered to the client from day one.
Frequently asked questions
Can a stack be chosen before the spec is written?
Partly. Before the spec you can fix the solution class: relational storage or not, monolith or services, whether real-time exchange is required. Specific frameworks are better settled once integrations and the load profile are described, because those are what most often cancel an elegant choice. A practical order is one or two weeks of discovery, requirements from that, stack from the requirements. Discovery of that size costs less than one month of development on the wrong stack and nearly always pays for itself in avoided rework.
What should a startup on a tight budget choose?
The most boring one available: PostgreSQL, a single monolithic back end on Django or NestJS, React or Next.js on top, Docker and one VPS. No microservices, no queues, no Kubernetes until load is confirmed. A startup exists to test a hypothesis on minimal money, not to build architecture for a million users who do not exist yet. A boring stack means fast hiring, plenty of ready components and predictable cost, and the move to complex architecture happens later, funded by revenue the product actually earned.
React or Vue for a Russian project in 2026?
If you already have a front-end developer, it is the framework they know, and that is not up for debate. With no team, React is the statistically safer bet: it leads Russian vacancy volume clearly, which makes replacing a departing developer faster and cheaper. Vue wins for a small team with no dedicated architect, because it guides code structure more firmly and tolerates less improvisation. There is no technical reason in 2026 why either of them would fail on a standard commercial project.
How much do data residency rules affect the technology choice?
More than people expect. The requirement to keep personal data of Russian citizens in a database inside the country rules out foreign managed databases and backend-as-a-service platforms for primary storage, and it affects the choice of mail services, analytics systems and external APIs. Technically it rarely changes the language or framework, but it always changes infrastructure and storage architecture. The cheapest approach is designing for it up front: separate personal data from the rest, document where everything lives, and avoid building logic on services that cannot be deployed domestically.
Is it worth changing the stack of a working project?
Only under one of three conditions: the technology physically cannot deliver the functionality you need, maintenance cost has risen high enough to exceed migration cost within twelve to eighteen months, or hiring on the current stack has become impossible. In every other case gradual displacement is cheaper: new modules go on the target stack, old ones stay while they work, and the transition spreads across a year without stopping the product. A full rewrite because the technology feels dated is the most common way to spend an annual development budget with no revenue gain.
Need a hand with this?
We do this work, not just write about it. Describe the task and we will scope it and send a staged estimate.
Related services
- IT consulting and product auditThe most expensive mistakes in software happen before the first line of code: a misread problem, a stack chosen out of a contractor’s habit, and a specification that does not exist. Consulting exists to settle all of that before the development meter starts running: what to build, out of what, at what cost and in which order. The result is a document, not an opinion on a call.
- Web app and Telegram Mini App developmentFor when a site is no longer enough and you need a product: an account area, a dashboard, an internal tool or a Mini App inside Telegram. We design the architecture, write the backend and frontend, and take it to release.
- Website development, end to endWe build sites that still hold up a year later: from a one-page CMS build to a store or a web application on React and Next.js. One team for design, code, integrations and launch.
Read next
- What to Build Your Site On in 2026: Tilda, WordPress, Bitrix or Next.jsBuilder, CMS or custom code is not a matter of taste but of scenario and planning horizon. We break down three-year cost of ownership, the ceiling of each platform, and what it costs to move if you picked wrong.
- Flutter, React Native or Native: Choosing in 2026Choosing between Flutter, React Native and native is a product economics decision, not a technology one. Where cross-platform halves the budget, where it costs more, and what the Russian market constraints change in 2026.
- The Technical Specification: Structure, a Worked Template and the Usual MistakesA specification is not bureaucracy, it is leverage: anything that does not match it gets fixed by the vendor at no charge. Here is the section structure, a filled-in example for a corporate site and how to write acceptance criteria somebody can actually test.