A static website generator for people who enjoy the simpler things in life.

Version 6.0.0


Ivy borrows its idea of themes from WordPress where a theme is a directory of templates, styles, and scripts that together provide the look and feel for a site.

A site's theme is completely independent of its content.

This idea is central. You can swap between themes and completely change the appearance of your site without touching its content.


Themes should be placed in the site's lib directory, and the name of the active theme directory specified in the site's configuration file.

theme = "graphite"

Ivy ships with a small collection of bundled themes including graphite, the default theme you're looking at right now, and debug, a diagnostic theme useful when designing themes or debugging sites.

Note that you can override the currently active theme with the build command's --theme flag:

$ ivy build --theme debug

Ivy searches for a named theme first in the site's theme library, then (if it exists) in the global theme library specified by the $IVY_THEMES environment variable. Finally it searches among the default themes bundled with Ivy itself.


Ivy looks for three subdirectories within the theme directory: resources, templates, and extensions.

Template Files

Template files provide the HTML scaffolding for constructing pages — you can think of a template file as the mould into which your content will be poured.

There are countless templating languages and Ivy can use any of them, but it has builtin support for Jinja and Ibis. Ivy determines the language of a template file by looking at its extension — .jinja for Jinja and .ibis for Ibis.

You can add support for alternative templating languages via plugins.

Template Hierarchy

When Ivy generates a HTML page for a node it searches for the appropriate template file to use in reverse order of specificity.

For example, the node file:


corresponds to the node:

<Node @root/foo/bar/baz//>

Ivy will search for a template file for this node in the following order:

1. node-foo-bar-baz.*
2. node-foo-bar.*
3. node-foo.*
4. node.*

A node can override this process by specifying a custom template file in its header:

template: my-custom-template

Note that the file extension should be omitted from the template name.