The vast majority of my career in web development as revolved around WordPress. There’s been a relatively recent paradigm shift in web development called the JAMStack that more and more developers are embracing, including myself. I’ve been pretty deep in the JAMStack world now for close to a year, and so I want to share my thoughts and experience transitioning from WordPress. I have a lot on my mind regarding this topic, so I’m planning for this to be a series of upcoming posts. In this first post, I want to give a brief overview of what JAMStack is, and some of the tools I’ve used with it.
Unlike many other tech stacks, JAMStack doesn’t really define specific technologies to use. It’s more like a theory on how to maximize performance and organize the components of a website. JAM stands for JavaScript, APIs, and Markup. These three general components are used with a static site generator to create websites that can be just as functional as any WordPress site, without all the extra bulk.
There are many static site generators that can be used in a JAMStack build, like Hugo, Gatsby, and Jekyll. Jekyll is probably the most widely used of these, and the one I have the most experience with. With Jekyll, I build out HTML templates for a site using Liquid templating, and add the site’s content to simple plain text, html, or markdown files. Once a build is triggered for the site, Jekyll’s Ruby framework takes that content and applies it to the appropriate templates, creating a directory of completely static content that’s ready to serve.
With Liquid templating and simple Ruby extensions, Jekyll is capable of everything a WordPress theme can do. Jekyll’s collections function the same as WordPress’ custom post types, front matter functions the same as custom meta, Liquid blocks work like shortcodes, Ruby plugins work like filters, and yaml configs can function the same as PHP globals. Jekyll makes the markdown part of JAMStack extremely powerful, but its lack of an actively running backend means it can’t do some of the things that WordPress has built-in like search and form submissions. This is where the JavaScript and API parts of the JAMStack come in.
One of the major selling points of JAMStack for me was how well-organized it requires code. JAMStack requires a very clear separation of frontend assets and backend functionality. In most applications of JAMStack, the frontend and backend of a site rarely even exist on the same server. JAMStack relies on the fact that there are countless API services a site can call on to provide almost any kind of backend functionality it needs. One such service that I’ve used pretty extensively is Algolia. I use Algolia to create an external index of a site’s content, and sometimes other external data that is used in the site. I can use Algolia’s index as a kind of database for the site, which lets me easily implement search functionality to a site without having to write my own algorithms. This very blog uses an Algolia index for the search bar in the menu. In addition to a site’s own static content, I’ve also used it to index data in Google Sheets to be applied across many different JAMStack projects. From the Jekyll side, this all boils down to a basic AJAX http request, and parsing through the JSON Algolia gives back.
There’s an API service out there for just about anything you’d want your website to do. But relying on these external APIs can sacrifice some of your ownership of a site’s functionality. What if a project requires a highly custom way to handle form submissions, or needs a highly custom authentication process? This is where serverless functions come in.
Serverless functions is an even newer part of web development than static site generators. It’s a way to build out backend code in a static site without having a server for the code to run on. “Serverless” is kind of a misnomer because ultimately there is a server that the code runs on, but it removes all of the maintenance, scaling, security, and other sysadmin aspects of running a server. Put way too simply, it’s a service you use to host your own API code. The biggest example of one of these services is Amazon Lambda, but so far my need for serverless functions has been too sparse to justify that particular service. I’ve been using a similar but simpler service called Webtask. As an example of how I’ve used Webtask, one particular JAMStack project I worked on needed its own custom form submission and admin view to display those submissions. I wrote the form submission process and admin authentication process in Node and Express, and saved that code into a directory in the Jekyll project that was configured to not build out with the rest of the site templates and content. I then took the config file that Jekyll uses to build the static site, and added a property to the build process that pushes the Node directory up to my Webtask account. From there, anytime a site visitor accesses the form, the form will make a basic request to Webtask, which will then handle scaling up a server on the fly and running my code. It’s incredibly powerful, and incredibly liberating as a developer.
Hopefully it’s clear from this post how powerful JAMStack can be when applied with the right tools. There’s still a lot more I want to go over about JAMStack, like hosting, deployment, and content management systems, but this is already my longest post ever. I think those topics are better left for another post. I will be working on having a Part II in the coming days.