| Crates.io | loro |
| lib.rs | loro |
| version | 1.8.1 |
| created_at | 2022-08-07 12:29:50.518504+00 |
| updated_at | 2025-09-23 13:32:43.23024+00 |
| description | Loro is a high-performance CRDTs framework. Make your app collaborative efforlessly. |
| homepage | https://loro.dev |
| repository | https://github.com/loro-dev/loro/ |
| max_upload_size | |
| id | 640197 |
| size | 436,987 |
Loro is a high‑performance CRDT framework for local‑first apps that keeps state consistent across devices and users, works offline and in real time, automatically merges conflicts, and enables undo/redo and time travel.
Loro is a high-performance CRDTs library offering Rust, JavaScript and Swift APIs.
LoroDoc::new() - Initialize a new collaborative documentget_text, get_list, get_map, get_tree, get_movable_list, get_counter (feature "counter")subscribe or subscribe_root - React to document/container modificationsexport and import - Save and load documentsexport(ExportMode::updates(&vv)) + import - Exchange incremental updates (see ExportMode::updates)subscribe_local_update - Send changes over WebSocket/WebRTCset_peer_id - Ensure each client has a unique identifierget_text - Initialize a collaborative text containerLoroText::insert, LoroText::delete, LoroText::apply_deltaLoroText::mark - Add bold, italic, links, custom stylesLoroText::get_cursor + LoroDoc::get_cursor_pos - Stable positions across editsconfig_text_style / config_default_text_style - Define expand behavior for marksget_list - Arrays with push, insert, deleteget_map - Objects with insert, get, deleteget_tree - Trees with create, mov, mov_toget_movable_list - Drag-and-drop with mov, setget_counter (feature "counter") - Distributed counters with incrementget_cursor data if needed.UndoManager - Local undo of user’s own editscheckout to any Frontiers - Debug or review historyoplog_vv, state_frontiers, VersionVectorfork or fork_at - Create branches for experimentationimport - Combine changes from forked documentsexport(ExportMode::updates(&their_vv)) - Send only changes (see ExportMode::updates)export(ExportMode::Snapshot) - Full state with compressed history (see ExportMode::Snapshot)export(ExportMode::shallow_snapshot(&frontiers)) - State without partial history (see ExportMode::shallow_snapshot)LoroDoc (container management, versioning, import/export, events)
That page hosts examples and details for most important methods you’ll use day-to-day.Add to your Cargo.toml:
[dependencies]
loro = "^1"
get_text, get_map, get_list, get_movable_list, get_treeexport(ExportMode::…), import, from_snapshotoplog_vv, state_frontiers, checkout/checkout_to_latest, revert_to, forksubscribe, subscribe_root, subscribe_local_update (send deltas to peers)get_path_to_container, get_deep_value / ToJson (to_json_value()), optional jsonpath (feature)Optional cargo features:
[dependencies]
loro = { version = "^1", features = ["jsonpath"] }
use loro::{LoroDoc, ExportMode};
use std::sync::Arc;
let a = LoroDoc::new();
let b = LoroDoc::new();
// Listen for container diffs on `a`
let _changes = a.subscribe_root(Arc::new(|e| {
println!("changed containers: {}", e.events.len());
}));
a.get_text("text").insert(0, "Hello, Loro!").unwrap();
a.commit(); // events fire on commit/export/import/checkout
// Sync via export/import (send `updates` via your transport)
let updates = a.export(ExportMode::all_updates()).unwrap();
b.import(&updates).unwrap();
assert_eq!(a.get_deep_value(), b.get_deep_value());
use loro::LoroDoc;
let doc = LoroDoc::new();
let text = doc.get_text("text");
text.insert(0, "Hello").unwrap();
let v0 = doc.state_frontiers();
text.insert(5, ", world").unwrap();
assert_eq!(text.to_string(), "Hello, world");
// Time travel to v0 (read-only)
doc.checkout(&v0).unwrap();
assert_eq!(text.to_string(), "Hello");
// Return to latest and revert
doc.checkout_to_latest();
doc.revert_to(&v0).unwrap();
assert_eq!(text.to_string(), "Hello");