Whiteboard
An endless surface with nothing on it until you put something there. Whiteboard, in the sidebar.
Why it is here
Everywhere else in Félagi a piece of work needs a title, a type and somewhere to live. That is the right shape for work that has been decided, and the wrong shape for the two hours before it was.
The early phase of anything — a workshop, an architecture argument, a retro — has nothing in it that fits a form yet. A tool that insists on one at that point does not get used; the team photographs a real whiteboard instead, and the photograph is where the thinking goes to die.
So: sticky notes, boxes, text, arrows, freehand drawing and images, anywhere on an endless plane.
What makes it not Miro
The wire back to the data model.
A note can become a real issue. The first line is the title, anything after it is the description, and the note stays on the board pointing at what it became — the shape of the board is the record of the conversation, and deleting a note because it graduated would take the argument with it.
An issue that already exists can be dropped onto the surface as a card, showing its live status, read on every load and pushed on every change. A board left open overnight is not lying by morning.
How it is drawn
The board is a canvas, not a page. Everything on it — notes, boxes, arrows, ink,
frames, issue cards — is painted into two <canvas> elements by a rendering engine, on
the GPU where there is one and on the CPU where there is not.
It used to be one HTML element per thing on the board, moved by transforming the layer they all sat in. That works and it never feels right: every pan is a layout of the whole page, every note is its own reactive scope, and the cost of the board is the number of things on it. A canvas moves the camera instead — a pan is a handful of numbers, and forty notes cost what four hundred do.
| WebGPU | One draw call for the visible scene. Shapes are drawn from their maths rather than from pictures, so they are sharp at any zoom |
| Canvas 2D | The same scene, on the CPU, where WebGPU is missing or fails. Not a stub: the same list of shapes, drawn a slower way |
| Which one | Said in the bottom-left corner of the board. "Is this the fast path" is the first question anybody asks of a canvas that feels slow |
The engine is Orivane, our own collaborative-canvas project, vendored in rather than rewritten. Only the drawing half came across — the camera, the spatial index, the scene builder and the two renderers. Its document model, its server, its identity and its storage stayed where they are: Félagi already has all four, and the seam between them turned out to be four methods wide.
Text is still a real textarea. Typing happens in an HTML box placed over the note, because a caret drawn by hand is a month of work and a worse caret — no spellcheck, no dictation, no IME, and no selection anybody recognises. The canvas draws the words again the moment you click away.
Only what is on screen is drawn. A spatial index answers "what is in view" without walking the board, so scrolling a large board costs the same as scrolling a small one.
Working at the same time
Everybody on a board sees everybody else's cursor, labelled.
Cursors are whispered between browsers and never reach the server. Sixty positions a second per person is not information worth a request, a queue job or a row; it is worth exactly as much as the moment it describes.
Changes to things — a note moved, a colour changed, a card dropped — do go through the server, because those are facts. They are sent immediately rather than queued. Everything else in Félagi queues its broadcasts, which is right for news; a whiteboard is not news, it is a shared object two people are touching.
Nothing is applied to an element you are holding. If a note arrives while your hand is on it or your cursor is in it, the update waits — otherwise the note jumps backwards mid-drag.
Two people dragging the same note is a conversation happening in the room. The last hand wins, per element, and there is no merge dialog.
Undo
⌘Z puts back the last thing you did, ⇧⌘Z does it again forwards, and both have
buttons beside the zoom controls — a keyboard shortcut nobody knows about is not
an undo, and the person who has just deleted the wrong note is the least likely
to go looking for one.
Deletes, creates, moves and resizes. A deleted note comes back with its text, its colour and its position; it gets a new identifier, because the row is gone and inventing the old one would claim an identity the database no longer knows.
Inverses rather than snapshots of the whole surface. A snapshot would undo somebody else's work along with yours, on a board where two people are drawing at once.
The stack lives in the browser and lasts the session.
Finding a note
⌘K searches the words on every note you can see. A result opens the board centred on the note, ringed for a couple of seconds.
That is the whole feature: a board has no edges, so a result that opened the board and left the viewport alone would leave you looking at empty grid. See Search.
Finding a board, and naming one
Boards in the header lists every board in the workspace: what it is called, how much is on it, who made it, when it last changed, and whether anybody else can see it. Search it by name. Clicking a row opens that board.
It used to be a dropdown of names, which could answer none of those questions — and with four boards called Untitled board it could not answer the only one it was asked. The dropdown was also capped, so past that many boards the oldest ones could not be opened at all: the link worked, the board was there, and the page came back with nothing on it.
The title in the header is the name. Click it and type. Enter or clicking away saves; Escape puts it back.
A new board opens with the cursor in its title, so naming it is the next keystroke rather than an errand. Until somebody names it, it is called Untitled board — and the second one is Untitled board 2, because two boards with one name is a list that cannot help you.
Renaming and deleting a board
The Board menu carries who can see it, and deleting. The name is in the title above.
It used to be an unlabelled gear with the deletion at the foot of a settings form, and the result was somebody reporting that deleting a board was not possible. It always was. A feature nobody can find is a feature that does not exist.
Deleting takes everything on the surface with it. Issues opened from the board stay — they are work, not drawings.
Its author, or an administrator. A shared board belongs to whoever has been drawing on it, so taking one away is not an ordinary edit — and Delete board is not offered to anybody else, rather than being offered and then refused. If a board changes hands while your menu is open, the refusal arrives as a sentence naming its author.
Private boards
A board is shared with the workspace by default, because the argument for having one at all is that other people are standing at it.
Only me makes it a notebook: nobody else sees it in the list, nobody else can open it from a link, and nobody else can subscribe to it — hearing a surface is reading it.
Only whoever made a board can change who sees it. A colleague turning your sketch into a team board is the same violation as the reverse.
Voting
A sticky note carries a vote button. One vote per person, stored as who rather than as a number, so it can be taken back — a retro where somebody's fifth vote was an accident is a retro with the wrong answer at the top.
And a thread, for the why. A count says how many of us care; it cannot say what the argument was — see Saying why.
Selecting several things
Drag on empty surface with the select tool and a rectangle follows the pointer. Anything it touches is selected — not only what it entirely encloses, because the note at the edge is the one you notice missing after you have moved the group without it.
Shift-click, or ⌘-click, adds one thing at a time. Either modifier works: somebody who
has used another canvas will reach for one of the two and should be right.
Once several things are selected:
- Dragging any of them moves all of them. Grabbing something that is not in the selection picks that up alone instead, so a click never drags four notes by accident
- A colour swatch recolours the lot
⌫deletes them, and one undo brings them all back — four separate undos to reverse one gesture is not what you did⌘C/⌘Vcopies and pastes, and⌘Ddoes both in one press
Pasted copies land slightly offset from their originals rather than under the pointer: a copy directly on top looks like nothing happened, and one that jumps to the cursor loses the arrangement, which is usually why the group was copied at all. The copies become the selection, so a paste can be dragged straight afterwards.
The clipboard is Félagi's own, not the system one. A board is not text, and asking for clipboard permission to duplicate a note is a browser dialog in exchange for nothing.
Right-click
Right-click anything for Duplicate, Bring to front and Remove. Right-clicking something outside the selection makes it the selection; right-clicking within one keeps the group, so "remove these six" works.
Arrows and drawings can be clicked. A line is two and a half pixels wide, and asking somebody to click it is asking them to miss — before this an arrow could not be selected, moved or deleted at all, and the only way to remove one was to undo in the session that drew it. The invisible fat copy of the line that used to catch the pointer went with the DOM; the engine measures the distance from the pointer to the stroke instead, against a tolerance in screen pixels, so it does not shrink as you zoom out.
The element menu says Remove and the board menu says Delete the board. Different verbs on purpose: one costs a note, the other costs everything on the surface.
Keys
Press ? anywhere in the application and the list includes the board's own keys while you
are on it — which is where somebody looks, rather than in a guide.
The full list
V N B F |
select, note, box, frame |
T A P H |
text, arrow, pen, pan |
| double-click | write on a note — or make one, on empty surface |
↵ |
write on the one thing selected |
| drag on empty surface | select everything the rectangle touches |
shift-click / ⌘-click |
add one thing to the selection |
⌘-drag on empty surface |
add what the rectangle touches |
hold ⌥ while dragging |
put it exactly there, ignoring the guides |
| arrow keys | nudge a pixel · with shift, ten |
⌘A |
select everything on the board |
⌘C ⌘V ⌘D |
copy, paste, duplicate |
⌘] ⌘[ |
bring to front, send to back |
⌘Z ⇧⌘Z |
undo, redo |
⌫ |
delete what is selected |
Esc |
deselect, back to the select tool |
| space-drag, shift-drag or middle-drag | pan |
| two-finger scroll | pan · ⌘/Ctrl + scroll zooms towards the pointer |
Arranging things
Notes line up with each other. Drag one and a blue line appears when an edge or a centre meets another element's — that is where it will land. Nothing to line up with, and it lands on the 24-pixel grid the surface draws, so a board assembled over an afternoon does not end up a few pixels out everywhere.
Hold ⌥ to put something exactly where you mean it, snapping ignored.
Bring to front · Send to back on the right-click menu, or ⌘] and ⌘[. Only the first
existed, so anything covering what you wanted was dealt with by raising everything else in
turn.
Duplicate is ⌘D, or the right-click menu. A copy lands beside its original rather
than on top of it, and a set keeps its arrangement.
Areas, and a board that starts as something
Frame (F) draws a named area. Its title sits above it, and it carries what is
standing inside it: move the frame and the notes in it come along. That is the whole
difference between a frame and a box — a box says these belong together and then stays
behind when you rearrange the board.
A frame is drawn behind whatever ends up in it, and grabbing one does not bring it forward: a frame that jumped in front of its own contents would look like it had swallowed them.
Board → Start from a template lays out a set of areas: a retrospective, a flow, a decision, a plan. Four, deliberately — a list of twenty is a list nobody reads.
An empty surface is the hardest thing in this product to use. Everybody knows what a retro is and nobody wants to draw three columns and label them first, so the first five minutes of every session went on the same rectangles, badly aligned, by whoever opened the board.
Tip: A template lands to the right of whatever is already there, never on top of it. It is most useful halfway through a session, when somebody says let us structure this — not only on an empty board.
Saying why
A thread on a note. The speech bubble at its corner opens it; anything holding words can have one, including a frame.
Votes count how many of us care about a note. They cannot say why — and the why is what somebody reads a board for a week later, when the argument that produced the note is gone and the note is three words.
Tip: The count travels with the board and the words do not, so a board of four hundred notes does not carry every conversation anybody has had on it to every browser that opens it. The thread is fetched when you open one.
Tip: You can remove your own comments, and an administrator can remove any. Words a colleague can quietly remove are words people stop writing.
Tip: Escape closes the thread. It does not also drop your selection — one key, one thing at a time.
Holding things together
An arrow drawn between two notes stays between them. Move either and it follows, meeting the edge of what it points at. Resize one and it adjusts.
An arrow is a line between two points, and points do not follow — so before this a diagram was right until somebody touched it, which is not what a whiteboard is for. The fastening is decided when the arrow is drawn, because that is the only moment the intent is legible: an arrow drawn between two things means those two things.
Tip: An end pointing at something that was deleted stays where it was. A loose end where the note used to be is readable; a line snapping back to the origin is a mystery.
Group two or more things from the right-click menu, and selecting any of them selects all of them. Which is what a group is for: not having to rubber-band the same five notes again. Ungroup takes it apart.
Lock makes something scenery. A box drawn round some notes to group them visually gets dragged by accident every time somebody reaches for what is on top of it — locked, it stays put, keeps its place in the stacking order, and is skipped by Delete.
Tip: A locked element still selects, or there would be no way to unlock it. It shows a small padlock, because a background that will not move and does not say so reads as a broken drag.
Tip: Delete with a locked background and three notes selected removes the three notes. Skipping is the useful reading; refusing the whole thing is not.
Where you are
The minimap, bottom right, shows everything on the board and a rectangle for the part you are looking at. Click it to look somewhere else.
An endless surface makes it possible to be nowhere: pan far enough and there is nothing on screen and no direction that obviously leads back. Fit to content answers that in one jump; the minimap answers it while you work.
Taking a board out of the room
Board → Export as PNG. The whole board, whatever part of it is on screen, at twice the size so it stays legible in a document.
A board is a conversation, and the conversation usually has to be reported to somebody who was not there. The only way to do that was a screenshot — which captures the part of the board that happened to be visible, so the answer to what did you decide was a picture of a third of it.
It is drawn by the same engine that drew the screen, pointed at an offscreen canvas. The export used to be a second renderer written by hand, which agreed with the board until somebody changed one of the two — and the one that was wrong was the file people send to other people.
Not there yet: PDF. The honest route is the browser's own print dialogue, and printing this page today gives you the sidebar and a clipped board. That needs a print stylesheet rather than a button, so there is no button.
Nothing ends up out of reach
The toolbar, the palette, the zoom controls and the search box float over the surface, and they take the pointer. Something underneath one of them cannot be clicked — and everything you can do to an element starts with selecting it, so a note that ends up there is stuck: not selectable, not movable, not deletable, with nothing on screen to say why.
Fit to content is the way back, and it now fits to the part of the surface you can actually click rather than to the whole of it. It used to centre content in the full width with an even margin, and the clickable space is not even — the toolbar is on the left — so on a wide board it put the left-hand notes back underneath it. Fit could leave you exactly where you started.
Tip: It also counts drawings and arrows now. They were left out of the reckoning, so a board of nothing but pen strokes fitted to nothing at all.
Where the drawing lives
Positions are doubles, not integers. The surface has no edges and no fixed scale; two people at different zoom levels are looking at the same numbers, and rounding would quantise a drag at 25% into four-pixel jumps.
Colours are token names — yellow, blue — never hex. A board should survive a
theme change, and somebody who picked #ff00aa in light mode has made a note
nobody can read in the dark.
The canvas needs hex, so the names are resolved from the stylesheet when the board opens — and read again when the theme changes. A canvas re-renders when it is told to and never on its own, so a palette read once at start-up is every sticky keeping its light colours on a dark page until somebody reloads.
Everything is one row per element in one table. A table per shape would be six tables answering the same question and six joins to draw one board; the difference between a note and an arrow is two nullable columns, not a schema.
Not there yet
This list had four entries that were no longer true — connectors that follow, frames, templates, comments — and one, no selecting more than one thing, that the section Selecting several things contradicts on the same page. A list of missing features that lists features you have is worse than no list: it is read once, found wrong, and then nothing else on the page is trusted either. What follows is what is actually absent.
- Undo lasts the session. The stack lives in the browser, so a reload starts it empty. The failure it exists for — a misclick noticed in seconds — is covered; one discovered next Tuesday is not.
- No PDF. The honest route is the browser's print dialogue, and printing this page today gives you the sidebar and a clipped board. That wants a print stylesheet rather than a button, so there is no button. PNG is there.
- No history of who moved what. Threads say what somebody thought; nothing says who dragged a note across the board at four o'clock.
- Not in the import or the export, which is deliberate rather than pending. Boards are readable over the API and a note can be added, but moving, drawing and deleting are the interface's.
- No catch-up after a dropped connection. Reload the page.
- Text on a note is plain. A toolbar per note, on a surface where six people are typing at once, is a worse problem than the one it solves.
- A group is flat. No groups inside groups, and no name on one — it is a handle for moving things together, not an object in its own right.
- A frame's contents are whatever overlaps it. Nothing is pinned to a frame, so dragging a note out of one takes it out of the frame, which is usually what somebody means and occasionally not.
- Nothing rotates. The engine draws a rotation for anything that carries one and there is no column to keep an angle in, so the handle is not offered: a note that turned and then snapped back on the next reload would be worse than one that cannot turn.
- Connectors are straight lines. The engine routes elbows and curves as well, and turning that on changes the shape of every arrow already drawn — a decision rather than a side effect, so it is one field away and not taken.