6. Modern stacks: how we put everything together
At this point we can finally talk about stacks.
A stack is simply the concrete combination of languages, libraries, frameworks, databases, services and infrastructure used to build a product.
Let's look at a few stacks representing some of the main philosophies of contemporary Web development.
React + Node.js + PostgreSQL
This is one of the easiest stacks to understand because it clearly separates frontend and backend while keeping JavaScript throughout the application.
React
↓
Node.js
↓
Express / Fastify / NestJS
↓
PostgreSQL
React manages the interface in the browser, Node.js executes JavaScript on the server and PostgreSQL stores the data.
When to choose it: custom Web applications, dashboards, SaaS products, digital products and systems where frontend and backend need to evolve relatively independently.
Strengths: a single JavaScript/TypeScript ecosystem, enormous availability of libraries, clear architecture and great flexibility.
Limitations: many decisions remain with the team. Routing, backend framework, authentication, deployment, caching and many other components need to be selected separately.
Philosophy: build the stack by freely composing its individual pieces.
Next.js + PostgreSQL / Supabase + Vercel
This stack represents the modern tendency to reunify frontend and backend within the same project.
Next.js
↓
React
+
Server Components
+
API / server logic
↓
PostgreSQL / Supabase
↓
Vercel
Next.js determines which parts should run in the browser and which should run on the server. Supabase can provide database, authentication, storage and realtime capabilities, while Vercel manages much of the infrastructure.
When to choose it: SaaS, startups, modern ecommerce, digital products, MVPs and applications developed by small or medium-sized teams.
Strengths: rapid development, excellent frontend/backend integration, very simple deployment and the enormous React ecosystem.
Limitations: an increasing amount of the architecture is delegated to the framework and platforms; caching, rendering and client/server boundaries can become complex.
Philosophy: reduce the amount of infrastructure that needs to be built manually.
Angular + NestJS + PostgreSQL
This is a much more structured stack.
Angular
↓
NestJS
↓
PostgreSQL
Angular governs the frontend, NestJS the backend, and both use TypeScript with similar concepts such as modules, dependency injection and services.
When to choose it: large enterprise applications, large teams and software expected to be maintained for many years.
Strengths: strong architectural consistency, end-to-end TypeScript, clear conventions and good organisational scalability.
Limitations: more structure and boilerplate, a steeper learning curve and excessive complexity for simple applications.
Philosophy: reduce individual architectural decisions through strong conventions.
Laravel + MySQL/PostgreSQL + React, Vue or Livewire
Laravel represents a different philosophy: the backend is the centre of the application.
Laravel
↓
business logic
↓
MySQL / PostgreSQL
+
React / Vue / Livewire
Authentication, database access, queues, email, jobs, APIs and much of the application logic can all be managed within the same framework.
The frontend can be traditional, built with React or Vue, or use tools such as Livewire to add interactivity while keeping most of the logic on the server.
When to choose it: management systems, ecommerce, portals, CRMs, business applications and systems where logic and data matter more than frontend complexity.
Strengths: enormous productivity, many integrated features, very mature ecosystem and an excellent balance between simplicity and power.
Limitations: less natural for extremely distributed systems or applications where the frontend itself constitutes almost the entire product.
Philosophy: keep the backend as the stable centre of the application.
React + FastAPI / Django + PostgreSQL
This stack becomes particularly interesting when the application intersects with Python, data or AI.
React
↓
FastAPI / Django
↓
Python
↓
PostgreSQL
+
AI / data services
The frontend remains independent, while Python handles APIs, data processing, machine learning and integrations with AI models.
FastAPI is particularly suitable for services and microservices, while Django provides a more complete application platform.
When to choose it: AI applications, data-driven systems, analytics, scientific platforms and products that make intensive use of the Python ecosystem.
Strengths: direct access to the AI/data ecosystem, highly flexible backend, clear separation between frontend and intelligent services.
Limitations: introduces two different ecosystems — JavaScript and Python — requiring separate skills and deployment processes.
Philosophy: choose the best language for each part of the problem.
Astro + Headless CMS + CDN
This stack starts from a principle almost opposite to that of large Single Page Applications:
if a page does not need JavaScript, do not send it JavaScript.
Astro
↓
server-generated HTML
↓
Headless CMS
↓
CDN
Sections requiring interactivity can be turned into small React, Vue or Svelte islands.
When to choose it: editorial websites, magazines, corporate sites, documentation, blogs and projects with a strong focus on SEO and performance.
Strengths: very little client-side JavaScript, high performance and the ability to use components from different ecosystems.
Limitations: less natural for applications where almost the entire experience depends on state and client-side interaction.
Philosophy: send the browser only what it genuinely needs.
WordPress / WooCommerce
WordPress remains a very particular case because it integrates within a single ecosystem many parts that modern stacks often separate.
PHP
+
WordPress
+
MySQL
+
CMS
+
plugins
+
theme
+
admin
With WooCommerce it adds catalogue management, cart, orders, payments and ecommerce management.
When to choose it: editorial websites, corporate sites, traditional ecommerce and projects where autonomous content management and a large plugin ecosystem are important.
Strengths: rapid development, enormous ecosystem, complete CMS and huge availability of plugins and expertise.
Limitations: accumulating plugins and customisations can create performance, security and maintenance problems if the architecture is not carefully governed.
Philosophy: start from an already complete platform and customise it.
There is no best stack
At this point, it should be clear why asking what the “best stack” is does not make much sense.
For a startup with two developers, the ideal choice might be:
Next.js + Supabase + Vercel
For an internal business application:
Laravel + PostgreSQL
For an AI platform:
React + FastAPI + PostgreSQL
For a large enterprise application:
Angular + NestJS
For a magazine:
Astro + CMS + CDN
For an editorial ecommerce project:
WordPress + WooCommerce
Choosing a stack is therefore primarily about deciding where we want complexity to live.
We can build every component internally or delegate part of it to frameworks and services. We can prioritise flexibility or conventions, development speed or control, operational simplicity or maximum customisation.
Modern Web development is no longer simply about choosing a programming language.
It is about composing a system of technologies that work together, consciously deciding which parts we want to control and which we are willing to delegate.

1. Languages: what we use to write software
A programming language is the formal system we use to describe data, rules, operations and behaviours to a machine. It is not the website, the framework or the stack itself: it is simply the raw material we use to write software.
On the Web, we should also distinguish HTML and CSS. They are fundamental languages, but they are not programming languages in the strict sense. HTML describes the structure of a page, while CSS describes its appearance. Application logic is instead built using languages such as JavaScript, PHP, Python, Java or Go.
JavaScript
JavaScript is the native language of the modern Web and the only programming language executed directly by all major browsers.
It was originally a client-side language, but with Node.js it can also be used on the server. This allows JavaScript to cover practically the entire stack.
When to choose it: it is almost unavoidable when an application requires browser interactivity, and it is particularly convenient when you want to maintain the same technological ecosystem across frontend and backend.
Strengths: enormous ecosystem, universal adoption, huge availability of libraries and frameworks.
Limitations: its flexibility can result in codebases that become difficult to maintain if a project grows without a clear architecture.
TypeScript
TypeScript is an extension of JavaScript developed by Microsoft that primarily adds a static type system. TypeScript code is then transformed into JavaScript before execution.
It allows many errors to be detected during development and makes complex projects more readable and predictable.
When to choose it: practically always for medium and large JavaScript projects, especially when several developers work on the same codebase.
Today, it often makes more sense to think of JavaScript as the execution language and TypeScript as the language in which the application is actually developed.
PHP
PHP was created specifically to generate Web pages on the server side and is still one of the most widely used languages on the Internet.
It is the language behind WordPress, WooCommerce and modern frameworks such as Laravel.
When to choose it: CMSs, ecommerce, business applications, websites with a strong server-side component, and projects where simple hosting and a mature ecosystem are important.
Strengths: enormous adoption, straightforward deployment, mature Web ecosystem.
Limitations: it still carries a reputation inherited from old procedural PHP, which is quite different from modern PHP used with structured frameworks.
Python
Python is a general-purpose language known for its readability and simple syntax.
On the Web it is mainly used on the server side through frameworks such as Django, Flask and FastAPI, but its ecosystem has become particularly important thanks to data science, machine learning and AI.
When to choose it: applications that need strong integration between backend, data, automation, machine learning or AI services.
Strengths: readability, rapid development, and a scientific and AI ecosystem that is difficult to match.
Limitations: it is not normally the first choice when raw computational performance is the primary requirement.
Java
Java is one of the most widely used languages in enterprise systems. It is strongly typed, mature and built around an extremely stable ecosystem.
On the Web it is mainly used on the backend, often with frameworks such as Spring Boot.
When to choose it: large organisations, banking, insurance and administrative systems, applications involving many developers, and projects with strict stability and maintenance requirements.
Strengths: robustness, tooling, enterprise ecosystem and the ability to support very large projects.
Limitations: greater verbosity and complexity compared with languages designed around faster development.
C#
C# occupies a role similar to Java within the Microsoft ecosystem. With .NET it is used for Web backends, APIs, enterprise applications, cloud services and desktop software.
When to choose it: organisations already integrated into the Microsoft ecosystem, Azure infrastructures and enterprise applications.
It is a modern, strongly typed and very mature language, although less common in independent Web development than JavaScript, PHP or Python.
Go
Go was developed by Google with a very specific goal: building software that is simple, fast and well suited to concurrent and distributed systems.
It produces highly efficient native executables and has become particularly popular for APIs, microservices and cloud infrastructure.
When to choose it: high-performance backends, APIs, distributed services and systems that need to handle many concurrent requests.
Strengths: simplicity, speed, concurrency and very clean deployment.
Limitations: a smaller application ecosystem than JavaScript, Python or PHP for traditional Web products.
Ruby
Ruby is a highly expressive language that became famous primarily through Ruby on Rails.
Rails played a major role in the evolution of modern Web application development, introducing and popularising concepts such as convention over configuration and a strong focus on developer productivity.
When to choose it: SaaS products, business applications and projects where development speed matters more than extreme performance optimisation.
It is less dominant today than it was in the 2000s and 2010s, but it remains a mature and highly productive ecosystem.
Rust
Rust is a relatively newer language designed to deliver performance comparable to C and C++ while maintaining a very high level of memory safety.
On the Web it is not normally used to build an entire application, but it has found a place in infrastructure, high-performance services, tooling and WebAssembly.
When to choose it: components where security, performance and resource control are fundamental requirements.
It is extremely powerful, but its learning curve is steeper than that of most of the other languages mentioned here.
So which language should you choose?
There is no single best language. There is a language that is better suited to the problem we need to solve.
For a general-purpose Web application, JavaScript/TypeScript is currently the most versatile choice. PHP remains highly effective for CMSs such as WordPress, ecommerce and traditional Web applications; Python becomes particularly attractive when the product intersects with data and AI; Java and C# dominate many enterprise scenarios; while Go and Rust become increasingly valuable when performance, infrastructure and scalability are central requirements.
Choosing a language therefore determines not only the syntax we will use to write the code, but also the ecosystem of libraries, frameworks, developers and tools within which we will build the application.
2. Client and server: where the code lives
After choosing a language, the second question is: where will that code be executed?
In the traditional Web, the fundamental distinction has always been between client and server.
The client is the device or program making a request. In the most common case, it is the user's browser.
The server is the remote system that receives the request, executes the necessary logic, possibly queries a database or other services, and returns a response.
The simplest flow looks like this:
CLIENT / BROWSER
|
| HTTP request
↓
SERVER
|
| application logic
↓
DATABASE
|
↑
| response
|
CLIENT / BROWSER
This architecture is still at the core of most modern Web applications.

Are client/server and frontend/backend the same thing?
Not exactly, although in the traditional Web they often overlap. Client and server describe a technical relationship: who makes a request and who receives it.
Frontend and backend describe the roles of different parts of the application.
The frontend is the part the user interacts with: interface, buttons, forms, navigation and dynamic content updates.
The backend contains application logic, authentication, data management, integrations, processes and operations that are not normally executed directly on the user's device.
In the simplest model:
FRONTEND = CLIENT
BACKEND = SERVER
but in modern applications this equivalence is no longer always perfect.
3. Libraries: code we borrow
Once we have chosen the language, we need to understand which tools we want to add so that we do not have to build everything from scratch.
A library is essentially a collection of functions, components or tools that have already been written and that our program can use whenever it needs them.
The important conceptual difference is this:
with a library, we decide when and how to use that code.
The library enters our project, but it does not necessarily determine how the entire application must be organised.
Let's look at some of the main libraries used in modern Web development.

React
React is probably the most important example in the modern Web. Technically, it is a JavaScript library for building user interfaces through components.
A component can represent a button, a card, a menu, a form or an entire section of an application.
React keeps track of the state of the interface and updates what needs to change when the data changes. This represents an important change of perspective: instead of constantly telling the browser how to modify the page, we describe what the page should look like given a particular state.
When to choose it: highly interactive Web applications, dashboards, SaaS products, digital products and complex interfaces.
Strengths: enormous ecosystem, componentisation, code reuse, huge availability of developers and tools.
Limitations: precisely because it leaves many decisions open, a React project can require several additional libraries and become architecturally disorganised if it is not designed carefully.
SolidJS
SolidJS is a JavaScript library for building reactive user interfaces using components and JSX.
At first glance it can resemble React, but it uses a different update model: instead of re-running a component whenever state changes, it applies fine-grained reactivity, directly updating only the values and interface elements that depend on the modified data.
This makes it possible to build highly dynamic interfaces while reducing the work required to keep them synchronised.
When to choose it: highly interactive Web applications, dashboards, real-time tools and interfaces where many small values change frequently.
Strengths: highly granular updates, excellent performance, JSX syntax that feels familiar to React developers, low overhead.
Limitations: its ecosystem, community and availability of components and developers are considerably smaller than React's.
Lit
Lit is a JavaScript library for building reactive Web Components based on native browser standards.
It makes it possible to create custom HTML elements such as:
which can be used independently of the architecture of the application hosting them.
A Lit component can therefore live inside React, Angular, Vue, a CMS or a traditional HTML page without being tied to a specific framework.
When to choose it: design systems, embeddable widgets and components that need to be shared across applications built with different technologies.
Strengths: interoperability, low weight, use of Web standards, independence from the framework hosting the component.
Limitations: it is particularly effective for building reusable components, but provides less structure than tools designed to govern an entire complex application.
Alpine.js
Alpine.js is a minimal JavaScript library for adding dynamic behaviour directly to HTML.
Through attributes such as x-data, x-show, x-model or @click, it allows state and interactions to be managed without necessarily turning the page into a Single Page Application.
HTML therefore remains at the centre of the interface, while JavaScript is added only where dynamic behaviour is required.
When to choose it: server-rendered sites and applications that need menus, modals, dropdowns, tabs, filters, dynamic forms and other limited interactions.
Strengths: extreme simplicity, very little JavaScript, natural integration with PHP, Laravel, CMSs and server-generated pages.
Limitations: as state and client-side interaction become more complex, it becomes less suitable than libraries or frameworks designed for sophisticated frontend applications.
Other libraries that do specific things
TanStack Query
Manages fetching, caching and synchronisation of data coming from the server.
Zod
Allows us to define and validate data structures.
Three.js
Simplifies the creation of 3D graphics and scenes in the browser using WebGL.
D3.js
Provides advanced tools for building data visualisations.
Axios
Simplifies HTTP requests to APIs and external services.
Zustand
Manages shared state inside React applications.
In all these cases, the same principle applies:
our program uses a specific capability provided by the library without necessarily handing over control of the entire architecture.
A library is a building block
We can imagine an application as a construction assembled from several different pieces:
JavaScript / TypeScript
↓
React
+
TanStack Query
+
Zod
+
Three.js
+
other libraries
Each library solves a specific problem.
This approach gives us enormous freedom because we can choose the components best suited to the project. But that same freedom also introduces responsibility: someone has to decide how all those pieces should fit together.
And this is precisely where frameworks enter the picture.
4. Frameworks: when we also choose a structure
If a library provides tools that we can combine freely, a framework does something more: it also proposes a structure within which the application should be built.
The distinction is not always perfectly clear, but the general principle is:
with a library, we decide when to call it; with a framework, we also accept the way in which the project is expected to be organised.
Routing, data management, folder conventions, rendering, server communication, build processes and deployment may therefore already be defined or supported by the framework.
This reduces freedom, but it also eliminates many architectural decisions that we would otherwise have to make ourselves.

Angular
Angular is a complete frontend framework developed by Google and based on TypeScript, designed for building large, structured Web applications.
It already includes components, routing, forms, dependency injection, HTTP communication and numerous tools for organising the project.
Unlike React, it does not merely provide a system for building the interface: it proposes a much more clearly defined application architecture.
When to choose it: enterprise applications, large teams, projects expected to grow for many years and environments where consistency and structure are more important than architectural freedom.
Strengths: complete ecosystem, native TypeScript, strong conventions, excellent support for large codebases and large teams.
Limitations: greater initial complexity, more concepts to learn and a structure that can be excessive for simple applications.
Vue
Vue is a progressive JavaScript framework for building interfaces and Web applications.
It can be adopted gradually, starting from a small interactive section of a page and growing into a complete Single Page Application.
It provides a component system and highly accessible reactivity while generally imposing less rigidity than Angular.
When to choose it: small and medium-sized Web applications and teams looking for a good balance between simplicity, structure and room to grow.
Strengths: relatively gentle learning curve, readable syntax, excellent reactivity, mature ecosystem.
Limitations: a smaller ecosystem and job market than React and, in some enterprise contexts, less standardisation than Angular.
Svelte
Svelte is a framework for building reactive interfaces that moves a significant amount of work from runtime to compilation time.
Frameworks such as React keep a significant portion of the logic required to manage the interface in the browser. Svelte instead tries to transform components during the build process into more direct and lightweight JavaScript.
When to choose it: modern applications where code simplicity, frontend weight and performance are particularly important.
Strengths: very compact syntax, little complexity exposed to the developer, generally small bundles and an intuitive reactive model.
Limitations: its ecosystem and availability of developers are still smaller than React, Vue or Angular.
Full-stack frameworks
An important part of modern development has moved beyond the traditional distinction between “frontend framework” and “backend framework”.
Frameworks such as Next.js can decide which code should run in the browser and which should run on the server, managing both within the same project.
Next.js
Next.js is a full-stack framework based on React.
It adds routing, server-side rendering, static generation, Server Components, APIs, caching and numerous tools for building and deploying a complete application.
A component can therefore be rendered either in the browser or on the server depending on the requirements.
When to choose it: SaaS, ecommerce, modern Web applications, digital products and React projects requiring server-side rendering, SEO or integrated backend logic.
Strengths: enormous React ecosystem, ability to manage frontend and backend within the same project, multiple rendering strategies and excellent integration with serverless infrastructure.
Limitations: as its feature set has grown, the framework has become significantly more complex; caching, Server Components and the client/server boundary require a good understanding of the underlying architecture.
Nuxt
Nuxt plays a role in the Vue ecosystem similar to the one Next.js plays for React.
It is a full-stack framework based on Vue that integrates routing, server-side rendering, static generation, APIs and application management.
When to choose it: when Vue is preferred but you want to build a complete product with integrated frontend and server logic.
Strengths: highly polished developer experience, clear structure, simplicity of the Vue ecosystem and support for different rendering models.
Limitations: a smaller overall ecosystem compared with the React/Next.js combination.
SvelteKit
SvelteKit is the full-stack application framework of the Svelte ecosystem.
It manages routing, server-side rendering, APIs, data loading and deployment while preserving Svelte's philosophy of simplicity and reducing the amount of JavaScript sent to the browser.
When to choose it: modern full-stack applications when you want to use Svelte beyond the interface layer alone.
Strengths: compact code, good performance and a coherent full-stack model.
Limitations: smaller ecosystem and fewer available integrations and skills compared with Next.js.
Astro
Astro is a Web framework primarily designed for content-heavy websites and performance, built around a server-first philosophy.
By default, it generates HTML and sends JavaScript to the browser only for the parts that genuinely require interactivity, using the islands model.
One interesting feature is that it can also use components from different ecosystems such as React, Vue or Svelte.
When to choose it: editorial sites, corporate websites, blogs, documentation, landing pages and projects where SEO, speed and minimal browser-side JavaScript are priorities.
Strengths: performance, HTML-first approach, Islands Architecture and the ability to combine components from different frameworks.
Limitations: less natural for applications where almost the entire experience depends on complex client-side state.
Backend frameworks
A framework can, of course, also live exclusively on the server.
Laravel
Laravel is a complete PHP framework for building Web applications and APIs.
It provides routing, database access, authentication, queues, caching, email, jobs and many other tools out of the box.
When to choose it: business applications, management software, ecommerce, APIs and systems where server-side logic is at the core of the product.
Strengths: enormous productivity, mature ecosystem, many integrated features and relatively simple deployment.
Limitations: less natural when the application is built around a highly distributed architecture or very specific computational requirements.
Django
Django is a complete Python Web framework built around a “batteries included” philosophy.
It integrates an ORM, routing, authentication, security and even a powerful automatically generated administration panel.
When to choose it: data-driven applications, administrative platforms, complex Web products and systems that need to integrate with the Python ecosystem.
Strengths: maturity, security, rapid development of complete applications and natural integration with Python.
Limitations: it can be more structured than necessary when all that is required is a small API.
FastAPI
FastAPI is a modern Python framework focused on building APIs.
It makes extensive use of Python's type system, automatically generates API documentation and is particularly common in services exposing machine-learning and AI models.
When to choose it: microservices, APIs, backends for AI applications and Python services that need to communicate with frontends or other systems.
Strengths: simplicity, performance, typing, automatic documentation and natural integration with the Python AI ecosystem.
Limitations: it provides fewer ready-made application features than complete frameworks such as Django or Laravel.
NestJS
NestJS is a highly structured backend framework for Node.js and TypeScript, partially inspired by Angular's architectural principles.
It introduces modules, controllers, services and dependency injection to organise large JavaScript backends.
When to choose it: complex Node.js backends, large teams and applications where TypeScript is used throughout the stack without sacrificing a rigorous structure.
Strengths: clear architecture, TypeScript, dependency injection and excellent support for large codebases.
Limitations: it can introduce more structure and abstraction than necessary for simple APIs.
Choosing a framework therefore involves something deeper than the simple availability of functions.
It means deciding how many architectural decisions we want to make ourselves and how many we prefer to delegate to the tool.
5. Databases, services and infrastructure
A Web application does not live on frontend and backend alone.
It also needs to store data, authenticate users, manage files, send emails, run jobs, serve content quickly and remain available in production.
This is where databases, external services and infrastructure come into play.

Relational databases
Relational databases organise data into tables connected to one another and are normally queried using SQL.
The two most important names in modern Web development are PostgreSQL and MySQL.
PostgreSQL
PostgreSQL is a highly capable open-source relational database with strong support for transactions, advanced data types, JSON, extensions, search and geographic operations.
When to choose it: custom applications, SaaS, complex systems, data-driven products and projects where the database needs to grow together with the application.
Strengths: robustness, SQL standards compliance, great extensibility and an excellent balance between relational data and more flexible structures.
Limitations: it can be excessive for extremely simple projects.
MySQL
MySQL is one of the most widely used databases on the Web and is historically closely associated with the PHP ecosystem.
It powers a huge number of CMSs and applications, including WordPress and WooCommerce.
When to choose it: CMSs, ecommerce, traditional Web applications and infrastructures where compatibility and ease of management are priorities.
Strengths: enormous adoption, hosting available virtually everywhere, mature ecosystem.
Limitations: PostgreSQL now tends to provide more advanced functionality in many application scenarios.
NoSQL databases
Not all data necessarily has a relational structure.
Databases such as MongoDB store JSON-like documents rather than rows and tables.
When to choose them: highly flexible data, frequently changing structures, complex documents or systems where a relational model would be artificially rigid.
The advantage is flexibility; the risk is abandoning the structure and guarantees provided by relational databases too early.
For many modern applications, PostgreSQL with JSON support can already cover a significant proportion of the use cases that might once have automatically led to a document database.
Cache and temporary data
Not everything needs to be continuously read from the primary database.
Redis is commonly used for caching, sessions, queues, rate limiting and temporary data requiring very fast access.
The idea is simple:
if the same response is requested thousands of times, there is not always a reason to recalculate it or retrieve it from the main database every time.
Search and vector databases
When an application needs to search through large quantities of text or documents, specialised engines can be useful.
Elasticsearch / OpenSearch are designed for full-text search, indexing and analytics.
In the AI world, vector databases have become increasingly common. They allow embeddings to be stored and content to be retrieved according to semantic similarity.
Tools such as Pinecone, Weaviate, Qdrant, or extensions such as pgvector for PostgreSQL, are used, for example, in RAG systems.
This does not mean that every AI application needs a separate vector database: PostgreSQL + pgvector is often already sufficient.
Services: functionality we no longer build from scratch
One of the most important changes in modern development is that many capabilities are now purchased or integrated as services.
An application might use:
Stripe → payments
Auth0 / Clerk → authentication
SendGrid / Resend → email
Cloudinary → images and media
Algolia → search
Sentry → error monitoring
Supabase → database, authentication, storage, realtime
Firebase → database, authentication, hosting and application services
Instead of building every component internally:
payments
authentication
email
storage
search
analytics
we can compose specialised services through APIs.
This dramatically reduces development time, but introduces a new dependency:
less code to maintain internally, greater dependence on external platforms.
This is one of the fundamental trade-offs of modern development.
Backend-as-a-Service
Tools such as Supabase and Firebase take this approach even further.
Instead of building a complete backend, they provide many of its components directly:
database
+
authentication
+
storage
+
API
+
realtime
+
server functions
In some projects it is therefore possible to build:
React / Next.js
↓
Supabase
without writing a complete traditional backend.
When to choose them: MVPs, SaaS products, digital products, real-time applications and small teams that want to reduce the number of components they have to manage.
Strengths: rapid development, many integrated capabilities, reduced operational complexity.
Limitations: greater platform dependency and less control over the underlying architecture.
Infrastructure: where all this actually runs
At this point, the software needs to go online.
In the traditional model we had a server:
Internet
↓
Apache / Nginx
↓
PHP / Java / Python
↓
Database
Today there are many more possibilities.
VPS and traditional servers
A virtual machine on which we directly install the operating system, Web server, runtime and database.
When to choose it: when we want control, predictable costs and a relatively simple architecture.
Containers and Docker
Docker makes it possible to package an application and its dependencies inside a reproducible environment.
The same container can run on the developer's computer, in staging or in production.
When to choose it: teams, microservices, complex environments and reproducible deployments.
Serverless
With serverless computing, we do not directly manage the server. We upload a function and the platform executes it when required.
Examples:
AWS Lambda
Vercel Functions
Cloudflare Workers
Google Cloud Functions
When to choose it: lightweight APIs, webhooks, intermittent jobs and applications with variable traffic.
Strengths: automatic scaling and very little infrastructure to manage.
Limitations: less control, possible runtime restrictions and less predictable costs at high volume.
Edge
Edge computing moves part of the execution geographically closer to the user.
Instead of sending every request to a single central server:
user in Italy
↓
server in the USA
part of the code can run on distributed nodes:
user
↓
nearby edge node
When to choose it: lightweight authentication, personalisation, routing, caching, very fast APIs and global applications.
CDN
A Content Delivery Network distributes copies of static files — images, CSS, JavaScript and video — across geographically distributed servers.
Users can therefore receive the content from the node closest to them.
Today, services such as Cloudflare, Fastly or the CDNs integrated into Vercel and other providers have become an almost invisible but fundamental part of Web infrastructure.
The modern stack is increasingly compositional
The difference from the traditional Web becomes clear.
We once might have had:
PHP
+
MySQL
+
Apache
+
one server
Today we might have:
Next.js
+
PostgreSQL
+
Supabase Auth
+
Stripe
+
Cloudinary
+
OpenAI API
+
Vercel
+
Cloudflare
The advantage is enormous: we can build highly sophisticated products using extremely specialised services.
But the developer's job changes as well.
Less and less time is spent building every individual component from scratch, while more and more time is spent selecting, integrating and correctly orchestrating different systems.
And this final combination of languages, runtimes, libraries, frameworks, databases, services and infrastructure is what we call a stack.

I have worked on digital marketing since 2005, when we were still looking for music on Napster. I am a data-driven specialist, my job is to bring qualified traffic to websites. I have a degree with honors in comparative economic systems and a very nice computer. I smoke little and sometimes I run.
Request info