{"id":4092,"library":"loro","title":"Loro Python Bindings","description":"Loro provides high-performance Python bindings for the Loro Conflict-free Replicated Data Type (CRDT) library. It enables real-time collaboration and local-first software development by offering conflict-free data synchronization across distributed environments. The library supports various rich data types like Text, List, Map, and Tree. Currently at version 1.10.3, it maintains an active development and release schedule.","status":"active","version":"1.10.3","language":"en","source_language":"en","source_url":"https://github.com/loro-dev/loro-py","tags":["CRDT","realtime","collaboration","local-first","data synchronization"],"install":[{"cmd":"pip install loro","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Requires Python 3.8 or newer for the bindings.","package":"python","optional":false}],"imports":[{"symbol":"LoroDoc","correct":"from loro import LoroDoc"}],"quickstart":{"code":"from loro import LoroDoc\n\n# Create a new document\ndoc = LoroDoc()\n\n# Get a text container (creates it if it doesn't exist)\ntext = doc.get_text(\"my-shared-text\")\n\n# Insert text at a specific position\ntext.insert(0, \"Hello, Loro!\")\n\n# You can also use other CRDT types like Map or List\nmap_container = doc.get_map(\"my-shared-map\")\nmap_container[\"key\"] = \"value\"\n\n# To observe changes, subscribe to the document\ndef on_change(event):\n    print(f\"Document changed: {event}\")\n\n# Store the subscription reference to prevent garbage collection if running in an interactive session\nsub = doc.subscribe_root(on_change)\n\n# Commit changes to generate an update (important for sharing/persisting)\ndoc.commit()\n\n# To get the current state as a snapshot\nsnapshot = doc.export(mode=\"snapshot\")\nprint(f\"Snapshot size: {len(snapshot)} bytes\")\n\n# To load a document from a snapshot\nnew_doc = LoroDoc()\nnew_doc.import_from(snapshot)\nprint(f\"Loaded text: {new_doc.get_text('my-shared-text').get_value()}\")","lang":"python","description":"Initialize a LoroDoc, interact with CRDT data types like Text and Map, subscribe to changes, commit operations, and export/import document snapshots for persistence or synchronization."},"warnings":[{"fix":"Update imports and instantiation from `from loro import Loro` to `from loro import LoroDoc`, and change `Loro()` to `LoroDoc()`.","message":"The `Loro` class was renamed to `LoroDoc` in Loro v1.0. Code using `Loro()` as the entry point will break.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"If you have documents saved with Loro v0.x, first upgrade to a version between v1.0.0 and v1.8.x, load and re-save your documents, then upgrade to the latest Loro version.","message":"Loro v1.9.0 and later removed legacy v0.x encoding support. Documents created with v0.x must be migrated via an intermediate Loro release (version <=1.8.x) before upgrading to v1.9.0 or newer.","severity":"breaking","affected_versions":">=1.9.0"},{"fix":"Instead of `def my_func(arg=[]):`, use `def my_func(arg=None): if arg is None: arg = []`. This ensures a fresh mutable object is used for each call unless explicitly provided.","message":"When defining Python functions that might interact with Loro's mutable data structures (e.g., passing a `LoroList` as a default argument to be modified), avoid using mutable objects as default argument values. This can lead to unexpected state sharing across function calls.","severity":"gotcha","affected_versions":"All Python versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}