Cover image: A sketch of primate origins from Charles Darwin's notebook, dated 21 April 1868
The Third Age of web developments is the period that follows the Second Browser War, after Microsoft Internet Explorer lost its dominance on the web browser market (2012-today).
On the frontend, the Modernist SPA was still king, however the shortcomings of this model became more and more apparent as it rose to domination: SPAs make client-side scripting a strong requirement, they have to download large assets at startup, display the dreaded "White Screen of Death" to slower or older Web clients, don’t allow deep linking, can’t be indexed by search engines, and are often too resource-hungry for low-end terminals such as mobile phones or smart TVs, let alone outdated browsers on non-upgradable systems. Simply put, the basic principles of the SPA model are in direct contradiction with the core philosophy of the web: Graceful Degradation.
The Postmodernist period also saw the rise of the mobile web. When Apple released the first iPhone in 2007 with its WebKit-based mobile Safari browser, mobile Web usage was marginal. In 2015, as mobile Web browsers rose to 30% of the market, Google announced the "Mobilegeddon", a major revision of its ranking algorithm to favor mobile-friendly sites with new metrics based on ergonomics and performances. Performance audits became the daily life of Web developers where Time-To-Interactive (TTI) is a matter of life and death on the race to the top pages of Google Search results.
Faced with this new reality, frontend frameworks started to introduce performance improvements such as Ahead-of-Time compilation (AoT), brought back the good old SSR model of past periods with a reversal of workflow and a bit of rebranding (for example Angular Universal is SSR for Angular components), and reinvented techniques that had been available since the dawn of the Web: lazy loading and code splitting are features that plain Web pages get for free but for which SPAs require explicit design. Web development went full-circle, old is the new new, only more complex.
The mobile revolution also had a major impact on backend architecture. The monolithic backend of previous periods struggled to scale under the massive traffic induced by new mobile applications. Microservice architectures split the monolith into separate processes with fine-grained responsibilities, distributed over large clusters or cloud services and orchestrated with dedicated middleware. And web clients rely more and more on third-party services for social authentication or web-native databases such as Firebase.
- Google Lighthouse
- Spring Boot
- Amazon Web Services
- Google Cloud Platform
- Microsoft Azure
- Visual Studio Code
Postmodernist Web applications are engineered to scale under massive traffic and from a wide range of clients, building on the Modernist Web model while addressing its shortcomings.
Postmodernist Web clients focus on improving user-centric metrics such as Time-To-Interactive (TTI), especially on low-end devices, by implementing techniques such as Ahead-of-Time compilation (AoT). Application code uses non-imperative paradigms such as functional and reactive programming. Build tools also add metrics and budgets to limit the weight of bundled assets for low-bandwidth mobile clients, and other techniques such as lazy loading and code splitting help further reduce initial page load times. Service workers help download and cache assets in the background for offline use.
On the server side, Postmodernist Web frameworks reintroduce some of the Classical Web techniques for better SEO and discoverability, such as Server-Side Rendering (SSR). Many responsibilities of traditional web servers are delegated to separate services: Content Delivery Networks (CDNs) for static web assets, Single Sign-On servers (SSO) for authentication, etc. These services can be co-located with the backend or provided by third-parties. The backend itself can be split into microservices for asymmetric scalability between application subdomains. Complexity shifts from applicative code to service orchestration and infrastructure.
Core value: scalability
- Frontend frameworks with SSR support and integrated toolchains
- Mobile-friendly SPAs with compile-time optimizations
- OAuth-based login
- Web services with token-based authentication such as JWT
- Modular, distributed backends with orchestration middlewares
On the opposite side of the web development industry, new solutions began to emerge in the early 2000’s with the promise of a return to the past simplicity of the Web. Like the Classical period, the Neoclassical period is centered around content creation, whereas the Modernist and Postmodernist periods were focused on application development. Blogs became the major support of this revival: from a handful of blogs at the acquisition of the Blogger platform in 2003, the Blogosphere grew exponentially with hundreds of millions of blogs and millions of articles posted everyday. In parallel, Content Management Systems (CMS) such as WordPress and Drupal were increasingly used to power web sites. In 2020, roughly one out of three websites runs WordPress.
The Neoclassical period is a return to the original vision of the web, where the web browser served both as a client and an authoring tool. Web content creation should be accessible to anyone and not restricted to professional developers. Additional features should be easy to add. Third-party libraries should be easy to integrate. Tools should be simple to use and easy to understand. Frameworks should not be over-engineered for general-purpose application development, but should concentrate on specific goals and features. The build process and its output should be transparent and controllable. Backends and web services should only be used when required. Websites should gracefully degrade.
Launched in 2008, Jekyll was the first modern Static Site Generator (SSG) that combined the old principles of web asset generation with modern techniques and toolings. With a bunch of Markdown files (a text format much easier to author than HTML), one could generate a complete, modern, nice-looking website with almost no effort from a stock or custom template, and host it on cheap static hosting services such as Netlify. The templates were easy to modify to fit one’s tastes, add new features, or integrate third-party services such as comment systems. Web developers could use their skills to write their own templates and turn their SSG blog into a professional portfolio. Soon other tools followed: basic SSGs such as Hugo and Eleventy use a Jekyll-like model, whereas advanced SSGs such as Gatsby, Next.js or VuePress bridge the gap between SPA frameworks and CMS by generating dynamic sites from static content. Once a developer tool with command-line interfaces and Git workflow, SSGs are now full publishing chains with continuous delivery from the source content repository to the hosting service. Online one-click installs and CMS-like editors push the model even further.
On the server-side, the rise of cloud computing led to the emergence of the Function as a Service model (FaaS), also known as Serverless computing. Opened in 2014, AWS Lambda became the first generally-available FaaS service with pay-as-you-go billing, autoscaling, and support for multiple runtime environments. AWS Lambda defined a backend architecture model, with monolithic or even microservice server processes being split into stateless, short-lived functions that could scale independently. The Serverless model soon became a cheap and easy way to enrich static sites with server-side code.
The Neoclassical Web is centered on content creation. It does not reject modern tools and techniques but makes an enlightened and parsimonious use of them. It also acknowledges the new reality of the web ecosystem with the ubiquity of mobile web clients and the exponential growth of web traffic. To do so, it embraces the static web page model where web assets are either authored directly or produced by Static Site Generators (SSG) from templates and raw content files (such as Markdown files for example), before being stored on a static HTTP server or a Content Delivery Network (CDN). When needed, dynamic features can be added as client scripts, and backend logic can be implemented as serverless functions hosted on cloud FaaS services such as AWS Lambda or Google Functions. The resulting sites conform to the newest Web standards and practices, and can even take the form of SPAs, though most static sites are traditional MPAs for better SEO performances.
Core value: content as code
- Source content uses flat file formats such as Markdown, managed with version control software such as Git
- SSGs produce web assets from source content
- Web assets hosted on static Web servers and CDNs
- Publishing is either manual or automated with CI/CD software pipelines
- If needed, backend is provided as Serverless functions hosted on cloud services
- Client code can access third-party services third-party APIs
As web applications grew and became more complex, frontend frameworks made this complexity manageable, at the expense of their own complexity. But the most dramatic loss of the Postmodernist period is readability. The Web has always been a transparent platform. When websites were hand-crafted, their source code was available for anyone to read. How many of us web developers learned to code by reading website source codes? The Postmodernist Web is not human-readable anymore, but machine-readable: it is transpiled, tree-shaken, minified, bundled and distributed as an unreadable mess of keywords and special characters. And with readability comes learnability. Web development is no longer about the web standards, it is about mastering the intricacies of the most popular frameworks in the shortest possible time, because these frameworks evolve so fast that you often have to unlearn the old features and practices of previous versions in favor of the new ones. And since multiple frameworks cannot coexist easily in the same application, choosing the right one has become a career choice. The web is no longer a platform but a target for competing technologies, just like during the Dark Ages.
The Metamodernist Web is the most recent iteration in the history of Web development. It rejects the framework monoculture and the unsustainable pace of the Modernist and Postmodernist models in favor of web-native solutions with a simple motto: Use The Platform. Rather than generic, full-featured frameworks, websites and applications should aggregate and integrate feature-specific solutions as needed. But above all, they should be resilient, inclusive and environmentally responsible, with a minimalist footprint, manageable complexity and transparent dependencies.
Metamodernism acknowledges that many desirable features of frontend frameworks were designed at a time where the web platform lacked native support, but new standards have emerged since then, and as the web evolves and becomes more powerful, many common development tools and practices are becoming legacy and even counter-productive. New ECMAScript language features push the Vanilla JS developer experience closer to transpiled languages such as TypeScript. ECMAScript Module support (ESM) in all recent browsers enables buildless and bundleless workflows with productivity on par with older development servers: Snowpack for example supports live reload, Hot Module Replacement (HMR), etc. And services such as Skypack, unpkg and cdnjs allow for direct integration of third-party npm modules as web page script elements without having to install them locally. Dependency- and toolchain-free development is possible again.
On the client-side, monolithic component-based frameworks are no longer required now that Web Components are available. Web Component libraries such as Polymer and Ionic can be used with any frontend framework or even with plain HTML. Micro-frontend models are more and more popular. Script-based practices that duplicate native web functions are discouraged, such as CSS-in-JS and animations.
The Service Worker API enhances the client-side model even further by off-loading technical code from the much-solicited main thread to a dedicated thread: offline mode, caching, prefetching, persistence, push notifications, etc., all these features can now be implemented more efficiently and with Progressive Enhancement in mind. Web App Manifests bring web applications even closer to native desktop and mobile apps with application icons, installability, sandboxed execution, background and offline modes, etc. The combination of these technologies forms the core of the Progressive Web Application model (PWA). And with the support of WebAssemby (Wasm) as a compilation target for system languages such as C, the web finally becomes a truly universal application platform.
Launched in 2016, Svelte is at the crossroads of the Modernist, Postmodernist and Neoclassical Web models. Svelte combines the component-based development model of frontend frameworks and the capabilities of SSGs in the form of a compiler that produces framework-free, static web assets that only depend on standard Web features. In this sense it is the first Metamodern Web framework. In 2020, Basecamp released Hotwire (HTML Over The Wire), a set of techniques used to bring SPA-like enhancements to traditional SSR applications: partial page updates, client-side navigation history, AJAX, server pushes, etc. Hotwire is also Metamodern in the way it applies Progressive Enhancement techniques to existing models.
- Web Components (2011)
- asm.js (2013)
- Polymer (2013)
- Service Workers (2014)
- HTTP/2 (2015)
- WebAssembly (2015)
- ESM support in browsers (2015)
- PWA (2015)
Progressive Enhancement is at the heart of the Metamodernist Web model. Web pages should rely on native web features whenever possible, and may provide polyfills on a case-by-case basis. Applicative or third-party code that duplicates native web features are prohibited.
Client-side scripting is optional. Essential features may be implemented as client-side scripts as long as they also remain available by other means (e.g. server-side processing) to clients without adequate capabilities, for example when scripting is disabled or limited. Frontend and backend frameworks are optional. Dependency to third-party software must be kept minimal. The Service Worker is an ideal place to implement non-essential features and performance enhancements without blocking the main client thread.
The ideal workflow is buildless. Complex build processes and toolchains are optional, and when present they must be transparent, reproducible, and resilient. When using code generation tools, the resulting code should ideally be human-readable, although this is only a desirable goal for learnability.
Applications must be inclusive. Not all browsers are Evergreen. Not all applications need massive scaling. SSR is a perfectly fine model for many applications. Core functionalities should be available to all clients regardless of their performances and capabilities. Non-essential functionalities should be provided with Progressive Enhancement in mind.
Core value: sustainability
- Buildless, bundle-less front-end development if possible
- SSG or SSR for noscript clients
- No frontend framework
- Web Components or micro-frontends for dynamic enhancements
- Client code is Vanilla JS or transpiled to ES modules
- Dependencies can be self-hosted or loaded directly from CDNs
- Service Worker for non-essential enhancements: offline/background mode, caching, prefetching, resilience, etc.
- Application manifest for PWA mode
The history of web development is rich and complex, sometimes violent and filled with controversies. Of all the web development models presented here, none can pretend to be more "web-native" than the others, and even if some models are closer to the original vision, the web platform is powerful enough to embrace them all. Every model has its strengths, its weaknesses, its proponents, its zealots and its detractors. There is no one "True Way" to web development, just tools in a toolbox. Choose the right tool for the right job.
PS: Don't forget to read the other articles in this series if you haven't already!