Step-by-step introduction to graphden: text lessons, most of them paired with a guided in-editor tour (the ▶ column below).
Audience: someone who can program but has never seen graphden before. Each lesson assumes the previous ones and nothing else from the project docs.
Read them top to bottom — the table is in teaching order, in the same
five chapters the in-editor picker uses, and the numbering is
sequential in that order: the number is the file name, the deep link
(?tutorial=13), and the tour’s :id. Inserting a lesson mid-sequence
renumbers everything after it — that is a mechanical, repo-wide
search-and-replace (ids appear only in file names, links, tour :ids and
prose references), so keep the numbers honest rather than appending out
of order.
| # | Lesson | Status |
|---|---|---|
| 01 | Anatomy of a fn-def | ✅ written · ▶ interactive |
| 02 | Parents and inheritance — single parent, then multiple | ✅ written · ▶ interactive |
| 03 | Slots and bindings — what they are at the data level | ✅ written · ▶ interactive |
| 04 | Free arguments and how they propagate | ✅ written · ▶ interactive |
| 05 | Types — atomic, refinement, record, union, variant, list | ✅ written · ▶ interactive |
| # | Lesson | Status |
|---|---|---|
| 06 | Higher-order functions and :fn-typed slots |
✅ written · ▶ interactive |
| 07 | Composing pages from components | ✅ written · ▶ interactive |
| 08 | The :custom-script escape hatch |
✅ written · ▶ interactive |
| 09 | State — cells, swap, and a graph-native cache | ✅ written · ▶ interactive |
| 10 | Recursion: loops without cycles | ✅ written · ▶ interactive |
| 11 | Live fragments: htmx from the graph | ✅ written |
| # | Lesson | Status |
|---|---|---|
| 12 | Executing a fn — free-arg form, history, cancel | ✅ written · ▶ interactive |
| 13 | Effects and the :secret type-marker |
✅ written · ▶ interactive |
| 14 | Tests — the tests namespace |
✅ written · ▶ interactive |
| 15 | Debugging: traces, the call tree, and catching a request | ✅ written · ▶ interactive |
| 16 | When something breaks, and when it just repeats: the problem lenses | ✅ written · ▶ interactive |
| # | Lesson | Status |
|---|---|---|
| 17 | Finding your way: the lens and the Inspector | ✅ written · ▶ interactive |
| 18 | Working without the mouse — keyboard & accessibility | ✅ written · ▶ interactive |
| 19 | Workspaces — scope the editor to your projects | ✅ written · ▶ interactive |
| 20 | Branches — fork, edit, diff, merge | ✅ written · ▶ interactive |
| 21 | Review — propose, approve, protected merge | ✅ written · ▶ interactive |
| 22 | Editing the editor: asset overrides | ✅ written · ▶ interactive |
| 23 | Version history: what changed, and going back | ✅ written · ▶ interactive |
▶ interactive — the lesson also exists as a guided in-editor tour:
open the editor with ?tutorial=NN (the landing demo link does this for
Lesson 01), or pick “Interactive tutorial” in the account-chip menu —
in an organization workspace the lesson runs on its own tutorial-NN-*
branch, and ending it offers branch deletion = full rollback. The tour’s
step scripts live in the graph (app.tour/_tour-lessons) and are
drift-guarded by tools/browser-test/edit-tutorial-tour.test.js —
keep the written lesson’s “Try it” section and the tour steps in
sync when either changes.
The catalogue remembers what you have read (in your browser, not in the
graph) and marks it ✓ done. That mark is yours: the ↺ beside a
finished lesson takes it back off, and Clear progress in the
catalogue’s footer clears the whole history at once, behind a
confirmation. Finishing a lesson offers what to read next right there —
the lesson that follows, plus the first one you have not read when that
is a different lesson — and starting it from the dialog cleans the
finished lesson up first (deleting its branch, or the rows it created).
Six lessons have no tour: 28 is about files on disk and
bb rebuild, which the editor cannot show; 11 is a route-wiring
marathon that reads better as text than as thirty steps; 31 is
about running a second, local instance — something one editor session
cannot demonstrate; 36 needs a second service running while the
tour would hold the page; 38 is a two-role loop that a tour cannot
play from one seat without inventing the other person; and 39 is
mostly set-up in a terminal and an AI client, outside the editor. All
six sit in the chapter their subject belongs to, which is why the ▶
column is worth reading.
The organization tours drive surfaces not every session has, so they
declare what they need (:requires) — a capability (manage-users,
publish-packages, …), or a named condition: the services tour needs the
dedicated plan (services run on an executor the org owns), the
services-talking-to-services tour additionally needs your own
instance (it names the editor’s web-server, which a cloud organization
does not own), the cross-org tour needs organizations to exist at all,
and the asset-override tour needs a single-tenant instance. Anywhere the condition
fails — the public demo, a free-plan org, a self-hosted instance with no
tenancy addon — the picker still lists the lesson, disabled, with the
reason on the row.
Lesson 22 is written self-host-only and its tour declares that
(:requires "assets"): the Assets panel is hidden under the cloud
tenancy addon and its writes are platform-only, because an editable
shared frontend would be a stored-XSS surface across tenants. On a
single-tenant instance both halves apply as written.
New lessons are added as features ship. If a lesson would document a feature that doesn’t yet exist or behaves differently from how it’s described, it stays ⏳ planned until the gap closes.
Once you’ve worked through the Basics and Composing chapters (lessons 01–11) plus Services (lesson 32), Building an API-poller puts it all together: a scheduled service that calls an external HTTP API with a vault-backed bearer token and writes each result into your own Postgres table — built entirely from fn-defs, no Clojure.
A lesson is a short focused walkthrough of one concept. Keep:
Avoid:
docs/*.md (link)