Why I love (and how I make) simple, static, minimal-tech websites

There was some interesting chatter a while ago in my tech social bubbles about the tiny decline in WordPress’s CMS market share.

This was followed by some interesting Twitter replies. But I chose to pick up on my friend Keith Devon’s response:

And it caused me to reflect on how I now build small/quick sites for side projects.

Previously I’d have installed WordPress and a page builder to cook up a simple site for my own needs. But nowadays it’s very different.

Partly my skills have developed – and in all of what I’m about to describe, I appreciate that this is not the kind of thing that an average person can do. And partly there have been some technology shifts that have enabled different ways of achieveing the “simple landing page” goal.

But lets dig in to what’s changed, and what I would do now instead of using WordPress.

What’s changed?

If you rewind even a relatively small number of years, building a simple several-page website with some interactivity was painful. HTML lacked some advanced things like date/time inputs, and media elements.

CSS was lacking in simple things like animated transitions, flexbox, grid, image/object fit/cover, custom properties, and calc.

You might need PNG icon sprite sheets.

JavaScript was so clunky you kinda had to have jQuery to make it usable. There was no good way to make it modular (other than conflicting standards jostling to be The True Way). And anything more than the simplest code quickly became a spaghetti of functions and nested callbacks.

So much stuff required importing libraries of code to achieve what is now basic and built-in.

Hosting was on shared servers with SFTP and SSH if you were lucky. CDN’s were for advanced projects. HTTPS certificates cost money.

LOOK AT US NOW!!!!

HTML5 semantic markup; programmable video and audio elements; date/time inputs; built-in input validation and errors; CSS transitions and animations; flexbox, grid, calc, fancy units; CSS custom properties; background-size and object-fit options; ES6+ JavaScript with all sorts of niceties that make coding in vanilla JS so much easier; the fetch API; promises and async/await; simple reactive JS libraries like Alpine and Petite Vue; a multitude of browser APIs for things like geolocation, text-to-speech, speech-to-text, cameras, video, orientation, bluetooth and stuff; native ES modules; fast and simple JavaScript tools like ESBuild; SVG’s; and super-easy deployment of static pages to free or super-cheap, serverless hosts like Netlify, GitHub Pages, and Cloudflare pages.

Phew! I can barely handle the power. And there IS power here.

How I’d build and host a single page website now

With all this power, let’s explore what a difference this has made. First off – how would I build and deploy a single page site?

Let’s start with the caveat that I’m not a designer, so I very much stand on the shoulders of giants when it comes to design.

These days that’s usually TailwindUI, or something I can throw together in Shuffle (probably using TailwindCSS as well). Though there are some free alternatives as well for this kind of thing.

Pick some components, chuck them together, tweak them as necessary (which I find much easier to do in this kind of small site with TailwindCSS than in regular CSS) and away you go.

If I need some simple JavaScript-driven interactivity I’ll add AlpineJS (a small, reactive JS library) alongside vanilla JavaScript if needed. This needs no build process.

And I’d put the whole thing in GitHub and deploy it to a static hosting service like Netlify (which has a generous free tier) or Cloudflare Pages (which is 100% free). No FTP; a quick push to Git and you’re done! This is the modern way.

Wait? What? Tailwind?!

“But wait…”, I hear you say, “aren’t we aiming for minimal tech here? A no-build-process type thing?”

Well, there are some exceptions. And let me justify Tailwind as a build tool.

I have NEVER had a big problem with Tailwind’s CLI tool. It’s well maintained by some very smart people who have a decent business model. I just don’t get the kind of npm-error-vomit from Tailwind that I have got from other build tools. It’s stable, robust, well-documented, and the nature of what it does means that backwards-compatibility rarely seems to break.

I enjoy using Tailwind as a build tool and so I’m happy to have it in my simple toolchain.

PLUS, for me, one of the big benefits of Tailwind is it’s easy to come back to a project to tweak its styling. These projects are often build-deploy-and-forget-for-ages type things. So simple re-visiting of them is really helpful.

There’s one more thing to mention about about Tailwind: to get the best from it you really need to have HTML components, possibly with parameters. And this might also need a build tool such as a static site generator.

So this is starting to sound complicated. But wait!

How I’d build and host a multi-page website

If the site has multiple pages, then to get the benefit of push-to-deploy to a static file host but also using some kind of templating, we’re going to need a static site generator.

When I went surveying the environment for this, everything was just WAY too complicated. Sure, Jigsaw, Eleventy, Nunjucks and the many others are useful. But I didn’t want this big a dependency for these small sites.

But then I realised that the popular back-end PHP language does this job already. It’s original purpose was as a templating language. So why don’t I just use that?

So I wrote a super-simple static site generator in about 160 lines of PHP.

This not only lets me use templating, but also lets me have partials/components with parameters. Perfect for Tailwind!

Pulling it all together

So we have all the building blocks:

  • HTML, CSS, vanilla JavaScript
  • TailwindCSS – my only real dependency
  • AlpineJS – which is a dependency if you want it, but it just gets included from a CDN so there’s no build process
  • My simple PHP static site generator – which isn’t a dependency as such, but does have a build step

To pull this all together I just use a couple of bash scripts.

build.sh does a development build

prod.sh does a production build (if this needs to be different)

This isn’t quite a perfect process. It needs a little more refinement. But I wanted to share it with you. I have kinda hastily thrown together a Git repository with all this ready to go:

https://github.com/rosswintle/small-site-template

A quick npm install on a fork or clone of the repo, followed by a ./build.sh should deliver you a working site.

The aim is NOT that you include this as a dependency of your project. But you fork it and make it your own. This is a template for you to take off in whatever direction you choose.

Examples

You want to see this in action? Sure thing. Here’s some examples of where I’ve used some or all of this tech stack to make real things.

Go forth, and build uncomplicated websites

The web doesn’t have to be complicated. My process here is, if anything, still over-complicated. But I’ve stripped down the tech to the minimum that I need to be productive building small sites.

I don’t use WordPress unless I need to. I don’t need databases and logins and servers to host on. And I’m free to build and experiment quickly with these tools, which generate sites which will last and where I hope the tooling is sustainable and the projects easy to return to at a later date if I need to.

I was inspired to finally finish and publish this post by various sentiments I’ve seen on Twitter in the last week or so. At one end are people saying “web dev is never finished because it’s constantly evolving”. And at the other end are people saying it’s taboo that “you don’t need a frameworks” and “this is how we USED to build the web” (emphasis mine).

But HTML, CSS and JS are stable technologies. They are evolving, but they will always have great backwards compatibility. These things won’t break!

And we don’t need to be ashamed of this approach – you should develop simple sites with pride! – and it can be how we build the web now!

So go and do so. And let me know how you get on.