Soupault (soup-oh) is a tool that helps you create and manage static websites.

It's best described as a robotic webmaster. Like a human webmaster, it understands HTML, but doesn't get tired of editing it. You can tell it to do things like insert the HTML from footer.html after the last element in the page <body>.

Traditionally, there was a dichotomy between unlimited possibilities of handwritten Web 1.0 pages and convenience of “cookie cutter” tools (CMSes and classic static site generators). People often had to add JavaScript to non-interactive pages if they wanted a good table of contents, syntax highlighting and so on. Soupault removes that dichotomy: it can do all the DOM manipulation you could do with JavaScript, but the result is a static page.

It can generate complete pages from a “theme” and content files, automatically modify existing pages, and extract site metadata.

Soupault is...

To get started, install soupault from a release archive or with a package manager. Then run soupault --init in an empty directory to initialize a basic project, and then run soupault in that directory to build it. Generated pages will be in build/.

Then read the quick start guide to learn how to set up a simple blog. If you want to automatically deploy your site with Netlify, GitHub Actions or similar, also read the deployment tips.


Most static site generators are essentially CMSes that generate all pages at once rather than on demand. HTML is an opaque format to them: they can generate it using a template processor, but they cannot manipulate it. This limits what you can do with them: for example, pages with a unique design can only be included as static assets.

Soupault makes HTML a first-class citizen. Like web browsers, it can parse HTML and manipulate the element tree of the page. However, it saves the result in a static page rather than displays it on screen.

This allows features like footnotes with automatic links in both directions, and even an option to delete unwanted HTML elements. It also means all features work the same regardless of the content file format.1

You can also use soupault as a post-processor for an existing website, whether hand-written or generated by another tool.

It also helps you avoid unnecessary client-side JavaScript and create pages designed to last.

Dependency-free and future-proof

Soupault is available as a single, statically linked executable (~16 MB) for Linux, macOS (x86_64 only, so far), and Microsoft Windows (64-bit). It means you can keep using soupault indefinitely even if it becomes unmaintained, and you are never forced to upgrade just to keep using it.

It's easy to install on your own computer or incorporate in a CI script. Just download and unpack a release archive and it's ready to use.

Even though you are never forced to upgrade to a new version, soupault tries to make upgrading as easy as possible too. The maintainer uses semantic versioning, properly marks backwards-incompatible releases with a major version change, and documents breaking changes.


Soupault aims to do one thing: manipulate HTML element trees offline, and do it well.

It purposely doesn't include things like a development web server, a Sass compiler, or an image processing library. It avoids bloating the executable with built-in functionality that only some users will want, and that some users will want to work different from the built-in.

Instead, it makes it easy to plug your own tools into the pipeline. Statically linked and dependency-free doesn't have to mean “not extensible”. Soupault is extensible in several ways.



Soupault comes with an embedded Lua interpreter, so it can be extended with plugins. Its API is similar to the JavaScript DOM API and allows you to manipulate pages in arbitrary ways.

There are many things plugins can do. They can expand custom elements to real HTML (think a static version of web components, or shortcodes on steroids). They can also call external programs, read data from files, and modify the entire page: not just the content, but also the HTML coming from the page template.

Page preprocessors

Soupault only supports HTML internally, but it allows you to bring your own page preprocessors.

Thus it's possible to write pages in any format. Want to use CommonMark? Install cmark and add this to your soupault.conf:

  md = "cmark --unsafe --smart"

Now all Markdown pages with .md extensions will be automatically converted to HTML by piping them through cmark --unsafe --smart command.

You can use any external program as a page preprocessor, and you can have as many preprocessors as you want. Whether you are a fan of Pandoc, AsciiDoctor or something else—as long as it can read from standard input and write HTML to standard output, you can use it as a preprocessor.

Element preprocessors

It's also possible to pipe HTML elements through external programs. Those programs have access to the element tag names and attributes via environment variables.

This is how you can add syntax highlighting to code samples in <pre class="language-something"> elements. Assuming you have highlight and sed installed:

# Runs the content of <* class="language-*"> elements through a syntax highlighter
  widget = "preprocess_element"
  selector = '*[class^="language-"]'
  command = 'highlight -O html -f --inline-css --syntax=$(echo $ATTR_CLASS | sed -e "s/language-//")'
  action = "replace_content"

Content model

Soupault allows you to define your own content model. There is no front matter, metadata is extracted directly from HTML using CSS selectors, similar to how microformats and web scrapers work.

For example, this is how you can say use <h1 id="post-title"> for the post title if a page has one, else just use <h1>:

  title = { selector = ["h1#post-title", "h1"] }

Extracted metadata can be rendered on pages using a built-in template processor or an external script. You can also export it to a JSON file for further processing.

Ready to start?

First, install soupault from a release archive or using a package manager.

Then read a step by step tutorial for a quick start.

You can also browse the source of this website and play with it, or check out websites of other soupault users.

Then read the reference manual for details. There's also a blog and a section with tips and tricks.

Why it's named soupault?

Soupault is named after the French dadaist and surrealist writer Philippe Soupault because it's based on the lambdasoup library. Its development is sponsored by the College of 'Pataphysics.2


Soupault logo is a stick horse. It's a reference to the meeting where Philippe Soupault et al. chose a name for their movement by opening a dictionary at a random word and landed on dada (n.), a colloquial for a stick horse, which is why they named it “dadaism”.

If you are using soupault for your site or want to raise awareness of it, feel free to put a button there.

Who's behind it?

So far just me, Daniil Baturin, but everyone is welcome to send a patch/pull request or a suggestion. It has grown out of the bunch of ad hoc scripts that used to power my own website, and then I thought I can as well make it usable for everyone who finds other generators too annoying or too limiting.

Feel free to contact me.

1In some other projects you may see a situation when both Markdown and reStructuredText are technically supported, but tables of contents or footnotes only work for Markdown because it's an opaque feature of their Markdown processor. There's no such problems in soupault.

2Not really.