Real-time collaborative editing for Obsidian. Share your vault with others and edit together with live cursors, file sync, presence tracking, and end-to-end encryption.
cd server && npm install && npm run build && npm startRuns on http://localhost:3000. Verify: curl http://localhost:3000/healthz
Build from source:
cd plugin && npm install && npm run buildCopy into your vault:
mkdir -p /path/to/vault/.obsidian/plugins/obsidian-live-share
cp plugin/main.js plugin/styles.css manifest.json \
/path/to/vault/.obsidian/plugins/obsidian-live-share/Or install via BRAT for automatic updates.
Enable Live Share in Settings > Community Plugins.
Open Settings > Live Share and set your Server URL, Display name, and Shared folder (leave empty for the whole vault).
Host: Run Live Share: Start session from the command palette. An invite link is copied to your clipboard.
Guest: Run Live Share: Join session and paste the invite link. Files sync automatically.
- Real-time editing — Yjs CRDT-powered character-level sync with live cursors and selections
- File sync — Creates, deletes, renames, and binary files sync automatically
- End-to-end encryption — AES-256-GCM with PBKDF2 key derivation; passphrase never leaves the invite link
- Presence panel — See who's connected, what file they're viewing, follow/summon/kick users
- Permissions — Host can set guests to read-write or read-only (enforced server-side), with per-file overrides
- Guest approval — Optionally require host approval before guests can join
- Kick protection — Kicked users must be re-approved by the host to rejoin, even when approval is not required
- Host transfer — Hand off the host role to another participant
- Presentation mode — Auto-broadcast your navigation to all participants
- Canvas collaboration — Real-time sync of
.canvasfiles - Cross-platform support — Windows filename character mapping for seamless sync between platforms
- Offline queue — File operations are buffered when disconnected and replayed on reconnect
- Auto-reconnect — Optionally rejoin the previous session on startup
| Command | Description | Access |
|---|---|---|
| Start session | Create a room and start hosting | Anyone |
| Join session | Join via invite link | Anyone |
| End session | End the session for all participants | Host |
| Leave session | Leave the session | Guest |
| Copy invite link | Copy invite to clipboard | Anyone in session |
| Show collaborators panel | Open the presence sidebar | Anyone |
| Focus participants here | Send a "look here" notification | Anyone in session |
| Summon all participants here | Navigate all users to your cursor | Host |
| Summon a specific participant | Navigate one user to your cursor | Host |
| Reload all files from host | Re-download shared files | Guest |
| Toggle presentation mode | Auto-broadcast navigation | Host |
| Transfer host role | Offer host role to another user | Host |
| Set file permissions | Per-file read-only/read-write | Host |
| Show audit log | View session event log | Host |
| Log in with GitHub | GitHub OAuth authentication | Anyone |
| Log out | Clear stored authentication | Anyone |
| Setting | Default | Description |
|---|---|---|
| Server URL | http://localhost:3000 |
Your Live Share server address |
| Server password | — | Optional server password |
| Display name | Anonymous |
Your name shown to collaborators |
| Cursor color | #7c3aed |
Your cursor color in the editor |
| Shared folder | — | Subfolder to share (empty = whole vault) |
| Require approval | false |
Require host approval for guests |
| Approval timeout | 60 |
Auto-deny join requests after N seconds (0 = disabled) |
| Notifications | true |
Toggle non-critical status notices |
| Auto-reconnect | true |
Rejoin previous session on startup |
| Debug logging | false |
Write debug logs to a vault file |
| Excluded patterns | — | Glob patterns for files to exclude from sync |
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Server port |
SERVER_PASSWORD |
— | Restrict access to authorized clients |
TLS_CERT / TLS_KEY |
— | Enable HTTPS/WSS |
REQUIRE_GITHUB_AUTH |
false |
Require GitHub OAuth |
GITHUB_CLIENT_ID |
— | GitHub OAuth client ID |
GITHUB_CLIENT_SECRET |
— | GitHub OAuth client secret |
JWT_SECRET |
— | JWT signing secret (required with auth) |
CORS_ORIGIN |
* |
Allowed CORS origins |
Exclude files from sync by adding glob patterns in Settings > Live Share > Excluded patterns.
Default excludes: .obsidian/**, .trash/**.
Example patterns: drafts/**, *.tmp, private/**.
The system uses a stateless relay server and two WebSocket channels:
- Yjs sync (
/ws-mux/:roomId) — Multiplexed binary channel for Yjs CRDT updates and cursor awareness per file - Control (
/control/:roomId) — JSON messages for file operations, presence, permissions, and session lifecycle
The host's vault is the source of truth. Text files sync character-by-character via Yjs. Binary files transfer as base64 with automatic chunking (up to 50 MB).
- E2E encryption (AES-256-GCM, PBKDF2 100k iterations) for file content in control messages
- Timing-safe token comparison on all auth checks
- Server-side enforcement of read-only permissions and host-only operations
- Path traversal protection, rate limiting, payload size limits
- Use TLS (
wss://) to encrypt all traffic including Yjs sync data
See docs/security.md for the full threat model.
# Server: 108 tests
cd server && npm run dev && npm test && npm run lint
# Plugin: 310 tests
cd plugin && npm run dev && npm test && npm run lintNetwork use. This plugin requires a relay server. All sync, file transfer, and presence data is sent over WebSocket connections to a server URL you configure. You can self-host the included server. File content can be end-to-end encrypted so the server cannot read it.
Optional account. GitHub OAuth login is available but not required. Without it, a local anonymous ID is generated.
This project is licensed under the MIT License. See LICENSE for details.