Library / SDK
edicl/hunchentoot avatar
edicl/hunchentoot

Hunchentoot: a Common Lisp web server and dynamic site toolkit

Web server written in Common Lisp

753 stars132 forksCommon LispLicense varies

At a glance

What is it?
Hunchentoot is a web server written in Common Lisp that also serves as a toolkit for dynamic sites, with session handling, logging, error handling and request parameter access. It deliberately leaves HTML generation to other libraries and cannot be implemented in fully portable Common Lisp because it uses TCP/IP sockets and multiprocessing.
Who is it for?
Adopt Hunchentoot if you are writing a Common Lisp web application and want the server layer, sessions, logging and request handling in the same language as the rest of your code, since the BSD-style licence leaves you free to do whatever you want with it.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 174 days ago.
What is it written in?
Mainly Common Lisp, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A server and a site toolkit in one package

Hunchentoot is a web server written in Common Lisp and, at the same time, a toolkit for building dynamic websites. That double description is the accurate one, because the package does the transport and the request plumbing and leaves the page generation to you.

As a stand-alone web server it is capable of HTTP/1.1 chunking in both directions, persistent connections with keep-alive, and SSL. Those three are the features you would look for first in a server that has been in use for a long time, and none of them are exotic.

The toolkit side covers the facilities a dynamic site needs and that you would otherwise write yourself. There is automatic session handling, with and without cookies. There is logging. There is customizable error handling. And there is easy access to the GET and POST parameters sent by the client.

The exclusion is stated just as plainly as the inclusions. Hunchentoot does not include functionality to programmatically generate HTML output, and for that task you can use any library you like, with CL-WHO and HTML-TEMPLATE both given as examples, and both hosted by the same author as separate projects.

That boundary is a design position rather than an omission. The server deals with sockets, sessions and requests, and the view layer is a separate choice you make per project.

Why it cannot be fully portable Common Lisp

The next paragraph of the documentation is the one that tells you what kind of project this is. Hunchentoot talks with its front-end or with the client over TCP/IP sockets, and optionally uses multiprocessing to handle several requests at the same time. Therefore, it cannot be implemented completely in portable Common Lisp.

The consequence is stated with the alternatives that do work. It currently works with LispWorks, and with all Lisps that are supported by the compatibility layers usocket and Bordeaux Threads.

So the portability story is a compromise with a clear shape. If you run LispWorks, it works as a native product. If you run another Common Lisp, you need a socket library and a threading library that the project supports, which is the standard way Lisp implementations have papered over the gaps in the standard for years. If you need a build that is portable Common Lisp and nothing else, this is not the server for you, and the reason is architectural rather than a missing feature.

The optional use of multiprocessing is worth separating from the requirement, because the sockets are the hard constraint and the multiprocessing is a choice. A deployment that serialises requests can still run on a Lisp with usocket and Bordeaux Threads, at the cost of concurrency.

The primary language is Common Lisp, the default branch is master, and the licence is described as BSD-style, with the documentation saying you can basically do with it whatever you want.

The file layout maps the feature list onto the source

The top level of the repository is a good index of what the server does, because the source files are named after the facilities rather than hidden behind a package namespace.

There is session.lisp and cookie.lisp, which together cover the session handling with and without cookies. There is log.lisp for the logging, conditions.lisp for the customizable error handling, and specials.lisp for the package exports. There is request.lisp and reply.lisp for the two halves of the HTTP exchange, headers.lisp for header handling, and mime-types.lisp for content type mapping. acceptor.lisp is the socket accepting side, taskmaster.lisp is the concurrency layer, set-timeouts.lisp handles the timeout configuration, and ssl.lisp covers SSL.

Two files are unusual enough to be worth naming. easy-handlers.lisp is a convenience layer for writing handlers, and util.lisp holds general utilities. Then there is compat.lisp, which is the compatibility layer for the different Lisp implementations, and lispworks.lisp, which holds the LispWorks-specific code. That pair is the concrete expression of the portability discussion above.

The url-rewrite/ directory is a separate feature area rather than a file, and the test/ directory holds the test suite, with run-test.lisp as its entry point. There is also a make-docstrings.lisp script and a docs/ directory with the documentation, and hunchentoot.asd, which is the ASDF system definition that makes the package loadable by any Common Lisp implementation with a working ASDF.

The CHANGELOG and CHANGELOG_TBNL at the top level are two different files, and the second name suggests it tracks changes to a next version. The release-checklist.txt file is the maintainer's own process documentation for cutting a release.

What to read before you install it

The documentation says that complete documentation for Hunchentoot, including details about how to install it, can be found in the docs directory of the repository or at the project website, and the website is the linked homepage.

That is where the installation instructions live, and it is the honest answer to how you get this running. There is no pip-style single command in the README, because a Common Lisp system is loaded through ASDF and then the application framework is started from your own code, and the specifics of how the two fit together depend on the Lisp you are using and on the version of the package you check out.

The project site is edicl.github.io/hunchentoot, and the same address is the repository's homepage field, so the docs and the site are the same resource in two forms.

The release history is worth noting before you pin a version. Version 1.2.38 dates from 2017-12-03, version 1.3.0 from 2020-05-07, and version 1.3.1 from 2024-04-27. The last push to the repository was on 2026-05-04, so there is work on the branch after the last tagged release, and the repository publishes no GitHub releases of its own beyond those tags.

A library that was last tagged in 2024 and last touched in 2026 is a reasonable read for a stable server component. It is the sort of dependency where the changelog matters more than usual, so reading CHANGELOG and CHANGELOG_TBNL before upgrading is the sensible first step.

Where Hunchentoot is the wrong tool

The first wrong case is a project that wants one package to do everything. The server does not generate HTML, so a team looking for a single dependency that gives them routing, templating and a server is looking at the wrong shape of tool. CL-WHO and HTML-TEMPLATE are separate installs, and you assemble the stack yourself.

The second is a portability requirement. If your deployment target is restricted to portable Common Lisp, or if you are on a Lisp that neither usocket nor Bordeaux Threads supports, Hunchentoot is not usable as it stands. The socket requirement is not negotiable.

The third is a concurrency expectation. Multiprocessing is described as optional, and the whole model is threads over sockets. A workload that is CPU-bound rather than IO-bound, such as heavy computation per request, is a poor fit for a threaded server without a separate process pool, and the documentation does not describe one.

The fourth is a modern deployment environment. This is a server library with no container image, no process manager, no configuration format and no health endpoint, which means all of that work is yours. There is also no TLS termination story beyond the ssl.lisp file, and no HTTP/2.

The alternative worth weighing is a Common Lisp web framework that includes the view layer and the routing, where you trade the small, focused server for a larger opinionated one. Hunchentoot is the choice when you want the plumbing and nothing else, and it is old enough and stable enough to be the boring choice.

Editorial conclusion

Adopt Hunchentoot if you are writing a Common Lisp web application and want the server layer, sessions, logging and request handling in the same language as the rest of your code, since the BSD-style licence leaves you free to do whatever you want with it. Step back if you need HTML generation included, because the project explicitly leaves that to libraries such as CL-WHO or HTML-TEMPLATE, or if your deployment must be fully portable Common Lisp with no socket or threading extensions. Before you plan an upgrade, read the CHANGELOG and CHANGELOG_TBNL at the top of the tree, since the last release is 1.3.1 from 2024-04-27 while the last push was on 2026-05-04 and the two changelogs track different things.

Frequently asked questions

What is Hunchentoot and what does it provide?

It is a web server written in Common Lisp that doubles as a toolkit for dynamic websites. It provides automatic session handling with and without cookies, logging, customizable error handling, and easy access to GET and POST parameters, and as a server it supports HTTP/1.1 chunking in both directions, keep-alive and SSL.

Does Hunchentoot generate HTML for me?

No. The documentation is explicit that it does not include functionality to programmatically generate HTML output, and suggests using any library you like, giving CL-WHO and HTML-TEMPLATE as examples. You assemble the view layer separately from the server.

Which Common Lisp implementations does Hunchentoot run on?

It works with LispWorks, and with Lisps supported by the usocket and Bordeaux Threads compatibility layers. It cannot be implemented completely in portable Common Lisp because it uses TCP/IP sockets and optionally multiprocessing.

How do I install Hunchentoot?

The README points to the docs directory of the repository and to the project website at edicl.github.io/hunchentoot for the complete documentation including installation details. The package is defined by hunchentoot.asd, so it is loaded through ASDF like other Common Lisp systems.

Official sources

  1. edicl/hunchentoot on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/edicl-hunchentoot.svg)](https://hysenlabs.com/projects/edicl-hunchentoot)

Was this useful?