# The Strand guide

This guide takes you from `strand new` to a full desktop shell in five
levels. Each level teaches a handful of ideas and ends with something
you can use. Levels 1 to 3 build one bar, on every monitor, with
workspace dots, the focused window's title, a clock with a calendar
popup, a volume slider, the battery and the tray. Level 4 adds the
surfaces that come and go (an on-screen display, notifications, a
launcher, a lock screen and an admin password dialog) and a settings
window, and level 5 your own theme, services, a control centre and a
dock.

Nothing at level N+1 appears in a level-N example. If you stop after
any level, everything you have written still works.

| Level | You learn | You build | Page |
| --- | --- | --- | --- |
| 1 | Surfaces, nodes, props, services as live values | The hello bar | [level-1.md](/guide/level-1.html.md) |
| 2 | `$tokens`, `component`, `for`, `when`, `on click` | Workspace dots, tray | [level-2.md](/guide/level-2.html.md) |
| 3 | `state`, `<->`, `if`, `popup`, `enter` | Clock with calendar, volume slider | [level-3.md](/guide/level-3.html.md) |
| 4 | `on change … after`, `after … while`, `persist`, `export`, `list`, `Async` | OSD, notifications, launcher, lock screen, password dialog, settings window | [level-4.md](/guide/level-4.html.md) |
| 5 | `tokens`, spring overrides `~`, `service from dbus`, `pages`, drag and drop, shaders, `file` | Control centre, dock, custom services | [level-5.md](/guide/level-5.html.md) |

## Every construct and its level

The constructs the "You learn" column does not name are taught at
these levels.


| Level | Also taught here |
| --- | --- |
| 1 | `split` (with `start`, `center`, `end`); comma shorthands; expressions (`?.`, `??`, operators, calls such as `pct` and `join`) |
| 2 | `on secondary`; `hit:`; the node booleans `hover` and `pressed` |
| 3 | assignment and compound assignment (`=`, `+=`, `-=`, `*=`, `/=`); `else`; `exit`; `on scroll(dy)` |
| 4 | `let`; `enum`; `match`; `every … while`; `on show`; `id:`; `@reset`; lambdas (`n => …`); `await`; the `lock` and `window` surfaces |
| 5 | `set { }`; `keyframes` and `play`; `canvas`; `type` and `key`; `slot`; `fn`; a node's `box` and `pointer`; settings files (`state x from "file.toml" { … }`); SVG layer selectors (`#name { … }`); `service … from file`, `from dir`, `from listen`, `from poll` and `permit exec`; `action` |

## How to read the code blocks

Every code block marked `strand` is the **whole** file it names, as it
should be after that step. Copy it over the file and save; you never
merge a fragment by hand. The block's tag says its level and its file:

````
```strand level=2 file=dot.strand
component Dot(ws: Workspace) { … }
```
````

Steps run in page order, level 1 first. A file a step does not show
stays as it was.


A step can also need a file that is not `.strand`, such as level 5's
template. Its block is tagged with its own language and the same
`level=` and `file=`, and is that file's whole content too:

````
```css level=5 file=colors.css.tmpl
:root { … }
```
````

Short pieces of syntax inside a sentence (`when hover { … }`), and
untagged blocks (commands to type, keybind lines for your compositor),
are not steps.

## What you need

- A Wayland compositor with layer-shell, such as sway, Hyprland, niri
  or labwc, the four Strand is tested on. GNOME does not offer
  layer-shell.
- The `strand` binary on your `PATH`. There is no release yet, so
  either build it from a checkout of the repository with
  `cargo build --release -p strand` (it lands in
  `target/release/strand`), or take the
  [prebuilt binaries](/start/install.html.md#prebuilt-binaries)
  and rename `strand-gpu` in them to `strand` (`strand-cpu` is the
  same without the GPU backend). `strand --version` tells you it is found.

Then start at [level 1](/guide/level-1.html.md).

## More pages

- [Plugins](/guide/plugins.html.md): a service written in Rust and built into your
  own `strand` binary (level 5, section 7).
- The language itself, in full: [`docs/spec.md`](https://github.com/jakeb-grant/strand/blob/main/docs/spec.md) for what
  each construct means, [`docs/grammar.md`](https://github.com/jakeb-grant/strand/blob/main/docs/grammar.md) for how it
  is written.
- Every element, prop, service, type, function and token, with its
  doc: [`docs/reference/`](https://github.com/jakeb-grant/strand/blob/main/docs/reference/README.md), generated from the
  schemas by `strand-dev reference`.
