HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
weavejester
hiccup
Clojure2010–2025
weavejester / hiccup

hiccup

Fast library for rendering HTML in Clojure

59Distinct people
64Mentions
1Explicit recommenders
2.9KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Fast library for rendering HTML in Clojure

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

Do you have a github repo for your project ? Or somewhere where I can take a look at the code ? I was hoping to find the time to write something similar in Clojure (a lisp…

siscia used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year64 dated mentions

Observed mentions: 2010-04-26 15:18:06 UTC to 2025-12-03 19:46:10 UTC.

0369122010-01-01 00:00:00 UTC to 2011-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20102011-01-01 00:00:00 UTC to 2012-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2012-01-01 00:00:00 UTC to 2013-01-01 00:00:00 UTC (exclusive): 11 mentions; 0 submissions, 11 comments2013-01-01 00:00:00 UTC to 2014-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20172018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 6 mentions; 0 submissions, 6 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 6 mentions; 0 submissions, 6 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 6 mentions; 0 submissions, 6 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20102010-01-01 00:00:00 UTC2011-01-01 00:00:00 UTC202
20112011-01-01 00:00:00 UTC2012-01-01 00:00:00 UTC101
20122012-01-01 00:00:00 UTC2013-01-01 00:00:00 UTC11011
20132013-01-01 00:00:00 UTC2014-01-01 00:00:00 UTC404
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC303
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC404
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC101
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC202
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC404
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC606
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC707
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC606
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC110
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC606
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC404
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC211

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
Hiccup Hiccup is a library for representing HTML in Clojure. It uses vectors to represent elements, and maps to represent an element's attributes. Install Add the following dependency to your deps.edn file: hiccup/hiccup {:mvn/version "2.0.0"} Or to your Leiningen project.clj file: [hiccup "2.0.0"] Documentation Wiki API Docs Syntax Here is a basic example of Hiccup syntax: user=> (require '[hiccup2.core :as h]) nil user=> (str (h/html [:span {:class "foo"} "bar"])) "<span class=\"foo\">bar</span>" The first element of the vector is used as the element name. The second attribute can optionally be a map, in which case it is used to supply the element's attributes. Every other element is considered part of the tag's body. Hiccup is intelligent enough to render different HTML elements in different ways, in order to accommodate browser quirks: user=> (str (h/html [:script])) "<script></script>" user=> (str (h/html [:p])) "<p />" And provides a CSS-like shortcut for denoting id and class attributes: user=> (str (h/html [:div#foo.bar.baz "bang"])) "<div id=\"foo\" class=\"bar baz\">bang</div>" If the body of the element is a seq, its contents will be expanded out into the element body. This makes working with forms like map and for more convenient: user=> (str (h/html [:ul (for [x (range 1 4)] [:li x])])) "<ul><li>1</li><li>2</li><li>3</li></ul>" Strings are automatically escaped: user=> (str (h/html [:p "Tags in HTML are written with <>"])) "<p>Tags in HTML are written with &lt;&gt;</p>" To bypass this, use the hiccup2.core/raw function: user=> (str (h/html [:p (h/raw "Hello <em>World</em>")])) "<p>Hello <em>World</em></p>" This can also be used for doctype declarations: user=> (str (h/html (h/raw "<!DOCTYPE html>") [:html {:lang "en"}])) "<!DOCTYPE html><html lang=\"en\"></html>" Differences between Hiccup 1 and 2 In brief: Hiccup 1 doesn't escape strings by default, while Hiccup 2 does. They occupy different namespaces to ensure backward compatibility. In Hiccup 1, you use the h function to escape a string - that is, ensure that unsafe characters like <, > and & are converted into their equivalent entity codes: (h1/html [:div "Username: " (h1/h username)]) In Hiccup 2 strings are escaped automatically, but the return value from the html macro is a RawString, rather than a String. This ensures that the html macro can still be nested. (str (h2/html [:div "Username: " username])) It's recommended to use Hiccup 2 where possible, particularly if your app handles user data. Use of the non-core namespaces, such as hiccup.page, should be avoided with Hiccup 2. License Copyright © 2025 James Reeves Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.
Read the full README on GitHub

What Hacker News says

64 sources

Show HN: Niccup – Hiccup-Like HTML Generation in ~120 Lines of Pure Nix

Yesterday I saw https://news.ycombinator.com/item?id=46121799 (Nixtml: Static website and blog generator written in Nix) and before I clicked on it, I thought it was gonna be a polished version of something I've hacked together myself in the past few weeks, but it was something else, so since seeing it, I've been polishing my hacked together Hiccup-alternative made with Nix, and I think it's good enough for some feedback from the outside world :) The basic premise is to take a Nix expression like this: [ "div#main.container" { lang = "en"; } [ "h1" "Hello" ] ] And turn it into HTML like this: <div class="container" id="main" lang="en"><h1>Hello</h1></div> Nothing more, nothing less. Just "Nix Expressions/Data > HTML". If you've used hiccup (https://github.com/weavejester/hiccup) before this will be immediately familiar to you, n
Read the rest
ative data types in arrays transformed into HTML, and it matches really well with Nix! Kind of almost took me by surprise. I've made some more involved examples available on the website, where the website itself is also dynamically generated with niccup: https://embedding-shapes.github.io/niccup/ And if that wasn't enough, I also added a quine example on the website itself, which if you copy-paste the two files you get a built version of the page itself: https://embedding-shapes.github.io/niccup/examples/quine/ (this was probably the most tricky and fun part of this whole project, so worth mentioning separately for sure) I've used it to generate documentation websites and some smaller projects so far, but hasn't been used by others before, so I'm eager to hear what people think about it! Thank you for reading and your temporary attention! GitHub repository: https://github.com/embedding-shapes/niccup (~800 lines of Nix in total, main implementation src/lib.nix is only ~120 lines though) The source of the blog itself: https://github.com/embedding-shapes/embedding-shapes.github.... (~150 lines of Nix)
2 points · Open discussion
Look at that, you almost reinvented `hiccup` (https://github.com/weavejester/hiccup) :) Taking things a bit further, you get an almost full copy of hiccup, and can save even more space and make it even simpler: [div.card [h3 "Familiar browsing experience"] [p "Clear real-time audio...."]] Removing the closing elements, make children nested without opening/closing brackets, make strings explicit and you're done! (only difference is hiccup/clojure would make you use :div and :h3 instead, as they're keywords)
In Ask HN: What if we wrote HTML with [brackets][/brackets]?
The Clojure's approach is to favour libraries over frameworks. We use Clojure on various style of applications (mainly web and API based), hosted on widespread infrastructure technologies of Cloud Providers (Kubernetes, PostgreSQL, Kafka, etc.) and it's a breeze: here are our reasons for choosing Clojure https://defsquare.com/blog/why-we-bet-on-clojure If you want to look at libraries where some people have settled, here are our _opinionated_ takes on libraries that we use on almost every project: - HTTP: Ring is the de facto way to manage HTTP request (see https://github.com/ring-clojure/ring/wiki/Concepts) supplemented with various "Middlewares" for web-related concerns (security, logging, content encoding, etc. see https://github.com/ring-clojure/ring/wiki/Standard-middlewar...). Jetty and Aleph are common web servers (and https://gith
Read the rest
ub.com/clj-commons/aleph) that implement Ring interface. - Routing: Reitit (https://github.com/metosin/reitit) - Single-Page App: shadow-cljs for the build concerns (https://github.com/thheller/shadow-cljs), Reagent with Re-frame for complex/large app (https://reagent-project.github.io and https://github.com/day8/re-frame). Even if we now prefer using HTMX (https://htmx.org) and server-side rendering (Hiccup way of manipulating HTML is just amazing, https://github.com/weavejester/hiccup). - Schema management: Malli (https://github.com/metosin/malli) - Lifecycle management: Mount, Integrant or Component (https://github.com/tolitius/mount https://github.com/weavejester/integrant and https://github.com/stuartsierra/component) - Config management: Aero (https://github.com/juxt/aero) and environ (https://github.com/weavejester/environ) - Log: μ/log (https://github.com/BrunoBonacci/mulog) - Time: https://github.com/juxt/tick - Testing: https://clojure.github.io/clojure/clojure.test-api.html and Kaocha for the runner (https://github.com/lambdaisland/kaocha). - Package and project management: tools.deps is simple and powerful (https://clojure.org/guides/deps_and_cli) For infrastructure stuff (PostgreSQL, Keycloak, Solr, Kafka, etc.), just wrapping the underlying Java library or driver is often enough, and there are lots of wrappers for easing the integration. And we implement Hexagonal architecture style to put all of that in place. Don't be afraid a libraries not moving a lot recently, it's a sign that the library is mature and battle-tested. Clojure is a joy to use every day :)
In A History of Clojure (2020) [pdf]
That is why I like Hiccup/ Clojure so much: https://github.com/weavejester/hiccup It is very natural to produce something resembling a document in pure Clojure data structures and then just convert it to valid HTML. I think, Reagent has some hiccup extensions that are nice like writing the class or id with a . or # notation right in the keyword describing the tag. So there probably still is some space to improve the ergonomics and probably performance. Concatenating strings still wins performance wise by a lot.
In That people produce HTML with string templates is telling us something

Showing the 15 most recent of 64 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.