A real-time, ephemeral clipboard for sharing text across devices. No accounts, no setup — just a room code.
GoKlip lets you sync code snippets, notes, and text between devices instantly through the browser. Open a room, share the 10-character code, and start typing. Everything auto-deletes after 24 hours.
- Real-time sync — WebSocket-powered, keystroke-level collaboration across multiple devices.
- Ephemeral by design — All data self-destructs after 24 hours via MongoDB TTL indexes.
- Markdown preview — Toggle between editing and rendered Markdown with
Ctrl+M. - No accounts — Share via URL or room code. Nothing to sign up for.
- Keyboard-first —
Ctrl+Sto save,Ctrl+Shift+Cto copy, and more.
graph TD
Browser["Browser Client"]
subgraph Frontend["Frontend"]
ReactApp["React / Vite App"]
end
Browser -- "HTTP / WebSockets" --> ReactApp
subgraph Backend["Backend"]
Express["Express API"]
SocketServer["Socket.io Server"]
end
ReactApp -- "HTTP Requests" --> Express
ReactApp -- "WebSocket Events" --> SocketServer
MongoDB[("MongoDB")]
Express -- "Mongoose" --> MongoDB
SocketServer -- "Mongoose" --> MongoDB
Why this stack?
- WebSockets over polling — A persistent bidirectional connection means text updates appear instantly, not on the next poll interval.
- MongoDB TTL indexes — The database handles cleanup automatically. No cron jobs, no background workers.
- Zod on the socket layer — WebSocket payloads skip Express middleware entirely, so Zod validates every incoming event directly in the socket handlers.
| Layer | Technologies |
|---|---|
| Frontend | React 19, Vite, Tailwind CSS v4, Socket.IO Client |
| Backend | Node.js, Express, Socket.IO, Mongoose, Zod |
| Database | MongoDB |
goklip/
├── client/ # React frontend (Vite)
│ ├── src/
│ │ ├── features/ # Feature-sliced modules (editor, landing)
│ │ ├── components/ # Shared UI components
│ │ ├── pages/ # Route pages
│ │ └── services/ # API and socket clients
│ └── ...
├── server/ # Express + Socket.IO backend
│ ├── models/ # Mongoose schemas
│ ├── routes/ # REST API routes + tests
│ └── utils/ # Zod schemas, helpers
└── ...
git clone https://github.com/devo-id/GoKlip.git
cd GoKlipcd server
npm install
cp .env.example .envEdit server/.env if needed. Defaults work out of the box with a local MongoDB:
PORT=3000
MONGO_URI=mongodb://localhost:27017/goklip
ALLOWED_ORIGINS=http://localhost:5173,http://127.0.0.1:5173cd ../client
npm install
cp .env.example .envThe default VITE_API_URL points to http://localhost:3000.
In one terminal:
cd server
node server.jsIn another:
cd client
npm run devOpen http://localhost:5173 and you're in.
Tip: Install
nodemonglobally (npm i -g nodemon) and runnodemon server.jsfor auto-reloading during backend development.
GoKlip exposes a REST API and a WebSocket interface. If you want to build your own client, here's what's available.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/clipboards |
Create or join a room. Optionally pass { customId: "my-room" }. Returns a generated 10-char hex ID if none is provided. |
DELETE |
/api/clipboards/:id |
Delete a clipboard room. |
GET |
/health |
Health check. |
Emit:
| Event | Payload | Description |
|---|---|---|
room:join |
customId (string) |
Join a clipboard room. |
content:update |
{ customId, content } |
Broadcast a text change to all connected clients. |
content:save |
{ customId, content } |
Persist current content to MongoDB. |
Listen:
| Event | Payload | Description |
|---|---|---|
content:update |
content (string) |
Receive text updates from other clients. |
room:users_count |
count (number) |
Current number of users in the room. |
| Command | Description |
|---|---|
npm test |
Run the Jest + Supertest test suite. |
| Command | Description |
|---|---|
npm run dev |
Start the Vite dev server. |
npm run build |
Build for production. |
npm run lint |
Run ESLint. |
npm run preview |
Preview the production build locally. |
cd server
npm testBackend tests use Jest and Supertest to validate the REST API.
- Frontend → Deploy to Vercel, Netlify, or Cloudflare Pages. Set
VITE_API_URLto your production backend URL at build time. - Backend → Deploy to Render, Railway, or any Node.js host. Set
MONGO_URIto a production database and add your frontend domain toALLOWED_ORIGINSfor CORS.
Contributions are welcome — see CONTRIBUTING.md for the full guide.
The short version:
- Fork the repo and create a branch (
fix/somethingorfeature/something). - Run
npm testin/serverandnpm run lintin/clientbefore pushing. - Open a PR and link the relevant issue.