Barebones Rust CLI client and server for collaborative plain-text peer to peer editing over TCP.
Uses Carnelia as the backend CRDT engine.
Linux / macOS:
curl -fsSL https://raw.githubusercontent.com/Agate-DB/Carnelia-Collab/master/install.sh | shWindows (PowerShell):
irm https://raw.githubusercontent.com/Agate-DB/Carnelia-Collab/master/install.ps1 | iexOr download the binary for your platform directly from GitHub Releases.
cargo install --git https://github.com/Agate-DB/Carnelia-CollabAfter installation, the carnelia-collab command is available in your PATH.
- TCP server that maintains room/doc text state.
- CLI clients connect, join a room/doc, and send insert/delete/cursor ops.
- Server broadcasts updates to all clients in the same room/doc.
- Plain-text snapshots are persisted to
data/<room>/<doc>. - MDCS
TextDocis used internally for edits;/syncrequests a snapshot.
Note
The TUI joins/leaves automatically and manages cursor movement and edits.
Remote cursors are shown as colored highlights, and a short cursor list is visible in the status line.
cargo run -- server --addr 0.0.0.0:4000 --data-dir dataHealth check (HTTP GET):
curl http://127.0.0.1:8080/healthcargo run -- tui --addr 127.0.0.1:4000 --user Alice --room demo --doc shared.txt
cargo run -- tui --addr 127.0.0.1:4000 --user Bob --room demo --doc shared.txtTip
For ngrok, use the public host:port as the --addr value.
Controls:
- Arrow keys: move cursor
- Home/End: line start/end
- Enter: newline
- Backspace/Delete: remove characters
- Ctrl+R: request sync
- Ctrl+Q or Esc: quit
- Build a release binary locally:
cargo build --release- Copy the binary to your server (VPS) and run it:
# example path after build
./target/release/testing_carnelia server --addr 127.0.0.1:4000 --data-dir data- Open the port in your firewall (e.g. 4000/tcp) if you are not using a proxy.
- Clients connect using your public IP or domain:
./target/release/testing_carnelia client --addr <public-ip>:4000 --user Alice --room demo --doc shared.txtUse Nginx stream to terminate TLS on port 443 and proxy to the TCP backend.
- Copy
deploy/nginx-stream.confto/etc/nginx/conf.d/collab-stream.conf. - Replace the certificate paths with your domain cert (e.g. Let’s Encrypt).
- Reload Nginx:
sudo nginx -t
sudo systemctl reload nginx- Run the server on localhost and connect clients through 443:
./target/release/testing_carnelia server --addr 127.0.0.1:4000 --data-dir data./target/release/testing_carnelia client --addr <your-domain>:443 --user Alice --room demo --doc shared.txt- Create a service that runs the binary with your preferred
--addrand--data-dir. - Ensure the working directory is writable for
data/snapshots.
ngrok can forward raw TCP so others can connect without a VPS. This is best for short demos.
- Install and authenticate ngrok (see ngrok docs):
- Start the server locally:
cargo run -- server --addr 127.0.0.1:4000 --data-dir data- Start ngrok TCP tunnel to port 4000:
ngrok tcp 4000- ngrok will print a public address like
tcp://0.tcp.ngrok.io:12345. Share the host and port with others:
cargo run -- client --addr 0.tcp.ngrok.io:12345 --user Alice --room demo --doc shared.txtNotes:
- ngrok TCP does not add TLS. For encrypted connections, use a VPS with Nginx stream + TLS.
- If you want a stable address, use an ngrok reserved TCP address.
Build and run the server in a container and publish port 4000. Via docker-compose:
docker compose up --buildSet your ngrok token (required for TCP tunnels) and watch the ngrok output in the container logs:
$env:NGROK_AUTHTOKEN = "<your-token>"
docker compose up --buildYou can still connect from clients using the host IP or from ngrok by forwarding port 4000 on the host:
ngrok tcp 4000The container also serves a health endpoint on port 8080:
curl http://127.0.0.1:8080/healthLine-delimited JSON over TCP.
- Client → Server:
Join,Insert,Delete,Cursor,SyncRequest,Ping - Server → Client:
Welcome,Applied,Presence,SyncResponse,Error
See src/protocol.rs for full message schemas.