Graphden Tutorial

Step-by-step introduction to graphden. Text-only for now — per ROADMAP § Block 0 the UI integration is a later decision.

Audience: someone who can program but has never seen graphden before. Each lesson assumes the previous ones and nothing else from the project docs.

How to read this

  • Read lessons in order on first pass.
  • Each lesson has a Goal (what you'll be able to do at the end), Concepts (vocabulary introduced), and Try it (something concrete to type into the running editor).
  • If a concept needs deeper detail than the lesson gives, the lesson links into ARCHITECTURE.md, PACKAGES.md, or wherever it lives.

Lessons

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.

Basics

# 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

Composing

# 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

Running it

# 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

The editor

# 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

Your organization

# Lesson Status
24 Members — managing who is in your org ✅ written · ▶ interactive
25 Grants — who may touch what ✅ written · ▶ interactive
26 Roles — capabilities as a bundle ✅ written · ▶ interactive
27 Apps — publishing a fn as a public site ✅ written · ▶ interactive
28 Packages — namespaces, fns.edn, impls.clj, deps ✅ written
29 Distributing packages — publish, install, update, fork ✅ written · ▶ interactive
30 Working across organizations ✅ written · ▶ interactive
31 Working offline: a local instance, git snapshots, push/pull ✅ written
32 Services — long-running fns supervised by graphden ✅ written · ▶ interactive
33 Signing up & signing in: your account ✅ written · ▶ interactive
34 Plans & tiers — what the cloud grants each account ✅ written · ▶ interactive
35 Services talking to services — the contract lives in the graph ✅ written · ▶ interactive
36 Queues — asynchronous work between services ✅ written

▶ 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.

Three lessons have no tour: 27 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; and 30 is about running a second, local instance — something one editor session cannot demonstrate. All three 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 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.

End-to-end worked example

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.

How to contribute a lesson

A lesson is a short focused walkthrough of one concept. Keep:

  • ~60-150 lines of markdown total
  • One concrete worked example you can paste into the running editor
  • Concepts introduced explicitly named (so future lessons can refer)
  • No prerequisites beyond the previous lessons in this index

Avoid:

  • Re-explaining what earlier lessons already covered (link to them)
  • Duplicating reference material that lives in docs/*.md (link)
  • "Why we did it this way" rationale — that belongs in PHILOSOPHY.md and gets linked, not pasted