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:

  1. Validation and Object Construction: The collab_object method validates that the requested workspace matches the currently opened workspace (preventing race conditions) and constructs a CollabObject containing the unique object ID, type (Document, Folder, or Database), and metadata.

  2. Local Persistence Attachment: The build_collab method creates the low-level Collab instance and immediately attaches a RocksDB plugin for local durability. This ensures all changes persist to disk before any network transmission occurs.

  3. Cloud Sync Finalization: If sync_enable is true (the default), the finalize method queries the CollabCloudPluginProvider for 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_disk when 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

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →