At a summer barbecue, a friend asked if I could build a website for his new restaurant. But what he didn't know was that I haven't built a static site in nearly a decade. However I couldn't let him spend thousands of dollars on a cookie cutter website designed by a firm that knew nothing about his restaurant.

We started coming up with ideas right away over a couple of beers. He wanted manageable content, an Instagram feed, and an easy to change restaurant menu. It quickly started sounding like a full on Content Management System and not a simple website. I had to reel in this ambitious project before it became a feature sink. So we decided to just make a beautiful static site.

I started using Wordpress to build the website because I've used it in the past and it's easy to expand. With a list of dream features in mind, a basic website quicky emerged. But as it grew, themes became complicated to build. Plugins were ugly and difficult to customize. And templates were clunky to use. I couldn't continue with the Wordpress route.

Having been spoiled by component based systems, I decided to try Next.js. I use React in my day job, so it's familiar ground, but I couldn't justify the complexity for a website that didn't need dynamic content. Also, Next.js had no CMS support.

That's when I decided to reach for hiccup, a Clojure library for generating server side content. hiccup let me use Clojure data structures to build my pages.

1 2 ;; generating a span element with the class `foo` and content of `bar` ( html [ :span.foo "bar" ])

This short syntax let me express more with less code. I also had components.

1 2 3 4 5 6 7 ;; defining an `h1` variable with the content `Welcome` ( def header [ :h1 "Welcome" ]) ;; using `header` variable inside a `div` with an additional paragraph ( html [ :div.content header [ :p "more content" ]])

I could define functions or plain variables, then use them as components in my templates.

On top of that, I didn't have to learn a special syntax for working with data. I had the full power of Clojure to interact with data and components themselves.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 ;; defining data for the menu ( def menu-items [ "Crab Rangoon" "Pot Stickers" "Miso Soup" ]) ;; creating a function to generate a list elment from the provided `menu-item` ( defn create-menu-item [ menu-item ] [ :li.menu-item menu-item ]) ;; generating an unordered list by mapping over the `menu-items` data ( def menu [ :ul ( map create-menu-item menu-items )])

I could do all this with a concise syntax that is simpler than Wordpress templates, and shorter than React components.

The final benefit is the ease of mind provided by Clojure. I know that no matter what features we dream up, they will be possible with this general purpose language.