AppFlowy
Audited from github.com/AppFlowy-IO/AppFlowy
AppFlowy is an open-source, local-first workspace for documents, wikis, databases and project boards, built with Flutter on a Rust core and positioned as a privacy-focused Notion alternative with optional cloud sync and local AI.
- Language
- Dart
- Database
- SQLite
- Hosting
- Docker
- License
- AGPL-3.0
- Running for
- 3 years
- Team
- 6-20 People
Why this architecture
Flutter delivers five platforms from one codebase while a Rust core owns storage, CRDT documents, search and AI behind a protobuf FFI boundary, keeping data local by default and sync optional.
Tech stack by layer
9 technologies · audited Sep 17, 2026- FlutterOne Dart codebase in `frontend/appflowy_flutter` for macOS, Windows, Linux, iOS and Android (Flutter >= 3.27).
- DartApp logic with `flutter_bloc`/`bloc` for state, `get_it` for DI, `go_router` for navigation and `freezed` models.
- AppFlowy EditorThe block-based rich text editor is the separately published `appflowy_editor` package plus `appflowy_editor_plugins`.
- easy_localizationUI translations, with the catalogue managed through inlang (`project.inlang`) and the `ninja_i18n.yml` workflow.
- RustLocal backend in `frontend/rust-lib`: a Cargo workspace of `flowy-*` crates (user, folder, document, database2, search, ai, storage, server).
- TokioAsync runtime for the Rust backend; `lib-dispatch` routes events from Dart to crate handlers.
- Protocol BuffersDart and Rust exchange protobuf messages over FFI; `build-tool/flowy-codegen` generates the bindings on both sides.
- Dart FFIThe `dart-ffi` crate compiles to a static library and uses `allo-isolate` to deliver responses back to Dart isolates.
- WebAssembly`flowy-document` declares a `wasm32` target, so the document crate can compile for the web alongside native targets.
- AppFlowy CloudOptional sync and collaboration backend in a separate repository, consumed through the `client-api` crate (`flowy-server`).(inferred)
- SQLiteLocal persistence through `flowy-sqlite` using Diesel with r2d2 pooling; `flowy-sqlite-vec` adds vector storage on desktop.
- CRDT (collab)Documents, folders and databases are collaborative types from the `collab-*` crates integrated by `collab-integrate`.
- TantivyFull-text search index referenced by `flowy-search` and `flowy-error` (optional feature).
- OllamaLocal AI: `flowy-ai` uses `ollama-rs`, `langchain-rust` and `text-splitter` for on-device chat and retrieval.
- cargo-makeTask runner for the multi-language build (`frontend/Makefile.toml`) with a pinned `rust-toolchain.toml`.
- GitHub ActionsSeparate Flutter, Rust (with coverage), iOS, mobile, Docker and release workflows plus commit linting.
AppFlowy architecture diagram
Open SVGDiagram as text
- AppFlowy app (Flutter · Dart) → dart-ffi (protobuf over FFI): events
- AppFlowy Editor (block editor package) → dart-ffi (protobuf over FFI): document ops
- dart-ffi (protobuf over FFI) → Rust core (flowy-* crates · Tokio): dispatch
- Rust core (flowy-* crates · Tokio) → SQLite (Diesel · sqlite-vec): persist
- Rust core (flowy-* crates · Tokio) → Collab CRDTs (collab-* crates): documents
- Rust core (flowy-* crates · Tokio) → Local AI (flowy-ai · Ollama): chat · retrieval
- Rust core (flowy-* crates · Tokio) → Search (flowy-search · Tantivy): index
- Collab CRDTs (collab-* crates) → AppFlowy Cloud (optional sync): sync
Key architectural decisions
6 decisions- 01
Flutter UI on top of a Rust core, joined by FFI and protobuf
The Dart app never talks to storage or the network directly. It sends protobuf events through the
dart-ffistatic library tolib-dispatch, which routes them to theflowy-*crates.flowy-codegengenerates matching Dart and Rust types from.protodefinitions at build time. - 02
Local-first storage in SQLite with CRDT documents
flowy-sqlite(Diesel + r2d2) persists everything on the device, and content is modelled with thecollab-*CRDT crates so the same data can later sync through AppFlowy Cloud without a rewrite. Offline use is the default, not a fallback. - 03
The editor is its own open-source package
The block editor is published separately as
appflowy_editor(withappflowy_editor_pluginsandappflowy_board), which lets other Flutter apps reuse it and keeps the app repository focused on workspace features. - 04
Domain crates with public/private splits
Each domain has a
flowy-<x>crate with the implementation and aflowy-<x>-pubcrate with the interfaces (flowy-user-pub,flowy-folder-pub,flowy-document-pub,flowy-database-pub,flowy-ai-pub,flowy-storage-pub), so crates depend on interfaces rather than each other. - 05
AI runs locally by default
flowy-aiembedsollama-rs,langchain-rust,text-splitterandflowy-sqlite-vec, so chat over documents and retrieval can run on the desktop against a local Ollama model; thelocal_aiandfile_readercargo features gate the heavier pieces. - 06
A single repo builds five platforms
CMake and C++ for Linux and Windows runners, Swift/Objective-C for macOS and iOS, Kotlin/Java for Android are all present because Flutter needs native shells;
codemagic.yaml,ios_ci.yaml,mobile_ci.ymlandrelease.ymlbuild and ship each target.
How AppFlowy is built
How AppFlowy is structured
Everything lives under frontend/: appflowy_flutter (the Dart app, version 0.11.4, Flutter >= 3.27), rust-lib (the Cargo workspace), resources, scripts, a Makefile.toml for cargo-make and a pinned rust-toolchain.toml. Repository-level files cover contribution docs, codemagic.yaml for mobile CI, install.sh, commit linting and an inlang project for translations.
The Rust workspace declares more than thirty crates. The important groups are:
- Plumbing:
lib-dispatch(event routing),lib-infra,lib-log,dart-ffi(the FFI boundary) andbuild-tool/flowy-codegen,flowy-ast,flowy-derive(protobuf and Dart code generation). - Domains:
flowy-user,flowy-folder,flowy-document,flowy-database2,flowy-search,flowy-ai,flowy-storage,flowy-date,flowy-notification, each paired with a-pubinterface crate. - Persistence and sync:
flowy-sqlite,flowy-sqlite-vec,collab-integrate,flowy-serverandflowy-server-pub. flowy-corewires all of the above together and is whatdart-ffiexposes to the app.
Frontend
The Flutter app uses flutter_bloc for state, get_it for service location, go_router for navigation, freezed for immutable models and easy_localization for i18n. Editing is handled by the appflowy_editor package with plugins, appflowy_board for kanban and a forked calendar_view for calendars. Desktop specifics come from bitsdojo_window (Windows chrome), desktop_drop and auto_updater; flutter_chat_ui renders the AI chat. Math and code rendering use flutter_math_fork, flutter_tex and highlight.
Backend & APIs
The "backend" is in-process Rust. Dart serialises a protobuf event, calls into the dart_ffi static library, and lib-dispatch routes it to a handler in the relevant flowy-* crate on a Tokio runtime; responses come back through allo-isolate. flowy-server abstracts the remote side, with client-api implementing the AppFlowy Cloud protocol and an http_sync feature flag. Local AI lives in flowy-ai, which depends on ollama-rs, langchain-rust, text-splitter and reqwest.
Data & persistence
flowy-sqlite uses Diesel (features sqlite, chrono, r2d2, serde_json) for local storage. Content types are CRDTs from the collab, collab-document, collab-folder, collab-database and collab-plugins crates, integrated by collab-integrate, so the same document model works offline and when synced. flowy-sqlite-vec stores embeddings for local retrieval on desktop targets, and Tantivy provides full-text indexing behind a feature flag.
Build, test & deploy
- Rust CI (
rust_ci.yaml,rust_coverage.yml) and Flutter CI (flutter_ci.yaml) run separately;event-integration-testexercises the dispatch layer end to end. ios_ci.yaml,mobile_ci.ymlandcodemagic.yamlcover mobile;docker_ci.ymlbuilds a container;release.ymlpublishes desktop and mobile artifacts.commit_lint.ymlwithcommitlint.config.jsand.githooksenforce conventional commits;ninja_i18n.ymlandtranslation_notify.ymlmanage translations.
Self-hosting notes
AppFlowy is a client application, so there is nothing to host for single-user use: download a release or build with cargo make and flutter build. Teams that want sync run AppFlowy Cloud, the separate server project, and point the client at it. The install.sh script and doc/ folder describe local setup.
What to copy (and what not to)
Copy the event-dispatch-over-FFI pattern if you pair Flutter with Rust: protobuf messages plus generated bindings give a typed boundary without hand-written platform channels. Copy the -pub interface crate convention to keep a large Cargo workspace from tangling. Do not copy the full CRDT-plus-SQLite-plus-vector stack for a simple notes app; it exists here because AppFlowy must sync rich block documents across devices and run AI locally.
Sources & repo audit
- frontend/appflowy_flutter/pubspec.yaml (flutter_bloc, get_it, go_router, appflowy_editor)
- frontend/rust-lib/Cargo.toml (workspace members, diesel sqlite)
- frontend/rust-lib/dart-ffi/Cargo.toml (staticlib, allo-isolate, protobuf)
- frontend/rust-lib/flowy-ai/Cargo.toml (ollama-rs, langchain-rust)
- frontend/rust-lib/collab-integrate/Cargo.toml (collab CRDT crates)
Independent analysis of repository at github.com/AppFlowy-IO/AppFlowy. Spotted an inaccuracy? Use the claim form to request a correction.
Show this stack on your README or website
[](https://stackitfast.com/project/appflowy)Paste it into your README. It shows your current stack and links to this page.
Scaffold it with your agent
Paste this prompt into Claude Code, Cursor, Windsurf or AGY to start a project with AppFlowy's architecture.
- 1Copy the promptThe full markdown spec, with every layer and decision.
- 2Open your AI toolClaude Code, Cursor, Windsurf or Copilot, in a new repo.
- 3Paste and scaffoldUse it as the first instruction; review before you ship.
# MISSION: Scaffold "AppFlowy" Production Architecture
You are an expert Senior Staff Software Architect and Full-Stack Engineer. Your mission is to scaffold and implement a production-grade, highly reliable, and modular codebase following the proven architecture of **AppFlowy**.
---
## 1. PROJECT SPECIFICATIONS & BENCHMARK
- **Reference Architecture**: AppFlowy
- **What It Does**: AppFlowy is an open-source, local-first workspace for documents, wikis, databases and project boards, built with Flutter on a Rust core and positioned as a privacy-focused Notion alternative with optional cloud sync and local AI.
- **Domain & Category**: Local-First Privacy Workspace
- **Production Scale**: 6-20 People
- **Development Mode**: HYBRID
- **Architectural Rationale**: Flutter delivers five platforms from one codebase while a Rust core owns storage, CRDT documents, search and AI behind a protobuf FFI boundary, keeping data local by default and sync optional.
- **Live Website Reference**: https://appflowy.io
- **Source Repository**: https://github.com/AppFlowy-IO/AppFlowy
---
## 2. PRODUCTION TECH STACK
- **Full Stack Array**: Flutter, Dart, Rust, SQLite, Protocol Buffers, Tokio, Ollama, WebAssembly, Docker
- **Primary Language(s)**: Dart, Rust
- **License of the reference repo**: AGPL-3.0
- **Frontend**: Flutter — One Dart codebase in `frontend/appflowy_flutter` for macOS, Windows, Linux, iOS and Android (Flutter >= 3.27).; Dart — App logic with `flutter_bloc`/`bloc` for state, `get_it` for DI, `go_router` for navigation and `freezed` models.; AppFlowy Editor — The block-based rich text editor is the separately published `appflowy_editor` package plus `appflowy_editor_plugins`.; easy_localization — UI translations, with the catalogue managed through inlang (`project.inlang`) and the `ninja_i18n.yml` workflow.
- **Backend & APIs**: Rust — Local backend in `frontend/rust-lib`: a Cargo workspace of `flowy-*` crates (user, folder, document, database2, search, ai, storage, server).; Tokio — Async runtime for the Rust backend; `lib-dispatch` routes events from Dart to crate handlers.; Protocol Buffers — Dart and Rust exchange protobuf messages over FFI; `build-tool/flowy-codegen` generates the bindings on both sides.; Dart FFI — The `dart-ffi` crate compiles to a static library and uses `allo-isolate` to deliver responses back to Dart isolates.; WebAssembly — `flowy-document` declares a `wasm32` target, so the document crate can compile for the web alongside native targets.; AppFlowy Cloud — Optional sync and collaboration backend in a separate repository, consumed through the `client-api` crate (`flowy-server`).
- **Data & persistence**: SQLite — Local persistence through `flowy-sqlite` using Diesel with r2d2 pooling; `flowy-sqlite-vec` adds vector storage on desktop.; CRDT (collab) — Documents, folders and databases are collaborative types from the `collab-*` crates integrated by `collab-integrate`.; Tantivy — Full-text search index referenced by `flowy-search` and `flowy-error` (optional feature).
- **Infrastructure & deploy**: Docker — A Docker build of the desktop client is exercised by `docker_ci.yml`.; Codemagic — Mobile build pipeline configured in `codemagic.yaml` alongside `ios_ci.yaml` and `mobile_ci.yml`.
- **Tooling, testing & ops**: Ollama — Local AI: `flowy-ai` uses `ollama-rs`, `langchain-rust` and `text-splitter` for on-device chat and retrieval.; cargo-make — Task runner for the multi-language build (`frontend/Makefile.toml`) with a pinned `rust-toolchain.toml`.; GitHub Actions — Separate Flutter, Rust (with coverage), iOS, mobile, Docker and release workflows plus commit linting.
---
## 3. KEY ARCHITECTURAL DECISIONS (audited from https://github.com/AppFlowy-IO/AppFlowy @ 5cf3a36)
1. **Flutter UI on top of a Rust core, joined by FFI and protobuf**: The Dart app never talks to storage or the network directly. It sends protobuf events through the `dart-ffi` static library to `lib-dispatch`, which routes them to the `flowy-*` crates. `flowy-codegen` generates matching Dart and Rust types from `.proto` definitions at build time.
2. **Local-first storage in SQLite with CRDT documents**: `flowy-sqlite` (Diesel + r2d2) persists everything on the device, and content is modelled with the `collab-*` CRDT crates so the same data can later sync through AppFlowy Cloud without a rewrite. Offline use is the default, not a fallback.
3. **The editor is its own open-source package**: The block editor is published separately as `appflowy_editor` (with `appflowy_editor_plugins` and `appflowy_board`), which lets other Flutter apps reuse it and keeps the app repository focused on workspace features.
4. **Domain crates with public/private splits**: Each domain has a `flowy-<x>` crate with the implementation and a `flowy-<x>-pub` crate with the interfaces (`flowy-user-pub`, `flowy-folder-pub`, `flowy-document-pub`, `flowy-database-pub`, `flowy-ai-pub`, `flowy-storage-pub`), so crates depend on interfaces rather than each other.
5. **AI runs locally by default**: `flowy-ai` embeds `ollama-rs`, `langchain-rust`, `text-splitter` and `flowy-sqlite-vec`, so chat over documents and retrieval can run on the desktop against a local Ollama model; the `local_ai` and `file_reader` cargo features gate the heavier pieces.
6. **A single repo builds five platforms**: CMake and C++ for Linux and Windows runners, Swift/Objective-C for macOS and iOS, Kotlin/Java for Android are all present because Flutter needs native shells; `codemagic.yaml`, `ios_ci.yaml`, `mobile_ci.yml` and `release.yml` build and ship each target.
---
## 4. NON-NEGOTIABLE ARCHITECTURAL GUARDRAILS
1. **Monorepo & Modular Separation**:
- Structure as a Turborepo monorepo with strict package boundaries:
- `apps/web`: Application UI, routing, layouts, and server endpoints.
- `packages/ui`: Shared design tokens, CSS variables, and Radix UI primitive components.
- `packages/db`: Database schemas, client singleton, declarative migrations, and seed scripts.
- `packages/config`: Shared TypeScript, ESLint, and build configurations.
2. **Strict Type Safety & Zero `any` Policy**:
- Enable `strict: true`, `noImplicitAny: true`, and `strictNullChecks: true`.
- Validate ALL external inputs, API request bodies, and query parameters with **Zod** schemas before execution.
3. **Frontend & Rendering Guidelines**:
- Isolate interactive UI state to leaf components. Keep core pages lightweight and performant.
4. **Design System & Aesthetics**:
- Keep every color, radius, shadow and font in a single token file (CSS variables) and consume tokens everywhere; never hardcode hex values in components.
- Prefer crisp 1px borders and one subtle shadow scale over blurry default shadows. Pair one sans-serif for body/headings with one monospace for tags, badges, metrics, and code.
5. **Data Layer & Reliability**:
- Write declarative schema definitions with foreign keys, composite indexes on queried filters, and automated timestamp triggers.
- Use connection pooling and prepared statements for serverless database execution.
---
## 5. STEP-BY-STEP SCAFFOLDING ROADMAP
- **Phase 1: Workspace & Root Config**: Initialize package manager, monorepo configuration (`turbo.json`, `tsconfig.base.json`, `package.json`).
- **Phase 2: Database Schema & Client**: Set up the data layer (SQLite, CRDT (collab), Tantivy): client, connection pool, models, and migration scripts.
- **Phase 3: Design Tokens & UI Primitives**: Build accessible `Button`, `Input`, `Card`, `Badge`, and layout wrappers inside `packages/ui`.
- **Phase 4: Core Application Routes & Handlers**: Implement primary authentication, user session handling, and application routes.
- **Phase 5: Quality Assurance & Build Verification**: Run `tsc --noEmit`, ESLint, Prettier, and smoke test suites to ensure zero compilation or runtime errors.
---
## 6. EXECUTION INSTRUCTIONS
1. Review all specifications, architectural guardrails, and stack choices above.
2. Present the full monorepo directory tree structure.
3. Systematically generate the complete, production-ready codebase according to the 5-phase roadmap above — starting with the root workspace setup, followed by the database schema, UI design system package, and full-stack application routes until the repository is fully scaffolded and ready to run.Frequently asked about AppFlowy
What is AppFlowy built with?
AppFlowy is a Flutter (Dart) application with a Rust core. The UI uses flutter_bloc, get_it and go_router plus the appflowy_editor package; the Rust workspace under frontend/rust-lib handles storage (SQLite via Diesel), CRDT documents, search and local AI, and the two sides communicate over FFI with protobuf messages.
Does AppFlowy need a server?
No. AppFlowy is local-first: all data is stored in SQLite on the device and the app works offline. Sync, sharing and collaboration are optional and provided by the separate AppFlowy Cloud project, which this repository talks to through the client-api crate.
Which platforms does AppFlowy support?
macOS, Windows, Linux, iOS and Android from one Flutter codebase. The repository contains the native shells and CI workflows for each target, including a Codemagic pipeline for mobile builds.
How does AppFlowy handle AI?
The flowy-ai crate integrates ollama-rs, langchain-rust and a SQLite vector store, so chat and retrieval over your documents can run locally with an Ollama model. Cloud AI features go through AppFlowy Cloud.
Can I use the AppFlowy editor in my own app?
Yes. The block editor is published separately as the appflowy_editor Flutter package (with appflowy_editor_plugins), and AppFlowy itself consumes it as a dependency.
One email a month: new deep dives and stack trends
New source-audited architectures, head-to-head comparisons and the monthly stack report. No spam, unsubscribe anytime.
Similar architectures
- RustDeskClassicRemote Desktop Infrastructure · 6-20 peopleShares Rust · Flutter · Dart
- DenoClassicSecure JavaScript & TypeScript Runtime · 20+ peopleShares Rust · Tokio · SQLite
- VaultwardenClassicLightweight Self-Hosted Password Vault · Solo / 2-5 peopleShares Rust · SQLite · Docker
- LemmyClassicFederated Link Aggregator & Forum · 20+ peopleShares Rust · Tokio · Docker
- SurrealDBClassicMulti-Model Real-Time Database · 20+ PeopleShares Rust · WebAssembly · Tokio
- VectorClassicObservability Data Router & Telemetry Pipeline · 21-100 peopleShares Rust · Tokio · Docker