What is the JAMstack?

An introduction for more performant and secure frontends
1
Jun

What is the JAMstack?

Especially for content-heavy sites and applications where scaling and security play a major role, the JAMstack offers an approach that can make development easier and cheaper.

Just as in 2020, we can expect the JAMstack [1] topic to continue to gain momentum and attract interest from numerous companies. In the following, we’ll take a look at what the JAMstack is all about and how it makes our sites more performant and secure while improving the front-end development experience.

To do this, we will first look at what JAMstack actually means and where the differences lie compared to classic approaches. This is followed by a look at possible areas of application where the JAMstack can show its strengths.

For those who want to get hands-on, I’ll introduce a few frameworks that can be used to develop applications. And don’t worry: Fans of Angular, React, and Vue don’t have to learn a new framework right away.

What does JAM mean?

JAM is an acronym that stands for JavaScript, APIs, and Markup. The architecture involves delivering pre-rendered, static pages via a content delivery network (CDN). Applications are made dynamic via the integration of APIs and JavaScript. Technologies that can play to their strengths include common JavaScript frameworks, static site generators, and specialized third-party APIs (e.g., for authentication [2], payment service processing [3], or headless content management systems (CMS) [4]). This gives us good performance, higher security, easy and above all, cheap scaling with a good development experience.

Much of what the JAMstack introduces is not new and is already being used successfully in one project or another. Therefore, the JAMstack is a clear definition of modern architecture for websites and apps. In the following, we will take a look at how the JAMstack stands out from classic applications. Of course, the evaluations made here do not do justice to every application across the board.

Server-side rendering

Let’s start with a classical approach: Our server receives a request and performs matching operations on the database. The result of the database operation is processed and then rendered appropriately for the client. The client then displays this page to the user in the browser. When it comes to performance, we initially depend heavily on the performance of the server and database queries in the background. This can be improved via caching. Since the generated page is static HTML, this part should be extremely performant for the user (Fig. 1).

Fig. 1: The server interacts with a database and renders static web pages according to the requests

 

In this case, scaling often means that several servers (and/or databases) are needed to scale, which of course involves increased costs. Especially if only individual subsystems are under load, this can become too expensive. On the backend, one could resort to a serverless or microservice architecture. On the frontend, these approaches do not always fit.

From a security perspective, the server and database have to be considered, but you can also fall back on one of the numerous standardized solutions. From a developer’s perspective, this approach can result in application logic and presentation being mixed. For sophisticated frontends, the development experience is often better when the frontend is clearly separated from the backend.

Single Page Applications

With Single Page Applications, we move more logic to the client. This presents the page and communicates with the server via REST APIs. The server processes the requests, performs operations on the database, and usually returns the result to the client via JSON or XML, which updates the page accordingly (Fig. 2).

Fig. 2: The frontend is a single page application and communicates with the server via REST

 

From a performance point of view, part of the responsibility moves from the server to the client. The server “only” has to return the determined result to the client in the form of JSON or XML. Caching is also an established means of improving performance here. However, this is at the expense of the client, which has to load and render the JavaScript frameworks and applications in use. Obviously, this can’t keep up with a static page and will degrade the user experience in comparison.

When it comes to scaling and security, we are moving in similar dimensions as with the previously described solution. By caching the REST APIs, there is probably a bit more leeway for most applications before additional costs are incurred. Of course, it should not be underestimated that part of the application logic must be implemented in the frontend and backend, which can be an additional source of security vulnerabilities.

Of course, the development experience is much better in the frontend. Although there are still projects in which the backend and frontend are developed together, the frontend is clearly (more) separated from the backend. At the same time, there is the business logic already mentioned above, which in this case, must be maintained twice.

JAMstack

JAMstack websites and applications render all pages in advance as static HTML pages rather than for each request individually, as with server-side rendering. These pages are then delivered via a CDN. Where necessary, third-party APIs or custom APIs are connected (Fig. 3). Of course, we have two dimensions that we need to consider separately: Frontend and Backend.

Fig. 3: With JAMstack, the frontend is delivered by a CDN

 

On the frontend, this approach is highly performant: CDNs ensure that pages are delivered quickly (Box: “Advantages of CDNs”). Static pages, by their very nature, render quickly to the user. Compared to the classic approaches, the performance is outstanding, and the topic scaling is of interest. CDNs offer this quasi-out-of-the-box and it is much cheaper compared to classic hosting. If more resources are needed, no additional (complicated) server has to be set up, but only static files have to be made available. From a security point of view, this is also an improvement: the delivery of static pages is easier to secure than the operation of an application server.

In the development experience, we have achieved separation from the backend. The application can be developed with the desired toolset. The backend is only connected via APIs. It is immediately noticeable that the JAMstack can score in two areas:

  • for pages that do not need a backend, where we can render the content in advance, and
  • for microservices and serverless applications.

With these solutions, the JAMstack is particularly attractive, especially when we consider the topics of performance and scaling. For classic applications, the recommendation to migrate their application to microservices or serverless would probably be too big a step. Nevertheless, the separation of backend and frontend already brings numerous advantages during development and simplifies the application. The use of the JAMstack can be the first step towards more modern architecture. Parts of the logic could be outsourced to the cloud (either as microservices or in the form of serverless functions). Another way would be to use the domain expertise of third-party providers to handle areas such as authentication or payments and call them directly from the front end via the appropriate API.

Of course, there is no one architecture that covers all requirements. Let’s take a look below at where the JAMstack comes into its own.

Advantages of CDNs

Using CDNs to deliver a frontend became popular with the introduction of JAMstack. But what is a CDN and why do we achieve optimized performance and higher security from it?

A CDN is a group of servers that are geographically distributed. The task of the CDN is to provide static content (such as HTML, CSS, JavaScript, images, …) quickly. CDNs enjoy great popularity in this regard and are responsible for a large part of the worldwide traffic.

For the user, the geographical separation means that pages load faster, because a page is not retrieved from an origin server, but from the geographically nearest server. In the event of a server failure due to hardware fault or if servers reach their limits due to an increase in requests, other servers from the network can step in.

The file size of static data can be optimized via minification and compression, which can also improve traffic (and thus costs) and speed. For companies, this reduces operating costs while improving the user experience.

Of course, you don’t have to operate a CDN yourself: Major cloud providers have solutions ready, while companies like Netlify and Vercel offer them.

 

Application scenarios

There are already numerous examples [5] of pages implemented with the JAMstack. The use for pages that primarily display static content is obvious, starting with blogs up to news sites, which should be highly available. For these pages, the use of static pages naturally leads to better search engine optimization.

The JAMstack not only suitable for static pages. Dynamic content such as comments can be integrated using JavaScript and APIs. In the area of content management systems, there are numerous providers for headless CMS, such as Contentful. Even for complex processes such as payments, there are solutions on the market and also examples of how these can be developed using JAMstack. It is up to the team to decide how much dynamic content to include in a JAMstack page via JavaScript and the appropriate APIs. The own business logic can then initially continue to be integrated via the own server as an API or migrated to the cloud in order to be able to easily scale here as well at any time.

If the use cases fit and the advantages are convincing, we should take a closer look at the topic of development. Below, I describe some best practices for the JAMstack.

JAMstack Best Practices

JAMstack pages do not need a classic server to be executable. Even if we could deploy pages created with the appropriate frameworks on a classic server, I would not be discussing JAMstack, as it is closely linked to CDN. As already described, the use of a CDN plays a significant role in benefiting from the JAMstack. From a development perspective, the benefits of a separate front-end application should be taken advantage of: There are numerous frameworks and build tools in the JavaScript ecosystem that simplify the creation of web pages and improve the development experience. Of course, back-end development also benefits, since the focus is purely on application logic and providing APIs.

Especially for large sites, the issue of atomic deployments should be considered. For large sites, where each build is several hundred pages, changes can lead to site inconsistencies that will likely take a long time. Ideally, only changes are deployed and not complete pages.

As promised in the introduction, we don’t have to relearn everything now to develop applications for the JAMstack. We can even fall back on frameworks known from Single Page Applications.

Frameworks for the JAMstack

Of course, it is tempting to simply deploy an SPA in a CDN, and this is probably a good first step for existing applications. For many applications, however, it is not necessary to deploy a corresponding framework. There are workarounds to continue to use the SPA framework of choice, but provide static pages to the user.

Let’s first look at the solutions for largely static pages. Here, there are numerous generators on the market (e.g. Jekyll [6], Hugo [7] or Eleventy [8]) that generate static pages. This can be done via Markdown or using a headless CMS such as Contentful. If necessary, JavaScript can also be used to make the respective page more dynamic.

For applications that require SPA functionality, frameworks based on React, Angular, or Vue can also be used. In that case, frameworks such as Next.js (React) [9], Scully (Angular) [10], or Nuxt (Vue) [11] offer the possibility to generate static pages from the SPAs. When these pages are loaded in the browser, the associated JavaScript (e.g., the runtime of the framework) is reloaded and the page is subsequently extended with the functionality from the SPA (this is also referred to as hydration). This combines the advantages of a static page with the respective framework, providing an excellent user experience.

Creating an application with Next.js

If you want to create and deploy a JAMstack application now, you can turn to Next.js. Next.js is offered by Vercel [12], a provider that also offers CDNs. In this example, I show how to deploy the whole thing to Netlify [13].

The setup is similar to the approaches of SPAs: there is a suitable npm package to build the application. In this case, all that is needed in the terminal is:

npm init next-app

A dialog guides you through setup. After that, only the build command in package.json needs to be adjusted so that Next.js creates static pages with next export.

"scripts": {
  // ...
  "build": "next build && next export",
},

Now, when we build the application with npm run build, the out folder is where the static files are created that we will deploy later.

Deployment

While in server-side rendering, pages are generated at runtime, in a JAMstack page they are rendered in advance (Fig. 4). For this purpose, sources such as Markdown, CMS, or an RSS feed can be used during the build to generate the appropriate static pages. These pages are then published to the CDN.

Fig. 4: All pages are rendered in advance here

Very few companies will want to operate their own CDN, which is why using suitable providers is recommended. Companies that already rely on cloud providers can also use the JAMstack. With AWS [14], for example, an S3 bucket can be distributed via a CDN with the help of CloudFront.

With Netlify and Vercel, there are specialized providers that provide the required functionality. For example, pages can be deployed at Netlify and distributed via their CDN. Netlify Functions offers serverless functions to extend your own application.

Every major vendor now offers the necessary tooling to deploy your own application. We make sure that our Next.js application is available on GitHub (Netlify is not restricted to GitHub, of course) and link it to Netlify from within the terminal.

First, we have to install the Netlify CLI via npm install -g netlify-cli. With ntl login we log in to Netlify (we may have to register once in the opening browser). In the directory of our site, an ntl init is enough to link our site with Netlify. The dialog you are guided through links the GitHub repository with Netlify and ensures that after each push to the main branch the page is updated at Netlify. By the way, for private and smaller projects the free Netlify package is perfectly sufficient.

That’s all it takes. Now, the page can be developed further. There are numerous online tutorials that show how to integrate static resources into a Next.js page. This article should only serve as a first introduction.

Conclusion

With the JAMstack, we have a modern architectural approach that not only speeds up development, but also provides developers with a modern environment. Users benefit from high-performance pages. Companies can save operations costs and have to worry less about security.

There are numerous examples of JAMstack usage. Even if the idea of generating all pages statically in advance seems unusual at first, there is still a lot possible here. Not only content-heavy pages can benefit from this. With modern frameworks around Next.js, Scully and Nuxt, the advantages of the SPA can be easily combined with those of the static page.

 

Links & Literature

[1]https://JAMstack.org

[2]https://auth0.com

[3]https://stripe.com

[4]https://www.contentful.com

[5]https://JAMstack.org/examples/

[6]https://jekyllrb.com

[7]https://gohugo.io

[8]https://www.11ty.dev

[9]https://nextjs.org

[10]https://scully.io

[11]https://nuxtjs.org

[12]https://vercel.com

[13]https://www.netlify.com

[14]https://aws.amazon.com

STAY TUNED!

 

BEHIND THE TRACKS OF iJS

Angular

Best-Practises with Angular

Vue.js

One of the most famous frameworks of modern days

JavaScript Practices & Tools

DevOps, Testing, Performance, Toolchain & SEO

Node.js

All about Node.js

React

From Basic concepts to unidirectional data flows