Keybindings
Grafli is modal. Most commands are a single key in Select mode (the
default). The full cheat sheet is also available in-app via F1,
with live filtering.
Modes
| Key |
Mode |
| v |
Select |
| n |
Create node — Shift+click stays in mode |
| t |
Create note — Shift+click stays in mode |
| i |
Create SVG mockup in place — click writes a starter .svg into the vault and opens it in its system app; Shift+click stays in mode (place several, draw later) |
| c |
Connect arrow (one-shot) |
| s |
Style sub-mode (colors, sizes) |
| d |
Dimension sub-mode (resize) |
| Escape |
Cancel / back to Select |
In n / t mode a semi-transparent ghost preview follows the cursor
showing where the new element will land. Clicking creates the element
and exits to Select; holding Shift while clicking keeps you
in the create mode for rapid placement. New elements come prefilled with
placeholder text (A Node / Some text …) so the auto-opened editor
lands on the placeholder ready to type-replace.
File
| Key |
Action |
| ⌘+N |
New file |
| ⌘+O |
Open file |
| ⌘+S |
Save file |
| ⌘+Q |
Quit |
Navigate
| Key |
Action |
| Arrow keys |
Pan viewport |
| Middle-drag / Right-drag |
Pan from anywhere |
| + / - |
Zoom in / out |
| z |
Zoom-in step cycle: 25 → 50 → 100 → 150 % (wraps) |
| Shift+Z |
Zoom to fit (whole graph) |
| gz |
Focus: zoom the selection to fill the viewport; press again to fly back. Re-press after changing the selection to re-focus |
| gp |
Select parent (zoom if needed) |
| gc |
Select first child |
| Tab / Shift+Tab |
Cycle siblings (or search matches when search is open) |
| f / Ctrl+J |
Jump to any item (global) |
| Ctrl+O / Ctrl+I |
Nav history back / forward |
| Alt (hold) |
Graph nav: follow connectors |
| / |
Search dim-filter — see Search below |
Edit
| Key |
Action |
| e / Double-click |
Edit what the element is — box label / note text inline; an image's file opens in its system app (e.g. Inkscape for .svg) |
| E |
Open textli (the full-window Markdown editor) — edits a note's own text; for a box/image, opens (or creates) its attached markdown file |
| W |
Set URL on selected item |
| Return |
Open URL in browser |
| Enter |
Accept edit |
| y / p |
Yank / paste |
| u / ⌘+Z |
Undo |
| Ctrl+R / ⌘+Shift+Z |
Redo |
| x / Delete |
Delete selection |
| Ctrl+G |
Insert glyph (while editing a label) |
Editing a note (vim)
Editing a note (e / double-click) opens a small vim-capable
editor in place — the same keybindings as textli's full editor, without
leaving the canvas. It opens in INSERT mode so you can type right
away; Markdown (md:) notes are syntax-highlighted.
| Key |
Action |
| Esc (in INSERT) |
Drop to NORMAL mode (vim motions/edits) |
| Esc (in NORMAL) |
Commit and close |
| Shift+Esc (in NORMAL) |
Discard and close |
| Click elsewhere |
Commit and close |
The full editor (textli)
E opens textli, grafli's
Markdown editor and its own project. Writing keys, the rendered reading view
(⌘+R), and the comment / suggestion review workflow are
documented in the
textli key reference — or
press F1 inside the editor. See
Text annotations for how it fits into a review flow.
Create
| Key |
Action |
| o / O |
Create box below / above selection |
| Ctrl+G |
Encapsulate selection in a new parent box |
| Ctrl+arrow |
Create connected box in that direction |
| Alt+drag |
Connect nodes — boxes, notes, images (from Select) |
| Alt+click |
Paste at position |
Style
With a selection, press s to enter style mode, then any of the keys
below. Each one means the same thing whatever is selected — e is
appearance, c is colour, t is text, i is
symbols — so the map doesn't change under you when you switch from a box to a
connector.
| Key |
Action |
| e |
Element appearance overlay — box: background (plate / flat) and label position (center / top-left / top-center); note: background; image: frame (auto / frame / none). j/k pick a row, h/l cycle it, Enter commits, Esc cancels. A flat box with a top-left label is the container look, which is how you draw a layer band that has no children |
| c |
Open the color grid — hjkl to pick (live preview), Enter to confirm, Esc to cancel |
| i |
Open the symbol grid (sketchnote vocabulary, semantic + emphasis blocks) — same keys; Tab cycles placement (fill → lead → badge); 1–9 types a number badge (a second press appends: 1,2 → 12). Fill: big symbol + caption. Lead: small symbol beside the label. Badge: compact top-right corner overlay |
| t |
Open the text grid — rows = sizes, columns = Regular / Bold / Italic / Bold+Italic; hjkl to move (live preview), Tab toggles a note's font (handwritten ↔ monospace), Enter to confirm, Esc to cancel |
| j / k |
Cycle text size (quick nudge) |
| d then r |
Snap selected box(es) to the slide aspect ratio — a reusable export frame (re-apply after edits; works on a multi-selection) |
| Shift+G |
Snap to grid |
| = |
Auto-layout selection (or all) |
Focus & analysis
| Key |
Action |
| , |
Dim arrows |
| Shift+N |
Dim notes (and their connectors) |
| A |
Complexity heatmap |
| B |
Subgraph focus (cycle direction: all → forward → backward) |
| Shift+B |
Toggle focus depth (full / 1-hop) |
The same three view-toggles also have buttons in the side panel's View
section.
View
| Key |
Action |
| # |
Toggle grid |
| M |
Toggle minimap |
| \ |
Toggle tools panel |
| ⌘+Shift+D |
Toggle light / dark theme — or click the sun/moon button next to the tools button |
Light and dark
grafli ships two themes: the warm paper light theme and a dark counterpart in
the same style — same semantic roles, same contrast relationships, just a
low-key ground. Switch with ⌘+Shift+D, or click
the sun/moon button in the top-left of the canvas (it shows the theme you'd
switch to). The choice applies immediately and is remembered across restarts.
Colour tokens (%accent, %primary, …) are semantic, so they re-resolve per
theme and a .grafli written by someone on light reads correctly on dark. A
literal hex (#C0FFEE) is always kept exactly as written.
Headless renders don't follow the app's theme, so a given file and flags always
produce the same image. Pick one explicitly:
grafli render board.grafli out.png # light (default)
grafli render board.grafli out.png --theme dark
Export
| Key |
Action |
| Y |
Yank diagram as PNG to clipboard |
| Ctrl+E |
Export SVG to file |
Arrows
| Key |
Action |
| Shift+click |
Add / remove a connector from the selection (format many at once) |
| e |
Edit arrow label |
| s |
Arrow style mode |
| s then e |
Connector appearance overlay — heads, line pattern, thickness, routing, colour (j/k pick a row, h/l cycle it, Enter commits, Esc cancels) |
| s then c |
Open the color grid — the same picker boxes and notes get |
| s then t |
Connector label-text overlay (size) |
| h / l |
Toggle arrowheads (in style mode) |
| j / k |
Arrow label size (in style mode) |
| Shift+J / Shift+K |
Cycle line pattern (in style mode) |
| s then r |
Cycle connector routing: direct → spline → stair (in style mode) |
| s then a |
Toggle connector kind: graph edge ⇄ annotation (a graph edge to a note or image makes it a node) |
Buffers
| Key |
Action |
| Ctrl+K |
Open / switch buffer |
| Ctrl+6 |
Toggle last buffer |
| Q |
Close buffer (no selection) |
Bookmarks & flows
Save labeled viewpoints and string them into guided tours — see
Bookmarks & flows.
| Key |
Action |
| gb |
Bookmark what's shown (selection, else everything visible) |
| gB |
Bookmark the exact viewport (pixel-faithful framing) |
| gf |
Start / stop flow recording (each capture is appended) |
| gF |
Auto-flow: generate a flow by walking forward arrows from the selected node |
| F5 |
Present the current flow fullscreen (chrome hidden, paused) |
During playback (in-app or presenting):
| Key |
Action |
| Space / → |
Next stop |
| ← |
Previous stop |
| t |
Toggle smooth camera ↔ instant cuts |
| p |
Cycle paused → playing → playing (loop) |
| Esc |
Exit playback |
Mouse
| Action |
Effect |
Click @path:line in a code-mode note |
Open the file at that line in the configured editor |
| Shift+click |
Toggle selection (on empty space or a node's body) |
| Drag a corner handle |
Scale the selection — size and font, around its bounding box; keeps the aspect ratio. A preview frame shows where it lands and it commits on release. Hold Shift for a free (non-uniform) scale |
| Drag an edge handle |
Stretch that single axis (modifier-agnostic) |
| Alt+drag |
Connect nodes (boxes, notes, images) |
| Alt+click |
Paste at position |
Search
Press / to open the search dim-filter. Typing dims everything that
doesn't match to ~8% opacity so hits stand out across the canvas at once;
the minimap reflects the same dimming so off-screen hits stay visible.
| Key |
Action |
| / |
Open search input (works on non-US layouts where / needs Shift+7) |
| Type |
Live filter — matches box label + box id + note text (case-insensitive substring) |
| Tab / Shift+Tab |
Cycle to next / previous match (animated, lands at 100 % zoom) |
| Enter |
Dismiss the input badge but keep the dim filter active |
| Esc |
Clear the input and the filter |
| Backspace |
Edit the query |
Search is mutually exclusive with focus / complexity / arrow-dim — opening
one closes the others.
Help
| Key |
Action |
| F1 |
In-app cheat sheet (with filter) and text-annotation reference |
| ` |
Toggle debug overlay |