Driftboard docs
A Kanban-style project management app with no backend. Every board is a Yjs CRDT that lives on your machine and syncs directly, peer-to-peer, with the people you invite — over WebRTC, with no account and no central server holding your data.
These docs cover installing Driftboard, how a workspace is created and shared, exactly how sync and storage work under the hood, and the trust model you should understand before you invite anyone to a board.
Installation
Driftboard ships two ways: a signed MSIX package for the Microsoft Store, or straight from source if you'd rather build it yourself.
From source
$ git clone <this repo> $ cd driftboard $ npm install $ npm run electron:dev # Vite + Electron, hot reload
Requirements
- Node.js and npm installed locally.
- Windows, for the packaged MSIX build —
npm run electron:devworks cross‑platform for development. - No account, API key, or server of any kind. There's nothing to sign up for.
Building for release
$ npm run build # type-check + Vite production build → dist/ $ npm run dist:appx # package as MSIX (Windows only)
Full packaging and code-signing steps live in docs/MSIX_PACKAGING.md, and the
Microsoft Store submission checklist — including the required privacy policy — is in
docs/STORE_CHECKLIST.md.
Creating & joining a workspace
A workspace is Driftboard's unit of sharing — one board, one Yjs document, one WebRTC room.
- Open the app and create a workspace. This generates a local
roomCodeand apassphraseon your device — nothing is sent anywhere yet. - Click Invite to get a link, a short room code, or a QR code that encodes both.
- Share it however you'd share a password: over a call, a QR scan across the table, or a messaging app you trust.
- Whoever opens the link or enters the code via Join with code connects directly to your device over WebRTC and starts syncing immediately.
Both peers only need internet access for the initial handshake and NAT traversal. After that, data flows directly between them — not through any Driftboard-operated server, because there isn't one.
Why there's no server
Two peers who both have Driftboard open exchange board data directly over a WebRTC data
channel. To find each other in the first place, WebRTC needs a brief signaling
handshake — by default Driftboard uses the free, public signaling servers that ship with
y-webrtc (wss://signaling.yjs.dev and a couple of mirrors), configured in
src/store/workspaceSession.ts.
Those servers only ever see encrypted handshake noise — never your board data. The WebRTC channel itself is encrypted end‑to‑end with a passphrase generated on your device, shared only through your invite link or code.
Don't want to depend on someone else's free signaling server? Run your own — see Self-hosting signaling below. No code changes are required anywhere else in the app to switch to it.
Data model
Every workspace is its own Yjs document, its own IndexedDB database
(driftboard-<id>), and its own WebRTC room. Here's how the pieces fit together:
Y.Array<string> of list ids. Each list keeps its own Y.Array<string> of card ids for ordering.Y.Map<cardId, Y.Map<fields>> so any peer can edit any field concurrently. Yjs merges conflicts automatically — last‑write‑wins per field, proper CRDT merge for checklist/comment/attachment arrays.CardModal.tsx. Fine for images, PDFs, and small files — not meant for large media libraries, since everything attached copies to every peer's disk.Need larger attachments than 4 MB? The cleanest extension point is swapping data-URL
storage for content-addressed chunks synced over a WebRTC data connection — reusing
y-webrtc's existing peer connections, or a library like simple-peer directly —
instead of storing bytes in the CRDT.
Views & card fields
Every workspace can be viewed three ways, all reading from the same underlying document:
- Board — the classic drag-and-drop Kanban layout, powered by
@dnd-kit. - Table — a spreadsheet-style list of every card, useful for scanning or bulk edits.
- Calendar — cards laid out by due date.
Cards themselves support description, due date, labels, checklists, attachments, comments, and assignees — all stored as CRDT fields, so edits from different peers merge without stepping on each other.
Security & trust model
Read this before inviting anyone to a workspace.
An invite link or code is full read‑write access to that workspace, forever, for whoever holds it. There's no per‑person permission system, and no way to revoke a single peer's access once they've synced data — that's inherent to a serverless CRDT design, since everyone with the key is a full replica.
If you need to remove someone
- Regenerate a fresh workspace and re-invite everyone else. This isn't a perfect revoke — the removed member's existing local copy of the old workspace still works — but they'll stop receiving new changes once you stop sharing the new room code and passphrase.
- Treat an invite exactly like you'd treat a shared password: don't post it publicly, and assume anyone who's ever had it can still read the state as of when they last synced.
The signaling servers — public or self-hosted — only ever relay WebRTC handshake metadata.
See src/store/workspaceSession.ts for exactly what's configured there.
Self-hosting signaling
The signaling server is the only server-like component in the whole system. It holds no board data, and running your own is entirely optional — the public defaults work out of the box.
$ npx y-webrtc-signaling # listens on :4444 by default
Then replace the SIGNALING_SERVERS array in
src/store/workspaceSession.ts with your server's wss:// URL:
// before const SIGNALING_SERVERS = [ 'wss://signaling.yjs.dev', // ...mirrors ]; // after — pointed at your own server const SIGNALING_SERVERS = [ 'wss://your-domain.example:4444', ];
No other code changes are required — every workspace will use the new server for its next handshake.
Building & packaging
npm run build— type-checks the project and produces a Vite production build indist/.npm run dist:appx— builds and packages the app as MSIX. Windows only; seedocs/MSIX_PACKAGING.mdfor code-signing.docs/STORE_CHECKLIST.md— everything needed to submit to the Microsoft Store, including the privacy policy requirement.
Project layout
License
Driftboard is released under the MIT license. See LICENSE in the repository for the full text.