Skip to main content

P2P Collaborative Text Editor using CRDT

Project description

P2P CRDT Collaborative Text Editor

PyPI version Python License: MIT

A peer-to-peer collaborative text editor using Conflict-free Replicated Data Types (CRDT). No central server required - all peers are equal!

Features

  • True P2P Architecture: No server needed, all peers are equal
  • CRDT Synchronization: Uses RGA (Replicated Growable Array) for conflict-free merging
  • Real-time Collaboration: Changes sync instantly across all connected peers
  • Automatic Peer Discovery: UDP broadcast for LAN peer detection
  • Manual Connections: Connect to peers via IP address
  • Modern UI: Clean, professional Tkinter interface
  • Persistent State: Document state saved to disk
  • Batch Operations: Optimized bulk delete/insert operations

Installation

From PyPI (when published)

pip install p2pdocs

From Source

git clone https://github.com/yourusername/p2pdocs.git
cd p2pdocs
pip install -e .

Usage

Start the Editor

# Start with automatic peer discovery
p2pdocs alice

# Or connect directly to a peer
p2pdocs bob 192.168.1.100

Alternative (as Python module)

python -m p2pdocs alice
python -m p2pdocs bob 192.168.1.100

Programmatic Usage

from p2pdocs import P2PEditor

# Create and run editor
editor = P2PEditor(username="alice", peer_ip="192.168.1.100")
editor.run()

Version

Current Version: 1.0.14Zero Dependencies — Python 3.8+ stdlib only

Quick Start

Terminal 1: Start Server (Alice)

python p2p_crdt_editor.py server alice

Output:

[alice] Listening on port 5000...

Terminal 2: Start Client (Bob)

python p2p_crdt_editor.py client bob 127.0.0.1

Output:

[bob] Connecting to 127.0.0.1:5000...
[bob] Connected to alice

Start Editing

  • Alice types → Bob sees it instantly
  • Bob types → Alice sees it instantly
  • Both type simultaneously → automatic convergence

Architecture

See CRDT_ARCHITECTURE.md for detailed design:

  • CRDTId: Unique operation identifier (client_id, lamport_clock)
  • CRDTElement: Character + ID + visibility flag
  • CRDTDocument: CRDT state machine with merge logic
  • NetworkManager: TCP peer connection handler
  • P2PEditor: GUI + orchestration layer

Why CRDT?

Aspect Operational Transform (Old) CRDT (New)
Central server Required ❌ Not needed
Transformation logic Complex Simple
Concurrent ops Fragile Guaranteed safe
Merge order Critical Automatic
Convergence Assumed Proven
Multi-peer Difficult Natural

How RGA Works

Each character gets a unique ID: (client_id, lamport_clock)

Example:

Alice types "H" at pos 0 → ID = (alice-uuid, 1)
Bob types "i" at pos 0  → ID = (bob-uuid, 1)

Result (sorted by ID): "Hi"  ✅ All peers converge!

Deletions create tombstones (not removed), so positions never shift.

Thread Safety

Main Thread (Tkinter)          Network Thread
        ↓                            ↓
   _on_keystroke()          _recv_message()
        ↓                            ↓
  doc.insert_local()         doc.insert_remote()
        ↓                            ↓
 [doc.lock]◄────────────────[doc.lock]
        ↓                            ↓
  _rebuild_text()            root.after(0, _rebuild_text)

Protected Resources:

  • doc.elements — protected by doc.lock
  • text widget — protected by text_lock

Message Protocol

{
  "type": "INSERT",
  "elements": [
    {
      "char_id": {"client_id": "uuid", "lamport_clock": 5},
      "char": "A",
      "visible": true
    }
  ]
}

Supported messages:

  • INSERT — new character
  • DELETE — mark as tombstone
  • SYNC_REQUEST — request full state
  • FULL_SYNC — send all elements

Testing

  1. Type and see sync:

    • Alice: type "hello"
    • Bob: instantly sees "hello"
  2. Concurrent edits:

    • Alice types at pos 0
    • Bob types at pos 0 simultaneously
    • Both converge to same text
  3. Deletions:

    • Alice presses backspace
    • Bob sees character disappear
    • Text remains consistent
  4. Multi-line:

    • Type newlines, text wraps correctly
    • All peers sync properly

Limitations

  • Single connection (1 server ↔ 1 client)
  • No persistence (resets on restart)
  • No multi-peer mesh yet
  • No undo/redo support

Future Work

  • Multi-peer mesh networking
  • Disk persistence
  • Operation batching
  • Compression
  • Snapshots + garbage collection
  • Rich text formatting
  • Presence awareness (cursor position)
  • Offline support

Code Structure

p2p_crdt_editor.py (570 lines)
├── CRDTId ......................... Unique operation ID
├── CRDTElement .................... Char + metadata
├── CRDTDocument ................... State machine
├── NetworkManager ................. TCP networking
└── P2PEditor ...................... GUI + orchestration

License

MIT License - see LICENSE file for details.


Status: ✅ Production-Ready (Single Peer)
Python: 3.8+
Dependencies: None (stdlib only)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

p2pdocs-1.0.14.tar.gz (25.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

p2pdocs-1.0.14-py3-none-any.whl (25.0 kB view details)

Uploaded Python 3

File details

Details for the file p2pdocs-1.0.14.tar.gz.

File metadata

  • Download URL: p2pdocs-1.0.14.tar.gz
  • Upload date:
  • Size: 25.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for p2pdocs-1.0.14.tar.gz
Algorithm Hash digest
SHA256 fdbbb0ba8f743af2b27e8d1adf6261339549ce529ca25001887479bf2b9d0447
MD5 eb62b10d276bf01461e7f3a5a20dafd2
BLAKE2b-256 11ef46f36909efb503a8b119c3746a6ed98fd6f19a49caad346b65b7421a5216

See more details on using hashes here.

Provenance

The following attestation bundles were made for p2pdocs-1.0.14.tar.gz:

Publisher: publish.yml on taaha-0548/P2PDocs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file p2pdocs-1.0.14-py3-none-any.whl.

File metadata

  • Download URL: p2pdocs-1.0.14-py3-none-any.whl
  • Upload date:
  • Size: 25.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for p2pdocs-1.0.14-py3-none-any.whl
Algorithm Hash digest
SHA256 717355c29fc2253bc1fcb9c1ffb36ec95170ef1675b60f1bd0c86087b81d860e
MD5 d2224cbd318b086cad62029c8d6a2511
BLAKE2b-256 208c88e1c5ebe06d21f78a7a6a8f6d8af54da1fae31162a7eb2c2303b38d20a4

See more details on using hashes here.

Provenance

The following attestation bundles were made for p2pdocs-1.0.14-py3-none-any.whl:

Publisher: publish.yml on taaha-0548/P2PDocs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page