Blog

Why full-stack web development is the future of web applications

By  
Leif Åstrand
Leif Åstrand
·
On Sep 13, 2024 7:35:24 PM
·

Let's set the stage with a cliché: software development is constantly evolving towards ever higher levels of abstraction. We have object-oriented and functional programming built on top of imperative programming on top of assembler on top of machine code. Each new paradigm starts with some rough edges that are gradually refined to a point where it's a solid foundation for the next paradigm. This is also what's been happening with full-stack development for web applications.

Psst... Watch our recent webinar with Leif Åstrand, where we discuss why full-stack development is the future of web applications, and how Vaadin empowers developers to build modern, scalable solutions with ease.

Full-stack development originates from user needs and business needs

15 years ago, the dominant way of building web applications was to generate a full new HTML document on the server for each user interaction. Popular technologies included JSP, PHP, and ASP. It was also becoming increasingly popular to make the user experience more responsive with the help of isolated JavaScript snippets to handle specific interactions. Best practices for these cases were gradually evolving and eventually embodied in libraries like jQuery.

The rise of SPAs

As users got hooked on the snappy interactions, there was a desire to shift more and more towards incremental UI updates rendered in the browser using data fetched from the server. Entire applications were eventually built in that way – the SPA (single-page application) architecture was born.

The first SPAs were built on top of previous-generation tools like jQuery. There weren't yet established best practices for all the new situations that might be encountered, so developers were trying out widely different approaches. Insights gained from these experiments were distilled into in-house frameworks that were further subjected to natural selection and evolution as open-source solutions like React and Angular.

The distributed nature of SPAs

There's still one SPA challenge that is fundamental to the architecture and cannot be fixed with any amount of evolutionary refinement: building a traditional SPA means building a distributed system. There is a client-side application and a server-side application that interact with each other over an asynchronous network connection. Going over the network is inevitable in a web application. However, the overall application structure can still be radically simplified by building a single full-stack application instead of stitching together two separately built applications.

The evolution of full-stack concepts

The full-stack concept is still not a new one. Solutions like Apache Tapestry or Millstone (the precursor to Vaadin Flow) existed over 20 years ago and were updated with "AJAX" support for a SPA-like user experience long before, e.g., Angular or React, were released. What is changing now is that the full-stack concept is going mainstream as developers start to better understand the SPA development trade-offs.

latencies-desktop

Full-stack platform leads to faster time to market and better quality. With full-stack ownership, reduced overhead, and smaller iterations, teams can streamline development for more efficient results.

Full-stack development comes in many flavors

A common characteristic of all types of full-stack development is building a single, unified application rather than two separate ones. In this context, network communication is treated as a cross-cutting concern, best handled by a framework. The network boundary does not signify a separation between applications.

API-first development

An intermediate form between SPA and "full" full-stack development can be seen in API-first development, where you start by declaring the format of all network messages and use that to generate client-side code for sending requests and server-side stubs for handling the requests. This helps keep the two applications in sync with each other. However, the underlying mindset and many practical details are still based on the assumption that two independent applications are talking to each other. 

Code-first full-stack with RPC

This contrasts the code-first way of defining what is sent over the network. These are based on doing remote procedure calls (RPC) over the network rather than designing generic REST-like endpoints. RPC from the client to the server is still not sufficient for a true full-stack approach. You also need integration between the server and the client for other shared concerns like routing and access control. Add a unified build setup and support for bi-directional communication over WebSockets and you have a true full-stack solution like Vaadin's Hilla framework.

Server-side logic and rendering in full-stack

Another full-stack alternative is to also run UI logic and rendering on the server, as seen in frameworks like Next.js or Vaadin Flow. This provides an even simpler programming model but causes additional round-trip delays in some cases and makes true offline use impractical. This is offset by providing an escape hatch to a traditional SPA architecture for cases where it’s needed, while still enabling a true full-stack approach for the rest of the application. HTMX can also be seen as a lightweight variant of this approach.

Full-stack development is like automatic transmission

There's always a limit to how far analogies from the physical world can be applied for software development. However, there's still something to the thought that manually stitching two independent applications together is like driving a car with a manual transmission. Handling the clutch and the stick while driving comes with a learning curve and isn't essential for getting from point A to point B, but it's still something that is taken for granted in many parts of the world.

This is because early automatic transmission technology had compromises in areas like throttle response, fuel economy, and control in special situations. Newer solutions like computer-based control and dual-clutch systems eliminate those compromises and can even surpass the performance of a skilled driver using manual transmission.

Correspondingly, full-stack development has benefitted not only from new technologies such as TypeScript and React Server Components but also from a growing awareness of the complexity caused by building two separate applications. Another aspect of the analogy is how full-stack frameworks often allow you to regain complete control, similar to how some automatic transmissions offer manual gear selection, even though the shifting remains automatic.

Full-stack development allows developers to focus on business problems

The immediate benefit of automatic network communication is that it reduces the time spent writing boilerplate code and keeping data types in sync between two separate code bases. It also reduces the risk of bugs due to inconsistencies and the overhead of designing endpoint APIs with forward compatibility in mind. The full-stack nature makes it possible for reusable frameworks to help the developer with things like routing and real-time collaboration that spans both sides of the network boundary.

A full-stack unified approach streamlines the process by removing the bottlenecks and delays found in the decoupled method, where frontend and backend teams work separately.

A full-stack unified approach streamlines the process by removing the bottlenecks and delays found in the decoupled method, where frontend and backend teams work separately.

The most fundamental benefit is, however, that a single developer can add a new end-to-end feature in a single commit. There's no need to coordinate work across multiple teams and multiple code repositories. Full-stack development means that development is organized to let developers solve business problems rather than spending their time on technicalities or coordinating with other teams.

Yet again, there’s an even more fundamental benefit beyond simply avoiding wasted effort. Building an entire feature as a single commit means significantly less time is spent waiting for the next step to reach the top of the backlog for the next team. There's less multi-tasking while waiting for others, and features can be built in days rather than weeks. This shorter lead time allows the business to react more quickly to new insights. The improved lead time also provides more opportunities to gather feedback and iterate on the solution, ultimately leading to better quality for the end user.

Full-stack development is to web UI development what the majestic monolith is to backend development. It's empowering developers to be more productive.

Full-stack development is not a silver bullet

…because silver bullets do not exist in software engineering. 

Supporting third-party clients

One common objection to a full-stack mindset arises when the application needs to support third-party clients, which in turn means a generic, reusable API is required. The solution is often to adopt a Backends For Frontends approach, allowing the web application to remain full-stack with its own embedded communication layer.

Not every application needs full-stack

Another case is that not everything on the web needs the rich, SPA-like interactions provided by a full-stack application framework or a traditional SPA approach. While full-stack is simpler than SPA, thanks to having only a single application, there are also simpler alternatives, such as static server-side templates or static site generators, for cases where the focus is on content rather than interaction.

Offline support requires separate applications

Going in the opposite direction, full offline support often requires an architecture with two separate applications. Offline support also means that the backend may have been upgraded while the user was disconnected, making an explicitly defined endpoint API beneficial. This helps manage forward compatibility, ensuring the old client version can communicate with the new server version.

Enthusiasts and niche use cases

Finally, there's the case of enthusiasts. To continue with the car analogy, there will always be those who enjoy the feeling and maybe nostalgia of driving a car with old technology. Concerns like practicality or fuel economy are not important for them. But that's a hobby for their free time rather than a solid foundation for a viable freight business.

Full-stack is the future of web application development

As we have seen, the concept of full-stack development builds on top of the great user experience offered by SPAs. It removes the fundamental complexities caused by building and maintaining two separate applications. This helps developers use their time more productively while enabling businesses to deliver higher-quality products with greater agility.

Although full-stack development is not always the best option, it is often very well-suited for web application development, much like how high-level programming languages such as Java or C# have replaced C or COBOL for business applications.

Learn more about Vaadin's full-stack approach in a recent webinar: 'Why Full-Stack is the Future of Web Application Development.'

Leif Åstrand
Leif Åstrand
Leif Åstrand keeps an eye on the overall architecture of the Vaadin platform. He knows a thing or two about how Vaadin, Web Components, and the internet works.
Other posts by Leif Åstrand