Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚡ Flux

Draw together, instantly.

A real-time collaborative whiteboard where anyone can sketch, write, drop images, and leave comments on an infinite canvas — together, live, with zero friction. Start a party in one click and share a code, or sign up to keep your boards forever.

→ Try the live app


Live Spring Boot Java React TypeScript License


Why Flux

Most whiteboards make you sign up before you can draw a single line. Flux flips that. Click Start a party, get a shareable code like FLX-9K4T, and your teammates are drawing on the same canvas seconds later — no accounts, no installs, nothing to configure. When you want permanence, sign up and your boards live in a dashboard forever (you can even claim a party board into your account).

Under the hood it's not a toy. Concurrent edits are merged with a conflict-free replicated data type (CRDT), so two people erasing and drawing over each other never corrupt the board — every client converges to the same picture, even after a disconnect and replay. State is persisted to Postgres as an operation log, periodically compacted into snapshots in object storage, and fanned out across server instances through Redis pub/sub.


Two ways to use it

Party mode Account mode
Sign up? Never Free
Get going One click → share a FLX-XXXX code Email + password
Boards Expire after 24h of inactivity Saved forever
Dashboard Manage all your boards
Claim Pull a party board into your account
Export PNG / PDF PNG / PDF

Features

🎨 A real drawing surface

  • Infinite, pannable, zoomable canvas with a live minimap for navigation
  • Pen, highlighter (semi-transparent), and eraser tools
  • Text with full formatting — font family, size, bold / italic / underline, multi-line
  • Images — drag-and-drop or paste straight onto the canvas (uploaded via presigned URLs with an on-canvas progress ring)
  • Selection model — marquee + lasso select, move, 8-handle resize (images too), delete, double-click to re-edit text

👥 Truly collaborative

  • Live multi-user editing with presence and real-time cursors
  • CRDT merge (LWW-Element-Set + vector clocks) so concurrent edits converge — no lost strokes, no corruption
  • Comments anchored to individual shapes, with threads and unread indicators
  • Resilient reconnect — drop your wifi, come back, and the board replays to a consistent state

🗂 Persistence & sharing

  • Operation log persisted to Postgres; periodic snapshots to S3-compatible object storage with compaction
  • Export any board to PNG or PDF, entirely client-side
  • Per-board light / dark theme, persisted

Tech stack

Layer Technology
Frontend React 18 · TypeScript · Vite · Zustand · React Router · custom canvas engine
Realtime WebSocket over STOMP + SockJS
Backend Spring Boot 3.3 · Java 21 · Spring Security (JWT) · Spring Batch
Merge Custom CRDT — LWW-Element-Set + vector clock
Database PostgreSQL (Neon) · Flyway migrations
Cache / fan-out Redis (Upstash) pub/sub — optional for single-instance
Object storage AWS S3 / Cloudflare R2 (presigned uploads)
Export jsPDF
Deploy Vercel (frontend) · Render (backend, Docker)

Architecture

                ┌──────────────────────────────────────────────┐
                │                Browser (React)               │
                │   Canvas engine · CRDT client · STOMP client │
                └───────────────┬──────────────┬───────────────┘
                       REST/JWT │              │ WebSocket (STOMP)
                                ▼              ▼
                ┌──────────────────────────────────────────────┐
                │              Spring Boot backend             │
                │  Auth · Boards · Party · Draw/Presence WS     │
                │  CRDT merge service · Snapshot & batch jobs   │
                └───┬───────────────┬───────────────┬──────────┘
                    │               │               │
            ┌───────▼──────┐ ┌──────▼──────┐ ┌──────▼───────┐
            │  PostgreSQL  │ │    Redis    │ │  S3 / R2     │
            │  op log +    │ │  cross-     │ │  snapshots + │
            │  snapshots   │ │  instance   │ │  image       │
            │  (Neon)      │ │  fan-out    │ │  uploads     │
            └──────────────┘ └─────────────┘ └──────────────┘

How a stroke travels: you draw → the op is applied locally and merged into the client CRDT → published over STOMP → the backend merges it into the authoritative CRDT, persists it to the op log, and re-broadcasts. With multiple instances, Redis pub/sub fans the op out to clients connected to other nodes. Every so often a batch job compacts the op log into a snapshot in object storage so new joiners load fast.


Project layout

flux/
├── backend/                 Spring Boot 3 · Java 21
│   └── src/main/java/com/flux/
│       ├── controller/      REST: Auth, Board, Party, Comment, Health
│       ├── handler/         WebSocket: DrawOperation, Presence, Redis subscriber
│       ├── service/         CRDT, Board, Party, Auth, Jwt, Snapshot, Image, Presence
│       ├── crdt/            LwwElementSet, VectorClock
│       ├── batch/           Snapshot, PartyCleanup, KeepAlive jobs
│       ├── model/           JPA entities
│       └── config/          Security, WebSocket, Redis, R2/S3, CORS
│
└── frontend/                React 18 · Vite · TypeScript
    └── src/
        ├── canvas/          CanvasEngine, ViewportManager
        ├── crdt/            ClientCrdt
        ├── ws/              StompClient
        ├── pages/           Landing, Party, Board, Dashboard, Auth
        └── components/      Minimap, HistoryPanel, ExportModal, CommentThread, BoardCard

Running locally

Prerequisites

  • Java 21
  • Node.js 20+
  • Free accounts for the cloud services below (or point them at local equivalents)

1. Cloud credentials

Flux talks to managed services. Create the following and collect their credentials:

  • Neon — Postgres connection string
  • Upstash — Redis URL (optional; set REDIS_ENABLED=false to skip on a single instance)
  • AWS S3 or Cloudflare R2 — a bucket for snapshots & image uploads

Export them into your shell:

export NEON_DATABASE_URL="jdbc:postgresql://ep-xxxx.region.aws.neon.tech/fluxdb?sslmode=require"
export UPSTASH_REDIS_URL="redis://default:password@your-host.upstash.io:port"
export JWT_SECRET="your-256-bit-random-string-here"
export S3_BUCKET="flux-whiteboard-snapshots"
export R2_ACCESS_KEY_ID="your-access-key"
export R2_SECRET_ACCESS_KEY="your-secret-key"
export AWS_REGION="auto"            # a real AWS region for S3; "auto" for R2
# export R2_ENDPOINT="https://<account-id>.r2.cloudflarestorage.com"   # only for R2

2. Backend

cd backend
./mvnw spring-boot:run     # runs Flyway migrations on startup, then serves on :8080

3. Frontend

cd frontend
npm install
npm run dev                # http://localhost:5173

Open http://localhost:5173 and start a party.

Java version error? class file version 61.0 ... up to 52.0 means Maven picked up an older JDK. Make sure JAVA_HOME points at your Java 21 install before running ./mvnw.


Deployment

The live app runs on a split deployment:

  • Frontend → Vercel. Build frontend/; set VITE_API_URL to the backend origin.
  • Backend → Render (Docker, see render.yaml). Set all secrets in the dashboard, plus ALLOWED_ORIGINS to include your deployed frontend URL so WebSocket/CORS handshakes succeed.

The backend honours an injected $PORT, exposes /healthz for health checks, and runs a keep-alive job to avoid free-tier spin-down.


Roadmap

  • Party mode + account mode with board claiming
  • CRDT merge, persistence, snapshots & compaction
  • Presence, live cursors, reconnect resilience
  • Full tool set — pen, highlighter, eraser, styled text, images
  • Selection model — marquee/lasso, move, resize, re-edit
  • Shape comments with threads
  • PNG / PDF export
  • Server-side ownership hardening on comment edit/delete
  • World-coordinate remote cursors across zoom levels
  • Keep comments anchored through shape move/resize

Built with Spring Boot, React, and a hand-rolled CRDT.

flux-eta-one.vercel.app

About

Real-Time Multi-User Collaborative Whiteboard

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages