Static HTML files were how the web started. Then dynamic server-side rendering, then single-page applications. Each transition added capability but also complexity. The JAMstack movement of 2018 was not really a return to simplicity. It was more of a reframing: use modern tooling to generate static output, serve it globally from a CDN, and reserve dynamic behaviour for JavaScript in the browser and API calls.
The J, A, and M stood for JavaScript, APIs, and Markup. The Markup was pre-built at deploy time, not generated on request. This distinction matters enormously for performance.
When a user visits a traditional server-rendered site, the server must process the request: query databases, render templates, generate HTML, and send the response. This takes time and requires server capacity. When a user visits a JAMstack site, they get a pre-built HTML file from a CDN server close to them. No server processing, no database queries. The time to first byte is as low as it can be.
Netlify was the company most responsible for popularising the JAMstack approach. They built a deployment platform that took a Git repository, ran a build process to generate static files, and served those files from a global CDN. The developer experience was excellent: push to GitHub, your site updates in seconds. No server administration, no deployment pipelines to maintain, no scaling to worry about.
The static site generator ecosystem had grown significantly. Gatsby brought React to static site generation. Hugo was fast and practical. Jekyll had been around for years. Next.js was developing static export capabilities. Whatever framework you preferred, there was a way to generate static output.
The objection I heard most often was about dynamic content. A site with user logins, personalised content, or real-time updates could not be purely static. The JAMstack answer was that dynamic behaviour belonged in JavaScript and APIs. The HTML shell was static. Content loaded after page load via API calls. Authentication happened client-side via identity services.
This worked well for content-heavy sites: marketing sites, documentation, blogs, and news sites. For applications with heavy dynamic requirements, the JAMstack constraints were more awkward.
What the JAMstack movement contributed most was a renewed focus on performance and simplicity. The default for a static site was fast. You had to actively add complexity to make it slow. That inversion of defaults, where the easy path was also the performant path, was a genuine improvement over frameworks where performance required deliberate optimisation.