How AppFlowy Implements the Collaborative Editing (Collab) Module: Architecture and Code
AppFlowy’s collaborative editing module uses a three-layer Rust architecture centered on AppFlowyCollabBuilder, which orchestrates CRDT-based document creation, local RocksDB persistence, and optional cloud synchronization through pluggable providers.
The collaborative editing module in the AppFlowy-IO/AppFlowy repository enables real-time, conflict-free document synchronization across devices. Built atop the Collab library’s OT/CRDT foundation, the implementation cleanly separates object lifecycle management, storage durability, and network synchronization. This architecture supports both offline-first local editing and seamless cloud collaboration through AppFlowy Cloud.
Three-Layer Architecture Overview
The collab module organizes functionality into distinct layers that handle creation, synchronization, and persistence:
| Layer | Responsibility | Core Types | Key Files |
|---|---|---|---|
| Collab Builder | Orchestrates Collab instance creation for documents, folders, and databases |
AppFlowyCollabBuilder, CollabBuilderConfig |
frontend/rust-lib/collab-integrate/src/collab_builder.rs |
| Plugin Provider | Abstracts sync behavior between local-only and cloud-connected modes | CollabCloudPluginProvider, CollabPluginProviderType |
frontend/rust-lib/collab-integrate/src/plugin_provider.rs |
| Persistence | Manages RocksDB storage and state vector restoration | CollabPersistenceImpl |
frontend/rust-lib/collab-integrate/src/collab_builder.rs (lines 172–225) |
The Collab Builder: Core Orchestration
Builder Structure and Initialization
The AppFlowyCollabBuilder struct defined in frontend/rust-lib/collab-integrate/src/collab_builder.rs serves as the central factory for all collaborative objects. It maintains thread-safe references to storage providers, snapshot handlers, and workspace integration:
pub struct AppFlowyCollabBuilder {
network_reachability: CollabConnectReachability,
plugin_provider: ArcSwap<Arc<dyn CollabCloudPluginProvider>>,
snapshot_persistence: ArcSwapOption<Arc<dyn SnapshotPersistence + 'static>>,
#[cfg(not(target_arch = "wasm32"))]
rocksdb_backup: ArcSwapOption<Arc<dyn RocksdbBackup>>,
workspace_integrate: Arc<dyn WorkspaceCollabIntegrate>,
embeddings_writer: Option<Weak<InstantIndexedDataWriter>>,
}
The builder requires two mandatory dependencies during initialization: a storage provider implementing CollabCloudPluginProvider and a WorkspaceCollabIntegrate implementation supplying workspace and device identifiers.
Object Creation Workflow
Creating a collaborative document follows a strict three-phase process orchestrated by the builder:
-
Validation and Object Construction: The
collab_objectmethod validates that the requested workspace matches the currently opened workspace (preventing race conditions) and constructs aCollabObjectcontaining the unique object ID, type (Document, Folder, or Database), and metadata. -
Local Persistence Attachment: The
build_collabmethod creates the low-levelCollabinstance and immediately attaches a RocksDB plugin for local durability. This ensures all changes persist to disk before any network transmission occurs. -
Cloud Sync Finalization: If
sync_enableis true (the default), thefinalizemethod queries theCollabCloudPluginProviderfor network plugins and attaches them to the collab instance, enabling real-time synchronization via WebSocket or HTTP.
Snapshot and Backup Support
The builder exposes set_snapshot_persistence for configuring point-in-time recovery capabilities and set_rocksdb_backup (native builds only) for database-level disaster recovery. These features enable undo/redo functionality and crash recovery while maintaining the core CRDT integrity.
Plugin Provider System
The CollabCloudPluginProvider Trait
Synchronization behavior is abstracted through the CollabCloudPluginProvider trait defined in frontend/rust-lib/collab-integrate/src/plugin_provider.rs:
pub trait CollabCloudPluginProvider: Send + Sync + 'static {
fn provider_type(&self) -> CollabPluginProviderType;
fn get_plugins(&self, context: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>>;
fn is_sync_enabled(&self) -> bool;
}
This trait enables the builder to remain agnostic about network implementation details. The get_plugins method receives a CollabPluginProviderContext containing the target collab instance and returns a vector of plugins handling authentication, encryption, and transport.
Local vs. Cloud Implementation
Two primary provider types exist:
- Local Provider: Returns an empty plugin vector and disables synchronization, creating offline-only collabs that still persist to RocksDB.
- AppFlowyCloud Provider: Implemented in
frontend/rust-lib/flowy-core/src/deps_resolve/cloud_service_impl.rs, this provider returns plugins that establish WebSocket connections to AppFlowy Cloud servers, enabling real-time multiplayer editing.
Persistence Layer Implementation
CollabPersistenceImpl satisfies the CollabPersistence trait required by the underlying Collab library. Located in the builder file (lines 172–190), this implementation:
- Loads existing CRDT update bytes from RocksDB when opening a document
- Saves the final state vector after each transaction commits
- Performs disk write-through via
write_collab_to_diskwhen initializing new documents with starter data
This layer guarantees that every collaborative object maintains strong local durability regardless of network connectivity status.
Real-World Usage Across AppFlowy
Document Management
The DocumentManager resolves its dependencies in frontend/rust-lib/flowy-core/src/deps_resolve/document_deps.rs by receiving a weak reference to the shared AppFlowyCollabBuilder. When users open documents, the manager invokes collab_builder.create_document() with the validated object metadata and database reference.
Folder and Database Integration
- Folder Manager: Uses
collab_builder.create_folder()infrontend/rust-lib/flowy-folder/src/manager.rsto maintain the workspace hierarchy as a collaborative tree structure. - Database Editor: Creates workspace-level database managers via
collab_builder.create_workspace_database_manager()infrontend/rust-lib/flowy-database2/src/services/database/database_editor.rs, enabling concurrent table and view editing.
User Awareness
Real-time cursor presence and user metadata sync through create_user_awareness, allowing multiple users to see each other’s selections and names across shared documents.
Implementation Examples
Creating a Cloud-Synced Document
let collab_builder = Arc::new(AppFlowyCollabBuilder::new(
storage_provider, // implements CollabCloudPluginProvider
workspace_integrate, // provides workspace/device IDs
None, // optional embeddings writer
));
let object = collab_builder.collab_object(
&workspace_id,
uid,
&doc_id,
CollabType::Document,
)?;
// `DataSource::Disk(None)` loads from RocksDB if it exists
let doc = collab_builder
.create_document(
object,
DataSource::Disk(None),
collab_db.clone(),
CollabBuilderConfig::default(),
None, // start with empty document
)
.await?;
When sync_enable remains true (default), finalize automatically attaches the AppFlowy Cloud plugin, making the document instantly collaborative.
Configuring Local-Only Mode
struct LocalProvider;
impl CollabCloudPluginProvider for LocalProvider {
fn provider_type(&self) -> CollabPluginProviderType {
CollabPluginProviderType::Local
}
fn get_plugins(&self, _ctx: CollabPluginProviderContext) -> Vec<Box<dyn CollabPlugin>> {
vec![]
}
fn is_sync_enabled(&self) -> bool { false }
}
let builder = AppFlowyCollabBuilder::new(
LocalProvider,
workspace_integrate,
None,
);
All collabs created with this configuration persist locally via RocksDB without transmitting data to external servers.
Adding Snapshot Persistence
let snapshot_persistence = Arc::new(MySnapshotPersistence::new(...));
builder.set_snapshot_persistence(snapshot_persistence);
This enables point-in-time recovery and advanced undo/redo capabilities across all managed collaborative objects.
Summary
- AppFlowyCollabBuilder serves as the central factory for all collaborative objects, managing the lifecycle from creation to synchronization.
- Three-layer separation between builder logic, plugin provision, and persistence ensures the module remains extensible and testable.
- RocksDB integration guarantees offline-first durability, storing CRDT state vectors locally before any network transmission.
- Pluggable providers allow seamless switching between local-only mode and AppFlowy Cloud synchronization without changing application code.
- Type-specific creators (
create_document,create_folder,create_user_awareness) provide ergonomic APIs for Document, Folder, and Database managers throughout the codebase.
Frequently Asked Questions
What is the Collab library and how does it relate to AppFlowy?
The Collab library is AppFlowy’s core OT/CRDT engine that handles conflict resolution and state merging for concurrent edits. AppFlowy’s collaborative editing module wraps this library with additional logic for persistence, plugin management, and workspace integration, creating a complete user-facing synchronization system.
How does the collab module handle offline editing?
The module implements an offline-first architecture where CollabPersistenceImpl immediately writes all CRDT updates to RocksDB via the local plugin. Changes accumulate locally regardless of network status, and the CollabCloudPluginProvider only transmits accumulated updates once connectivity restores, ensuring no data loss during disconnections.
Can I use the collaborative editing module without AppFlowy Cloud?
Yes. By implementing CollabCloudPluginProvider to return CollabPluginProviderType::Local and an empty plugin vector (as shown in the LocalProvider example), you create a fully functional offline collab system. All documents persist locally and sync resumes only if you later swap the provider for a cloud-enabled implementation.
What distinguishes CollabPersistence from SnapshotPersistence?
CollabPersistence (implemented by CollabPersistenceImpl) handles mandatory CRDT state storage required for basic document functionality—loading updates on open and saving state vectors after transactions. SnapshotPersistence is optional and manages higher-level recovery points, enabling features like version history, undo/redo trees, and crash recovery snapshots beyond the core CRDT requirements.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →