# 3D Lego-like Brick Builder Web App Build and collaborate in real-time on 3D models using rectangular bricks. This multi-user application lets several people create designs together in a shared 3D space using Lego-like bricks. ![App Screenshot](/public/Screenshot.png) > Fork of [bhushan6/lego-builder](https://github.com/bhushan6/lego-builder) (MIT — see `LICENSE`, attribution preserved). The original used the **Liveblocks** SaaS for real-time collaboration; this fork replaces it with a **self-hosted, sovereign WebSocket backend** (`server/index.js`) — no third-party SaaS, no API key. ## Features - **3D Rendering**: Utilizes `three.js` and `react-three-fiber` for efficient and smooth 3D rendering. - **Real-time Collaboration**: Self-hosted WebSocket relay (`server/index.js`) synchronizes the shared build (`bricks`, `cursorColors`) and per-user presence/cursors across everyone in a room. - **Intuitive UI**: Built with `radix ui`. - **State Management**: `Zustand`, with a custom `roomSync` middleware (`src/store/roomSync.js`) that exposes the same store surface the components expect. ## Technologies Used - [React](https://reactjs.org/) - [three.js](https://threejs.org/) - [react-three-fiber](https://github.com/pmndrs/react-three-fiber) - [radix ui](https://www.radix-ui.com/) - [zustand](https://docs.pmnd.rs/zustand/getting-started/introduction) - [ws](https://github.com/websockets/ws) — WebSocket server for the real-time backend - [Vite](https://vitejs.dev/) ## Real-time architecture - **`server/index.js`** — a standalone Node WebSocket relay (uses `ws`, no build step). One server hosts many rooms; per room it keeps the current shared storage snapshot (`{ bricks, cursorColors }`) plus the connected clients. Clients connect with `ws(s)://HOST/?room=`. JSON protocol: - server → client: `init`, `join`, `leave`, `presence`, `storage`, `event` - client → server: `presence`, `storage` (last-writer-wins), `event` (ephemeral cursors, relayed to others only, never persisted) - **`src/store/roomSync.js`** — a Zustand middleware that drops in for `@liveblocks/zustand`. It exposes `state.liveblocks.{enterRoom, leaveRoom, status, others, room}` where `room` has `broadcastEvent`, `subscribe("event", cb)` and no-op `history.undo/redo` stubs — so the existing components work unchanged. ## Local Development ### Prerequisites - [Node.js](https://nodejs.org/) (18+; tested on Node 26) - [npm](https://www.npmjs.com/) ### Setup 1. Clone the repository: ```bash git clone https://git.saillant.cc/electron-rare/lego-builder.git cd lego-builder ``` 2. Install dependencies: ```bash npm install ``` 3. (Optional) point the client at a specific realtime server. Create `.env`: ```bash echo "VITE_RT_URL=ws://localhost:8090" > .env ``` If unset, the client falls back to `ws://localhost:8090` in dev, or `wss:///blocs-rt` when served over HTTPS in production (that path is routed to the relay by the deployment infra). 4. Start the realtime server (in one terminal): ```bash npm run server # listens on $PORT (default 8090) ``` 5. Start the dev server (in another terminal): ```bash npm run dev ``` 6. Open the app at the URL Vite prints (note the `/blocs-pro/` base path, e.g. http://localhost:5173/blocs-pro/). Open it in two browsers/tabs and join the **same Room ID** to collaborate. ### Build ```bash npm run build # outputs dist/, served under base /blocs-pro/ ``` ## Contribution Feel free to fork the project, open issues, and submit pull requests. Any contribution is highly appreciated!