Expand description
§Loro
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.
§Common Tasks & Examples
§Getting Started
- Create a document:
LoroDoc::new()- Initialize a new collaborative document - Add containers:
get_text,get_list,get_map,get_tree,get_movable_list,get_counter(feature “counter”) - Listen to changes:
subscribeorsubscribe_root- React to document/container modifications - Export/Import state:
exportandimport- Save and load documents
§Real-time Collaboration
- Sync between peers:
export(ExportMode::updates(&vv))+import- Exchange incremental updates (seeExportMode::updates) - Stream updates:
subscribe_local_update- Send changes over WebSocket/WebRTC - Set unique peer ID:
set_peer_id- Ensure each client has a unique identifier - Handle conflicts: Automatic - All Loro data types are CRDTs that merge concurrent edits
§Rich Text Editing
- Create rich text:
get_text- Initialize a collaborative text container - Edit text:
LoroText::insert,LoroText::delete,LoroText::apply_delta - Apply formatting:
LoroText::mark- Add bold, italic, links, custom styles - Track cursor positions:
LoroText::get_cursor+LoroDoc::get_cursor_pos- Stable positions across edits - Configure styles:
config_text_style/config_default_text_style- Define expand behavior for marks
§Data Structures
- Ordered lists:
get_list- Arrays withpush,insert,delete - Key-value maps:
get_map- Objects withinsert,get,delete - Hierarchical trees:
get_tree- Trees withcreate,mov,mov_to - Reorderable lists:
get_movable_list- Drag-and-drop withmov,set - Counters:
get_counter(feature “counter”) - Distributed counters withincrement
§Ephemeral State & Presence
- Not currently provided in the Rust crate. Model presence in your app layer alongside CRDT updates (e.g., via your network transport). Cursors can be shared using
get_cursordata if needed.
§Version Control & History
- Undo/redo:
UndoManager- Local undo of user’s own edits - Time travel:
checkoutto anyFrontiers- Debug or review history - Version tracking:
oplog_vv,state_frontiers,VersionVector - Fork documents:
forkorfork_at- Create branches for experimentation - Merge branches:
import- Combine changes from forked documents
§Performance & Storage
- Incremental updates:
export(ExportMode::updates(&their_vv))- Send only changes (seeExportMode::updates) - Compact history:
export(ExportMode::Snapshot)- Full state with compressed history (seeExportMode::Snapshot) - Shallow snapshots:
export(ExportMode::shallow_snapshot(&frontiers))- State without partial history (seeExportMode::shallow_snapshot)
§Documentation
- Start with the Rust API docs for
LoroDoc(container management, versioning, import/export, events) That page hosts examples and details for most important methods you’ll use day-to-day. - Loro Website for more details and guides
- Loro Examples for more examples and guides
§Getting Started
Add to your Cargo.toml:
[dependencies]
loro = "^1"§LoroDoc quick tour
- Containers:
get_text,get_map,get_list,get_movable_list,get_tree - Import/Export:
export(ExportMode::…),import,from_snapshot - Versioning:
oplog_vv,state_frontiers,checkout/checkout_to_latest,revert_to,fork - Events:
subscribe,subscribe_root,subscribe_local_update(send deltas to peers) - Paths/JSON:
get_path_to_container,get_deep_value/ToJson(to_json_value()), optionaljsonpath(feature)
Optional cargo features:
[dependencies]
loro = { version = "^1", features = ["jsonpath"] }§Quick Examples
- Local edits, change events, and two-peer sync
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());- Time travel and revert
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");Re-exports§
pub use loro_kv_store as kv_store;
Modules§
Macros§
- loro_
value - A macro for creating
LoroValue. It works just like thejson!macro inserde_json.
Structs§
- Change
Meta Changeis a grouped continuous operations that share the same id, timestamp, commit message.- Change
Modifier - Commit
Options - Options for configuring a commit operation.
- Configure
- Counter
Span - This struct supports reverse repr:
fromcan be less thanto. We need this because it’ll make merging deletions easier. - DocAnalysis
- First
Commit From Peer Payload - The payload of the first commit from a peer callback.
- Fractional
Index - Frontiers
NotIncluded - ID
- It’s the unique ID of an Op represented by PeerID and Counter.
- IdLp
- It’s the unique ID of an Op represented by PeerID and Lamport clock. It’s used to define the total order of Ops.
- IdSpan
- This struct supports reverse repr: CounterSpan’s from can be less than to. But we should use it conservatively. We need this because it’ll make merging deletions easier.
- ImVersion
Vector - Immutable version vector
- Import
Blob Metadata - Import
Status - Inner
Undo Manager - UndoManager is responsible for managing undo/redo from the current peer’s perspective.
- Internal
String - Json
Change - Json
Future OpWrapper - JsonOp
- Json
Schema - Loro
Binary Value - LoroDoc
LoroDocis the entry for the whole document. When it’s dropped, all the associatedContainers will be invalidated.- Loro
List - LoroList container. It’s used to model arrays.
- Loro
List Value - LoroMap
- LoroMap container.
- Loro
MapValue - Loro
Movable List - LoroMovableList container
- Loro
String Value - Loro
Text - LoroText container. It’s used to model plaintext/richtext.
- Loro
Tree - LoroTree container. It’s used to model movable trees.
- Loro
Unknown - Unknown container.
- MemKv
Store - PreCommit
Callback Payload - The payload of the pre commit callback.
- Style
Config - Style
Config Map - Subscription
- A handle to a subscription created by GPUI. When dropped, the subscription is cancelled and the callback will no longer be invoked.
- Tree
Delta Item - The semantic action in movable tree.
- Tree
Diff - Tree
Diff Item - TreeID
- Each node of movable tree has a unique
TreeIDgenerated by Loro. - Tree
Node - A tree node in the LoroTree.
- Undo
Item Meta - The metadata of an undo item.
- Undo
Manager - UndoManager can be used to undo and redo the changes made to the document with a certain peer.
- Update
Options - Options for controlling the text update behavior.
- Version
Range - Version
Vector - VersionVector is a map from PeerID to Counter. Its a right-open interval.
- Version
Vector Diff
Enums§
- Cannot
Find Relative Position - Change
Travel Error - Container
- All the CRDT containers supported by Loro.
- ContainerID
- ContainerID includes the Op’s ID and the type. So it’s impossible to have the same ContainerID with conflict ContainerType.
- Container
Type - Encoded
Blob Mode - Event
Trigger Kind - The kind of the event trigger.
- Expand
Type - Whether to expand the style when inserting new text around it.
- Export
Mode - The mode of the export.
- Frontiers
- Frontiers representation.
- Index
- Json
Future Op - Json
List Op - Json
MapOp - Json
Movable List Op - Json
OpContent - Json
Text Op - Json
Tree Op - Loro
Encode Error - Loro
Error - Loro
Tree Error - Loro
Value - LoroValue is used to represents the state of CRDT at a given version.
- Text
Delta - Tree
External Diff - Tree
Parent Id - Undo
OrRedo - Update
Timeout Error - Value
OrContainer - It’s a type that can be either a value or a container.
Constants§
- LORO_
VERSION - The version of the loro crate
Traits§
- Apply
Diff - Container
Trait - The common trait for all the containers. It’s used internally, you can’t implement it directly.
- Into
Container Id - KvStore
- ToJson
Functions§
Type Aliases§
- Counter
- If it’s the nth Op of a peer, the counter will be n.
- First
Commit From Peer Callback - The callback of the first commit from a peer.
- Lamport
- It’s the Lamport clock
- Local
Update Callback - The callback of the local update.
- Loro
Result - OnPop
- OnPush
- When a undo/redo item is pushed, the undo manager will call the on_push callback to get the meta data of the undo item. The returned cursors will be recorded for a new pushed undo item.
- PeerID
- Unique id for each peer. It’s a random u64 by default.
- Peer
IdUpdate Callback - The callback of the peer id change. The second argument is the next counter for the peer.
- PreCommit
Callback - Timestamp