# Core Architectural Components of the AppFlowy Project: A Deep Dive into the Flutter-Rust Stack

> Explore AppFlowy's core architectural components. Discover how its Flutter UI interfaces with a Rust engine via an FFI bridge and event dispatcher for seamless functionality.

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

---

**AppFlowy implements a modular, multi-language architecture that isolates the Flutter UI from a Rust-based core engine via an FFI bridge, using a plugin-based event dispatcher to coordinate domain-specific services for folders, documents, databases, and AI functionality.**

The AppFlowy project (AppFlowy-IO/AppFlowy) is structured as a cross-platform workspace application built with a strict separation between presentation and business logic. Understanding the core architectural components reveals how the codebase maintains portability across desktop and mobile platforms while delivering real-time collaborative features.

## Overview of the Multi-Layer Architecture

AppFlowy organizes its codebase into distinct layers that communicate through well-defined interfaces. The architecture separates platform-specific UI code from the business logic, enabling the core engine to run independently of the front-end implementation.

The stack consists of three primary layers: the Flutter front-end responsible for rendering, the Rust core engine handling business logic and state management, and the data persistence layer managing local storage and cloud synchronization.

## The Flutter Front-End and FFI Bridge

### Flutter UI Layer

The presentation layer resides in `frontend/appflowy_flutter/` and contains all Dart code for widgets, screens, and user interaction logic. This is the only platform-specific component, handling platform channels and native UI rendering while delegating all data operations to the Rust core.

### The FFI Bridge

Communication between Dart and Rust flows through the `frontend/rust-lib/dart-ffi/` crate. This bridge marshals data between the two languages, exposing Rust APIs to Flutter and serializing requests into events that the core engine can process.

When a user creates a new document in the UI, the Flutter layer calls into the `dart-ffi` crate, which forwards the request to the Rust dispatcher for execution.

## The Rust Core Engine

### AppFlowyCore Entry Point

The central orchestration happens in [`frontend/rust-lib/flowy-core/src/lib.rs`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/frontend/rust-lib/flowy-core/src/lib.rs). The `AppFlowyCore::new` function initializes the entire system, creating the configuration, logger, and background task scheduler.

```rust
// flowy-core/src/lib.rs – AppFlowyCore::new
let core = AppFlowyCore::new(config, runtime, stream_log_sender).await;

```

This entry point loads all domain service managers and establishes the dependency resolution system that wires services together.

### Event Dispatcher and Plugin System

The core uses an event-driven architecture to decouple UI calls from business logic implementation. The `make_plugins` function in [`frontend/rust-lib/flowy-core/src/module.rs`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/frontend/rust-lib/flowy-core/src/module.rs) registers all domain services with the `AFPluginDispatcher`.

```rust
// flowy-core/src/module.rs – make_plugins
pub fn make_plugins(
    folder_manager: Weak<FolderManager>,
    database_manager: Weak<DatabaseManager>,
    user_manager: Weak<UserManager>,
    document_manager: Weak<DocumentManager>,
    search_manager: Weak<SearchManager>,
    ai_manager: Weak<AIManager>,
    storage_manager: Weak<StorageManager>,
) -> Vec<Box<dyn AFPlugin>> {
    vec![
        Box::new(FolderPlugin::new(folder_manager)),
        Box::new(DatabasePlugin::new(database_manager)),
        // … other domain plugins …
    ]
}

```

Each plugin implements the `AFPlugin` trait and handles specific event types, allowing the system to route calls from the FFI bridge to the appropriate service handler.

## Domain Services and Business Logic

AppFlowy encapsulates each major feature area in its own crate, following a consistent pattern of trait-based service definitions and dependency resolution.

### Folder, Document, and Database Services

The primary domain crates include:

- **flowy-folder/**: Manages workspace hierarchy and view structures
- **flowy-document-pub/**: Handles rich-text document editing
- **flowy-database-pub/**: Manages grid and board views

Each service implements specific traits (e.g., `FolderService`, `DocumentService`) defined in their respective `*_pub` crates. The `FolderServiceImpl` in [`frontend/rust-lib/flowy-folder-pub/src/query.rs`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/frontend/rust-lib/flowy-folder-pub/src/query.rs) demonstrates this pattern:

```rust
// flowy-folder-pub/src/query.rs
pub trait FolderService: FolderQueryService + FolderViewEdit {}

pub struct FolderServiceImpl {
    folder_manager: Weak<FolderManager>,
    user: Weak<AuthenticateUser>,
}
impl FolderService for FolderServiceImpl {}

```

### AI and Search Services

Specialized services extend core functionality:

- **flowy-ai-pub/**: Generates content suggestions and manages embeddings using a local vector database
- **flowy-search-pub/**: Provides full-text indexing via Tantivy for fast document retrieval

### User and Storage Services

- **flowy-user-pub/**: Handles authentication and user preferences
- **flowy-storage-pub/**: Manages file attachments and binary data storage

Each service uses a dependency resolver (e.g., `FolderDepsResolver`, `DatabaseDepsResolver`) to receive its required dependencies, including the shared `AppFlowyCollabBuilder` and `ServerProvider`.

## Data Persistence and Collaboration

### Collab Integration

Real-time collaborative editing relies on the `collab-integrate/` and `collab-*` crates. The `AppFlowyCollabBuilder` constructs `Collab` instances that domain services use for CRDT-based conflict resolution.

All domain services share this collaboration layer, ensuring that changes to folders, documents, and databases merge correctly across concurrent edits.

### Local Storage

When operating offline, AppFlowy persists data via `flowy-sqlite/` and `flowy-storage/`. The `KVStorePreferences` and `StorageManager` handle local SQLite databases and file system storage, managed through the `FileStorageResolver`.

## Cloud and Server Infrastructure

### Server Layer

The `frontend/rust-lib/flowy-server/src/` directory contains the `ServerProvider`, which abstracts the difference between local-only mode and cloud synchronization. This layer supplies the `LoggedUser` implementation for authentication and manages remote storage adapters.

## Background Processing

### Task Scheduler

Long-running operations execute through the `TaskDispatcher` and `TaskRunner` found in [`frontend/rust-lib/lib-infra/src/task.rs`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/frontend/rust-lib/lib-infra/src/task.rs). Created during `AppFlowyCore::init`, this system manages periodic tasks like search indexing and cloud uploads without blocking the main thread.

## How the Components Connect at Runtime

The startup sequence demonstrates how these architectural components integrate:

1. **Initialization**: `AppFlowyCore::new` loads configuration and creates the task scheduler
2. **Dependency Resolution**: Resolvers construct services with the `AppFlowyCollabBuilder` and `ServerProvider`
3. **Plugin Registration**: `make_plugins` registers all services with the `AFPluginDispatcher`
4. **UI Integration**: Flutter calls Rust through `dart-ffi`, which routes events to the appropriate plugin
5. **Data Flow**: Services persist changes locally or sync to the cloud via the server layer

## Summary

- **AppFlowy** separates UI and logic using a **Flutter front-end** and **Rust core engine** connected via **FFI**
- The **event dispatcher** and **plugin system** in `flowy-core` decouple UI calls from business logic
- **Domain services** (folder, document, database, AI) live in separate crates with trait-based APIs
- **Collab integration** provides real-time CRDT-based synchronization across all data types
- The **server layer** abstracts cloud sync while **local storage** handles offline persistence
- A **background task scheduler** manages indexing and uploads without blocking user interactions

## Frequently Asked Questions

### How does AppFlowy handle communication between Flutter and Rust?

AppFlowy uses an FFI bridge located in `frontend/rust-lib/dart-ffi/` to marshal data between Dart and Rust. The bridge converts Flutter method calls into events that the Rust `AFPluginDispatcher` routes to the appropriate domain service, returning results back to the UI asynchronously.

### What is the role of the AppFlowyCollabBuilder?

The `AppFlowyCollabBuilder` constructs `Collab` instances that power real-time collaborative editing across all domain services. Located in the core integration layer, it ensures that folder structures, documents, and database records use consistent CRDT-based conflict resolution when merging local and remote changes.

### How are new features added to the AppFlowy architecture?

Developers create a new crate in `frontend/rust-lib/` following the existing service pattern: define traits in a `*-pub` crate, implement the service with a manager struct, create a dependency resolver, and register a plugin in [`flowy-core/src/module.rs`](https://github.com/AppFlowy-IO/AppFlowy/blob/main/flowy-core/src/module.rs). The service then becomes available to the Flutter UI through the existing FFI bridge without modifying core infrastructure code.

### Does AppFlowy support multiple front-ends beyond Flutter?

Yes. The architecture intentionally isolates all business logic in Rust with a clean trait-based API. While the current implementation uses Flutter for the UI, the core engine could theoretically support alternative front-ends (Tauri, web, or native mobile) by implementing a new FFI layer that calls the same Rust services.