Jamstack is an approach to building web sites and web applications that I like to use as a front end architecture. The acronym JAM stands for Javascript, API's and Markup, a technology stack that has existed for many years. The Jamstack however prescribes how to put these technologies together while adhering to the core principles of pre-rendering, progressive enhancement and decoupling.
Pre-rendering
The M of Markup implies the use of HTML, and more specifically that of static HTML pages. These static pages are not generated by a webserver as they would have been in the past, instead they are generated as part of your automated build process by means of a static site generator.
A static site generator is a command line tool that processes input files and turns them into a website. These input files are optimized for the task at hand, such as markdown files for content editing, handlebars templates for semantic page composition or YAML files for metadata. There are literally hundreds of static site generators for you to choose from. Each of these comes with its own set of assumptions, conventions and opinions.
I originally started out with Jekyll, but after a while switched to a different approach. Instead of trying to fit all of the requirements to the opinions of a command line tool, I'm now building a custom site generator for each site to exactly fit its needs. This may sound like a lot of work, but with the help of Dish, my static site generation library, it becomes fairly trivial.
Hosting
Once your build process outputs a static website, you can host it anywhere you like. A common hosting approach is to serve your apps directly from a CDN. Hosting on a CDN has many benefits:
- Instant global availability and great download speeds.
- Very cost effective, even a large site will only cost a few euro's per month.
- No need to manage webservers or deal with hosting providers.
- Many CDN's come with custom domains, free SSL certificates, built in routing rules and failover capabilities, etc...
I personally host my sites and apps on the Azure CDN backed by the Azure blob storage static websites infrastructure.
Progressive enhancement
While the site itself may be static, that doesn't mean that it needs to have static behavior. To enhance the experience and personalize the web site or web application, you can use Javascript if it is available.
Javascript can progressively enable more client side features if they are available in the browser runtime. The approach of progressive enhancement is also refered to as Progressive Web Apps. You will be surprised to see what a PWA can already do today. So many capabilities are already available to web apps that I believe PWA's can become a great way to build web, mobile and desktop apps alike, on a single code base, in the coming decade.
Microsoft also announced that on August 17, 2021, Internet Explorer 11 will no longer be supported. This also means that the last browser not supporting modern Javascript will be gone from that point on. Modern Javascript, the EcmaScript 6 standard, has become a very mature programming language that can finally stand on it's own. I personally see no more need for Javascript frameworks such as JQuery, Vue or React as the language itself has become powerfull enough to build components without additional framework support.
Decoupling
Over the past decade, many companies have begun exposing data and capabilities as services on the internet. These services can easily be integrated through API's exposed by the provider. Jamstack sites can leverage these api's both during the build process to generate static content and at runtime to dynamically generate content.
There are so many services available today that becomes perfectly possible to build an app without a backend at all.
- There are services to provide cross cutting concerns such as identity, authentication, content management, payments, email, monitoring, storage, etc...
- But there are also more and more domain specific services becoming available. As an example, the flemish basketball association exposes all clubs, players, game schedules, etc.. through an API as well. This data comes in quite handy when I'm building apps for basketball clubs.
If you do need custom data or logic, I recommend to follow the same convention, and expose your capabilities as API's as well. When integrating services into the UI at runtime, I recommend to provide packages with web components encapsulating the API calls, regardless if they are private or third party services. Then use a package manager during the build process to include them into the generated website. Similar for integration of data during the build process itself, each capability could expose an SDK package, with Dish pipeline sections, that can be included into the processing pipeline. This pipeline section then calls the API and renders the static HTML based on the data returned.
Exposing capabilities as API's, with accompanying components and SDK packages, ensures that the core principle of decoupling is being adhered to.
What would you like to hear about next?
Let me know in the comments what you think about my approach to building frontends, or what you would like to hear more about.