# How AppFlowy Implements the Collaborative Editing (Collab) Module: Architecture and Code

> Discover AppFlowy's collaborative editing architecture built on Rust CRDTs. Learn how the collab module uses AppFlowyCollabBuilder for document creation, persistence, and cloud sync.

- Repository: [AppFlowy-IO/AppFlowy](https://github.com/AppFlowy-IO/AppFlowy)
- Tags: architecture
- Published: 2026-03-03

---

**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](https://github.com/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`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/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`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/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`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/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`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/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:

```rust
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`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/frontend/rust-lib/collab-integrate/src/plugin_provider.rs):

```rust
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`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/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`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/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()` in [`frontend/rust-lib/flowy-folder/src/manager.rs`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/frontend/rust-lib/flowy-folder/src/manager.rs) to maintain the workspace hierarchy as a collaborative tree structure.
- **Database Editor**: Creates workspace-level database managers via `collab_builder.create_workspace_database_manager()` in [`frontend/rust-lib/flowy-database2/src/services/database/database_editor.rs`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/frontend/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

```rust
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

```rust
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

```rust
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.