Benefits of AFFiNE's All-in-One Workspace Approach: A Technical Deep Dive
AFFiNE's all-in-one workspace approach unifies note-taking, whiteboarding, and databases into a single CRDT-backed architecture, eliminating context switching and ensuring offline-first collaboration through a unified block-based data model.
The open-source AFFiNE repository (toeverything/AFFiNE) reimagines knowledge management by treating documents, canvases, and tables as interchangeable blocks within one coherent platform. This technical analysis explores how AFFiNE's all-in-one workspace approach delivers architectural advantages through its unified data model, local-first synchronization, and extensible monorepo structure.
Unified Data Model: The Block-Based Core
At the heart of AFFiNE's all-in-one workspace approach lies a block-based architecture where every content type—whether a text document, edgeless whiteboard, or database table—implements a common interface. This design eliminates the traditional boundaries between apps.
In packages/frontend/core/src/modules/at-menu-config/services/index.ts, the AtMenuConfigService demonstrates this unification by handling both page and edgeless creation through identical pipelines:
const createPage = (mode: DocMode) => {
const page = this.docsService.createDoc({
title: query,
primaryMode: mode, // 'page' | 'edgeless'
});
return page;
};
// Usage for regular page
this.insertDoc(inlineEditor, createPage('page').id);
// Usage for edgeless canvas
this.insertDoc(inlineEditor, createPage('edgeless').id);
This unified creation UI means users never navigate to separate "new whiteboard" or "new document" dialogs—the same @ menu adapts to the desired mode, reducing cognitive load and maintaining workflow continuity.
Local-First Collaboration with Y-Oct CRDT
AFFiNE's all-in-one workspace approach enables local-first architecture through the Y-Oct CRDT engine—a high-performance, thread-safe YJS-compatible library implemented in packages/common/y-octo/core/README.md. This technology ensures that all workspace data remains available offline while supporting real-time collaboration.
The CRDT engine maintains a single source of truth locally, synchronizing updates instantly across peers when connectivity returns. Because the entire workspace uses the same CRDT-backed document structure, merging changes happens deterministically without format conversion conflicts—whether you're editing a database table or a whiteboard sticky note.
Consistent Persistence Layer
All documents in AFFiNE's all-in-one workspace, regardless of type, persist as y-octo binaries through the backend DocWriter service. Located in packages/backend/server/src/core/doc/writer.ts, this service handles creation, updates, and metadata changes through uniform binary-update flows.
Creating a document from markdown follows the same pipeline as updating a whiteboard canvas:
async function createSampleDoc(
writer: DocWriter,
workspaceId: string,
title: string,
markdown: string,
editorId?: string,
) {
const { docId } = await writer.createDoc(
workspaceId,
title,
markdown,
editorId,
);
console.log(`Created doc ${docId}`);
}
Metadata updates also traverse this unified path:
await writer.updateDocMeta(
workspaceId,
docId,
{ title: 'New Title' },
editorId,
);
This consistency guarantees that every piece of content benefits from the same CRDT guarantees, versioning, and storage format—eliminating the data silos typical of separate note-taking and whiteboarding applications.
Extensible Workspace Architecture
AFFiNE's all-in-one workspace approach relies on a modular monorepo structure organized as Yarn workspaces. The repository dependency graph, defined in tools/utils/src/workspace.gen.ts, declares clear workspaceDependencies (such as blocksuite/affine/all and packages/frontend/core), ensuring a single version graph and consistent builds.
This architecture allows teams to introduce custom editor plugins or third-party blocks while preserving the unified workspace experience. Because all components depend on the same block-based core and CRDT engine, extensions automatically inherit offline capabilities and real-time synchronization.
Centralized Security and Ownership
Because AFFiNE treats the entire workspace as a single logical entity, permissions, sharing, and audit controls apply uniformly rather than per-application. The backend emits a single doc.updates.pushed event for any change, simplifying server-side processing and policy enforcement in packages/backend/server/src/core/doc/writer.ts.
Users retain full ownership of their data through the local-first architecture, while administrators benefit from centralized access control across all content types—whether managing a text document, database view, or collaborative whiteboard.
Summary
- AFFiNE's all-in-one workspace approach eliminates context switching by unifying documents, whiteboards, and databases into a single block-based architecture.
- The Y-Oct CRDT engine enables local-first collaboration with deterministic offline merging across all content types.
- Unified persistence through
DocWriterensures consistent storage, versioning, and metadata handling regardless of document mode. - The Yarn workspace architecture supports extensibility while maintaining tight integration between frontend, backend, and native components.
- Centralized security model applies permissions and audit controls uniformly across the entire knowledge base.
Frequently Asked Questions
How does AFFiNE handle different content types in its all-in-one workspace?
AFFiNE stores all content—text documents, edgeless whiteboards, tables, and databases—as blocks within the same CRDT-backed document structure. In packages/frontend/core/src/modules/at-menu-config/services/index.ts, the createDoc function accepts a primaryMode parameter ('page' or 'edgeless'), allowing users to instantiate any content type through the same creation pipeline. This block-based approach lets you embed spreadsheets inside documents or overlay sticky notes on diagrams without format conversion.
What makes AFFiNE's collaboration model "local-first"?
The platform uses the Y-Oct CRDT engine (packages/common/y-octo/core/README.md), a high-performance YJS-compatible library that maintains a single source of truth on the local device. All changes are recorded locally as binary updates, ensuring full functionality offline. When connectivity returns, the CRDT algorithm deterministically merges changes across peers without conflicts. This architecture applies uniformly to all workspace content, whether editing a database row or a whiteboard shape, as implemented in the DocWriter service (packages/backend/server/src/core/doc/writer.ts).
How does the unified persistence layer benefit users?
All documents, regardless of type, persist as y-octo binaries through the same DocWriter backend service. This means creating a document from markdown (createDoc), updating content, or modifying metadata (updateDocMeta) all traverse identical binary-update flows with the same CRDT guarantees. Users benefit from consistent versioning, backup, and storage formats across their entire knowledge base, eliminating the data silos and export/import friction typical of using separate apps for notes, whiteboards, and databases.
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 →