docker compose up runs the whole stack on your own box. There's an admin dashboard for organizations: create accounts, toggle self-registration, manage roles. There's a per-board activity log so you can see who added what.
GPU canvas (Pixi.js v8). The canvas isn't HTML/Fabric — it's a Pixi.js scene graph with viewport culling, LOD-aware texture loading, and GPU-batched draw calls. PureRef itself isn't GPU-accelerated; on the same set of high-res references the comparison is visible. I wrote a custom scene-converter so canvas state serializes to a portable JSON that survives sync, undo/redo, copy-paste, and round-trips through MinIO.
Real-time collaboration (Socket.IO). Full-scene sync inspired by Excalidraw — the whole canvas JSON is broadcast on changes (300ms throttle), with lightweight 50ms throttled object-transform events during drags so motion stays smooth. Interaction-aware deferral queues remote scene updates while a user is mid-drag, so other people's edits never yank objects out from under your cursor. Cursor positions are streamed separately. Follow-mode lets you snap your viewport to another collaborator and see what they're seeing. Presence is shown as stacked avatars in the toolbar.
PureRef-parity power tools. 40+ shortcuts, mapped 1:1 to PureRef's defaults — align left/right/top/bottom, distribute H/V, normalize size/scale/width/height, flip H/V, reset transform, lock, group/ungroup, optimal pack, arrange in grid/row/column/by name/by z-order/random/stack, overlay-compare (Ctrl+Y), grayscale toggle. Right-click context menu carries the same set. Tools the keyboard people will recognize without thinking.
Media pipeline. Sharp generates image thumbnails and LOD variants on upload. ffmpeg pulls the first-frame poster and metadata for videos. Poppler renders PDF pages individually — first 20 pages get thumbnails immediately, single-page PDFs get a hires render queued at higher priority. All processing runs in a background media worker, so uploads feel instant.
Threaded review. Pin a comment to any object on the canvas — that starts a thread. Replies, status (open / resolved), denormalized author labels so threads survive user deactivation. Review mode toggles a clean overlay for walking through feedback. This solves the gap I had where designers were leaving reference comments in Slack DMs that got lost.
Activity log. Per-board audit trail visible from a clock-icon in the toolbar — uploads, board create/rename/delete, threads, replies. Live updates over Socket.IO. Time-grouped feed (Today / Yesterday / older), live append on new events. Author labels denormalised at log time so a deactivated user's history doesn't go anonymous.
Admin dashboard. Organisation-friendly user management at /admin — create accounts, reset passwords, promote/demote between admin and member, deactivate / reactivate, runtime toggle for self-registration. Backed by a hybrid middleware that accepts either a JWT-with-admin-role (UI path) or an X-API-Key header (bot/server-to-server path). The very first user is auto-promoted to admin; SEED_ADMIN_* env vars can bootstrap an admin idempotently on first boot.
Self-hostable. Multi-stage Dockerfile bundles the frontend build into the backend image. docker-compose.yml brings up Refboard + a MinIO sidecar in one command. .env.example annotates every knob. README documents the path to a public domain via Cloudflare Tunnel (zero open ports), Caddy + Let's Encrypt, nginx with WebSocket upgrade headers, or Tailscale for tailnet-only access. Default config refuses to start in production without a real JWT_SECRET.
docker compose recipe; MinIO + backend + frontend all start cleanly from a fresh clone.