November 19, 2020
Web technology evolves over time and new tools and architectures are created and designed to address different problems in legacy systems. These could be in the development process, with performance, cost, user experience, scalability, and other system considerations. Jamstack is part of this evolution. But what exactly is it?
In more common web architectures, a web page is built using resources like data from a database, templates, and other content every time it is requested from a server and the resultant output is returned to the client. Jamstack is different from these architectures in that a site is pre-built into static assets before deployment, and these assets are distributed through a CDN.
In the Jamstack, the frontend and the backend are completely separate. The APIs are distinct reusable services that provide specific functionality to static sites like payments, authentication, search, image uploads, comment management, etc. They could be created in-house or provided by vendors. The decoupling of the frontend from the backend has created opportunities to use a wide range of APIs with the frontend. There all kinds of APIs available within the API economy like Paypal, Algolia, Cloudinary, Auth0, etc.
Jamstack was coined as a term to better communicate what this new kind of decoupled architecture should look like. It is important to note that technologies that separated the frontend from the backend, prebuilt the sites, and distributed them over a CDN pre-dated the term. However, it was crucial to have the terminology to collectively describe all the tools that used this architecture, to make it easy to evangelize, and to set up best practices.
Jamstack sites can be built in different ways using different tools and technologies. The most common types of Jamstack site build tools include static site generators like Hugo, Jekyll, Gridsome, etc... and headless content management systems (CMSs) like Strapi.
Traditional web architectures tend to be monolithic systems and their constituent parts are often tightly coupled. Let’s take the example below.
In this type of architecture, when a page request is made from the client, the webserver routes the request to the app server based on the URL. The app server then makes a data request to the database. Once the database returns data, the app server combines the data and page templates and renders them into a response. It then sends the response to the webserver which in turn passes it along to the client. In some architectures, cache layers may exist between some of the parts to facilitate quicker responses.
This tightly coupled architecture has inherent risks and complications. These range from impacts on how users experience the site, the site’s development, complexity, performance, and its developers and team experience.
Performance Issues Whenever a user requests a web page, it has to be built each time, multiple parts of the system need to be involved, and the response is passed along to several layers before it gets to the client. This slows down page load time. Some systems add caching layers to address this but implementing consistent caching can be difficult leading to users receiving varying results. The tight coupling also makes it challenging to migrate to better frameworks, update dependencies, or address bugs because it may adversely affect other parts of the system and take a long time to accomplish. These performance issues lead to lower visitor conversion on these sites.
Security Risks Traditional architectures are made up of several parts, increasing the surface area that needs to be monitored and secured. Since all parts of the system are involved when processing a request, they are all vulnerable and possibly open to security threats. As a result of tight coupling, when security vulnerabilities are identified, developers have to choose between patching them and potentially breaking the site with the change.
Complex and Expensive Scaling Another consequence of tight coupling in this architecture is the expensive and complicated scaling. Because every response to a request needs to be built before serving, the parts of the architecture that build and serve responses need to be scaled to accommodate traffic increases. However, not all web pages need to be built for every request. A one-off build that generates a page to be served continually would suffice. As such, the part that builds the app and that one that serves it do not ideally receive the same traffic and should not be scaled at the same rate. But in this architecture, both are scaled proportionally. Scaling this architecture is generally pretty expensive because of the type of technology that's part of it.
Complicated Development and Maintenance Owing to tight coupling, it's complicated to make changes, updates, and push out bug fixes because of the widespread effects it would have on the entire system. This impedes flexibility to implement designs and make regular updates to improve user experience and developer workflows.
In Jamstack, the frontend is completely separated from the backend. The frontend is prebuilt before deployment, APIs are used to provide services to it, and it is distributed through a CDN. So here's how a typical page request would be handled.
When a client makes a request for a web page, the CDN looks up the pre-rendered web page that matches the URL and sends it as a response to the client. The simplicity of this architecture has a range of benefits.
Performance Compared to traditional architecture, Jamstack drastically improves performance because its tiers are reduced. This means that responses to requests go through fewer tiers and are faster. The resources and time that would go into maintaining additional tiers in traditional architectures are invested in optimizing the remaining tiers. Since web pages are pre-rendered, no building happens for each request. This coupled with the fact that multiple tiers do not have to interface with each other to generate a response and sites are delivered through a CDN, contributes to faster responses. The potential for failures to occur is greatly reduced because of pre-deployment building and the minimized surface area of the architecture. Pre-building pages ensure that any errors can be detected early enough and fixed before users get to interact with the site.
Another benefit of the loose coupling of Jamstack is that it is easy to make changes, push updates, introduce new features, refactor code, and upgrade to better vendors without having to worry about breaking the system. However, the interface through which each of the components interacts must remain the same.
Reduced Cost In Jamstack, as a result of the decoupling, whole tiers/components may cease to exist in the infrastructure. If they do exist, they receive less traffic compared to the frontend and hence do not need to be scaled at the same rate. This heavily reduces the machine, labor, and software costs of the infrastructure. Jamstack sites are overall cheaper to build, scale, and maintain.
Easier to Secure Having fewer components, Jamstack sites have a significantly smaller surface area to secure, maintain, and monitor. There are fewer points of entry that attackers can exploit and are therefore less vulnerable. No code is run on a server to build pages, making it difficult to inject exploitative code in the site. Services are outsourced to vendors with domain expertise, who are better equipped to secure and maintain them.
Enhanced Team and Developer Productivity The Jamstack is simple because it has fewer components and is easier to understand. As such, developing and maintaining a site that uses this architecture tends to be a bit more straightforward. Developers of the site do not need to be completely adept at how each and every part of the system works. Since the components are loosely coupled and their boundaries clearly delimited, developers can specialize in the parts they work on.
Given the decreased number of tiers in the architecture, fewer developers are needed to work on the site. It also eliminates the need to have very specialized developers like DevOps engineers, SREs, etc. on teams. Since Jamstack sites are pre-rendered, there's no need to have replicated environments like development, staging, testing, etc. This substantially reduces the amount of work needed to set up and maintain these environments. Usually, with Jamstack sites, there's just one development environment and a pipeline for deployment. The reduced workload frees up time that allows developers on the team to better focus on understanding sections of the system they work on.
Jamstack sites make it easy to introduce new features and designs, make upgrades, and maintain them because their components are loosely coupled. Compared to traditional web architecture which is tightly coupled, implementing new designs is often tough, takes a long time, and has multiple complications. Developers working on these systems are often exasperated which sometimes leading to churn. Recruiting to replace them can also be challenging since developers may not want to work on inflexible projects. Using Jamstack sites means site additions and improvements are made relatively fast, improving reliability.
Jamstack site tools and technologies are widespread and modern. Jamstack best practices outline workflows that ensure productive and effective development. Most importantly, Jamstack allows teams to outsource complex services to vendors who provide, maintain, and secure APIs used on their sites.
Static site generators are build tools that add content and data to templates and produce static web pages of a site. These generators can be used for Jamstack sites. They are especially useful for large websites with many pages since they automate builds. Some well-known site generators include Hugo, Gatsby, Jekyll, Next.js, etc. You can find an expanded list of these generators at this link.
A content management system controls the production and alteration of digital content. A CMS is headless when it lacks a frontend and only has a backend that adds, provides, and modifies the content through an API. In some instances, the headless CMS may be augmented with an admin portal for content organization, workflow setup, etc. Headless CMSs fall under the APIs in Jamstack. Strapi is a great example of a headless CMS. It's open-source and the content on it is provided through GraphQL or REST.
To get the full benefit of Jamstack, it's important to follow some best practices. These include:
Jamstack is an architecture for static websites that are built before deployment and distributed through a CDN. Services to the website are provided through APIs and there is a complete separation of the backend and frontend. Jamstack sites have better performance, are easier to secure and scale, and cost a lot less than sites built with traditional architectures. They can be created using static site generators or with headless CMSs. To find out more about Jamstack sites head on over to jamstack.org.