Skip to main content
This walks through a small project from an empty directory to a rendered page. It takes about five minutes and requires only a terminal.
1

Install the compiler

That gives you a binary named slurp. Check it:
For options that do not need a Rust toolchain, see Installation.
2

Create a project

Slurp has no scaffolding command and no config file to start with. A project is a directory of .slurp files, and everything else is convention.
3

Write a page

Create pages/index.slurp:
pages/index.slurp
Three constructs are in use. ${ } interpolates a value and escapes it for wherever it lands. {each} loops, with {empty} as the branch taken when there is nothing to loop over. | sort and | currency are filters, which transform a value on its way out.
A pages/ directory is a convention rather than a requirement. Slurp emits an HTML file for every .slurp file except those under components/ and layouts/, so a file at the root would work too. Use pages/ anyway: the dev server in step 8 only serves routes from there.
4

Give it some data

A template renders against a JSON context. At build time that comes from a file:
data.json
Every top-level key becomes a global the template can read, which is why site and products resolve above.
5

Build it

dist/pages/index.html
The output is minified, and the sort filter ordered the products cheapest first. ${ } escaped everything on the way out, so a product named <script> renders as text rather than as a tag.
Add --verbose while developing. Slurp fails quietly, and --verbose turns silent truncations and unresolved values into printed warnings.
6

Extract a component

Once the same markup appears twice, move it into components/.
components/Product.slurp
Then use it from the page:
pages/index.slurp
Write product={product}, with braces. A quoted prop is a literal string, so product="product" passes the seven-character word rather than the object. This is the most common Slurp mistake and it fails silently.
Files under components/ are not pages. Slurp checks them and does not emit an HTML file for them.
7

Add a layout

A layout holds the chrome that every page shares.
layouts/base.slurp
<slot /> is where the page gets placed. The page now carries only its own content:
pages/index.slurp
Rebuild and the HTML is the same as before.
A layout does not receive props. Passing one has no effect, and a props default declared inside a layout is never applied either. Read shared values from page globals instead, or use a component, which does receive props and does apply their defaults.
8

Iterate with the dev server

The dev server serves built output, not .slurp sources, so build first and point it at dist:
That serves http://localhost:3000 and reloads the page when the output changes. It resolves a route by looking under pages/ in the directory it is serving, which is why step 3 put the page there.
slurp dev is a thin wrapper with only --port, --bind and --fixtures, and --bind is currently accepted and ignored. The full dev server is a separate binary, slurp-dev, which adds --theme-dir, --source-dir, --globals, --backend-url and a CSS watch command. See Dev server.

Result

Next

Project structure

Special directories, output paths, and static assets.

Displaying data

Expressions, property access, and operators.

Common mistakes

The silent failures, collected in one place.

Filters

Formatting values, and literal filter arguments.

Data in production

--globals is build-time data, which suits a static site. When Slurp is embedded in a server, the context arrives per request from the host instead and --globals covers only values that must be resolved at compile time. See Embedding with Rust for that path.