# What Is BlockSuite and How Does AFFiNE Use It? A Technical Deep Dive

> Discover BlockSuite, the collaborative editing engine powering AFFiNE. Explore its modular architecture and how AFFiNE leverages @blocksuite/affine for a seamless editing experience.

- Repository: [Toeverything/AFFiNE](https://github.com/toeverything/AFFiNE)
- Tags: deep-dive
- Published: 2026-03-05

---

**BlockSuite is a modular, framework-agnostic library that provides collaborative editing building blocks, which AFFiNE utilizes as its core editor engine through the `@blocksuite/affine` package integration.**

BlockSuite powers the real-time collaborative editing experience in AFFiNE, the open-source knowledge base and note-taking platform developed by toeverything. This article examines how the AFFiNE repository leverages BlockSuite's architecture to deliver block-based document editing, synchronization, and extensible UI components.

## What Is BlockSuite?

BlockSuite is a framework-agnostic library designed for building collaborative, real-time editing applications. It provides a comprehensive set of building blocks—including text editors, lists, embeds, databases, and graphics—along with a powerful extensibility model that enables developers to construct complex document editing experiences.

### Core Architecture and Packages

The library is organized into several core packages that work together to provide a complete editing solution:

- **`@blocksuite/store`**: Manages the document model, block tree structure, and state management using Yjs for real-time collaboration
- **`@blocksuite/std`**: Provides standard UI utilities, command handling, and the `BlockStdScope` for editor lifecycle management
- **`@blocksuite/affine`**: A specialized namespace containing AFFiNE-specific block types, UI widgets, and extensions

## How AFFiNE Integrates BlockSuite

AFFiNE integrates BlockSuite as its underlying editor engine through the `@blocksuite/affine` package. This integration spans data modeling, state management, UI rendering, and real-time synchronization across the application.

### The @blocksuite/affine Package Structure

The `@blocksuite/affine` namespace bundles all AFFiNE-specific implementations:

| AFFiNE Area | Blocksuite Component | Purpose |
|-------------|---------------------|---------|
| **Document model** | `@blocksuite/affine/model` | Defines data schema for paragraphs, headings, tables, and embeds |
| **State management** | `@blocksuite/affine/store` | Manages block trees, collaboration via Yjs, and reactive updates |
| **Standard UI utilities** | `@blocksuite/affine/std` | Provides UI scaffolding, command handling, and widget lifecycle |
| **Widgets & toolbars** | `@blocksuite/affine/widgets/*` | Implements floating toolbars, slash-menus, and page-linking widgets |
| **Extensions** | `@blocksuite/affine/ext-loader` | Allows custom block types without modifying core code |
| **Themes & icons** | `@blocksuite/affine/shared/theme` | Supplies styling tokens and SVG icons |

### Workspace and Store Management

At the foundation of AFFiNE's integration is the Blocksuite `Store` instance, which manages the block graph and document collection. In [`blocksuite/affine/store/src/index.ts`](https://github.com/toeverything/AFFiNE/blob/main/blocksuite/affine/store/src/index.ts), the store implementation handles Yjs-backed document collections that enable real-time collaboration.

AFFiNE creates a `DocCollection` instance that serves as the workspace container, then initializes individual document stores within this collection. This architecture allows AFFiNE to support multiple documents while maintaining synchronized state across clients.

### Editor Host and Block Rendering

The rendering layer relies on `BlockStdScope` from `@blocksuite/affine/std`, which wraps a Lit-based `EditorHost` component. This scope manages the lifecycle of block widgets and coordinates command execution across the editor surface.

Individual block types—such as paragraphs, images, and databases—are implemented as widgets under `blocksuite/affine/widgets/*`. For example, the toolbar widget in [`blocksuite/affine/widgets/toolbar/src/toolbar.ts`](https://github.com/toeverything/AFFiNE/blob/main/blocksuite/affine/widgets/toolbar/src/toolbar.ts) implements the floating formatting toolbar that appears when users select text.

## Key Implementation Details

### Extension Loader System

AFFiNE extends Blocksuite's capabilities through the extension loader system defined in [`blocksuite/affine/ext-loader/src/manager.ts`](https://github.com/toeverything/AFFiNE/blob/main/blocksuite/affine/ext-loader/src/manager.ts). This system supports dynamic registration of custom block types, view extensions, and commands at runtime, allowing applications like AFFiNE to add specialized functionality without modifying the core Blocksuite library.

### Real-Time Collaboration Layer

Blocksuite's synchronization layer, integrated through `@blocksuite/affine/store`, leverages Yjs for conflict-free replicated data types (CRDTs). This enables AFFiNE's real-time collaboration features, allowing multiple users to edit documents simultaneously with automatic conflict resolution.

The sync layer handles binary updates efficiently, transmitting only document deltas rather than full state, which optimizes network usage for AFFiNE's cloud and self-hosted deployments.

## Code Examples

The following examples demonstrate how AFFiNE interacts with Blocksuite APIs in practice.

### Creating a Blocksuite Store

AFFiNE initializes document storage using the Blocksuite store API:

```typescript
import { createStore } from '@blocksuite/affine/store';
import { DocCollection } from '@blocksuite/affine/store';

// Initialise a Yjs‑backed collection
const collection = new DocCollection();
const store = createStore(collection);

// Use the store in AFFiNE’s workspace provider
<WorkspaceProvider store={store}>
  {/* AFFiNE UI components */}
</WorkspaceProvider>

```

*Source*: [[`blocksuite/affine/store/src/index.ts`](https://github.com/toeverything/AFFiNE/blob/main/blocksuite/affine/store/src/index.ts)](https://github.com/toeverything/AFFiNE/blob/canary/blocksuite/affine/store/src/index.ts)

### Rendering Rich Text Blocks

The editor host renders rich text components using Blocksuite's standard scope:

```typescript
import { BlockStdScope } from '@blocksuite/affine/std';
import { RichText } from '@blocksuite/affine/rich-text';
import { css } from 'lit';

const editor = new BlockStdScope();

editor.mount(
  <RichText
    class={css`padding: 8px;`}
    placeholder="Start typing…"
  />,
);

```

*Source*: [[`blocksuite/affine/rich-text/src/rich-text.ts`](https://github.com/toeverything/AFFiNE/blob/main/blocksuite/affine/rich-text/src/rich-text.ts)](https://github.com/toeverything/AFFiNE/blob/canary/blocksuite/affine/rich-text/src/rich-text.ts)

### Implementing a Custom Toolbar

AFFiNE adds interactive toolbars using Blocksuite widget APIs:

```typescript
import { Toolbar } from '@blocksuite/affine/widgets/toolbar';
import { cssVarV2 } from '@blocksuite/affine/shared/theme';

const myToolbar = new Toolbar();
myToolbar.addButton({
  icon: 'bold',
  onClick: () => editor.command.exec('formatBold'),
  style: `color: ${cssVarV2('icon/primary')}`,
});

// Mount into AFFiNE’s editor container
editor.mount(myToolbar);

```

*Source*: [[`blocksuite/affine/widgets/toolbar/src/toolbar.ts`](https://github.com/toeverything/AFFiNE/blob/main/blocksuite/affine/widgets/toolbar/src/toolbar.ts)](https://github.com/toeverything/AFFiNE/blob/canary/blocksuite/affine/widgets/toolbar/src/toolbar.ts)

### Loading Extensions Dynamically

The extension loader enables runtime customization:

```typescript
import { loadExtension } from '@blocksuite/affine/ext-loader';
import { MyCustomBlock } from './my-custom-block';

loadExtension({
  name: '@my-org/custom-block',
  components: [MyCustomBlock],
  // Optional: define block schema, commands, etc.
});

```

*Source*: [[`blocksuite/affine/ext-loader/src/manager.ts`](https://github.com/toeverything/AFFiNE/blob/main/blocksuite/affine/ext-loader/src/manager.ts)](https://github.com/toeverything/AFFiNE/blob/canary/blocksuite/affine/ext-loader/src/manager.ts)

## Summary

- BlockSuite is a modular, framework-agnostic library providing collaborative editing building blocks including text, lists, embeds, and databases.
- AFFiNE uses BlockSuite as its core editor engine through the `@blocksuite/affine` package, which bundles AFFiNE-specific block types and widgets.
- The integration relies on `DocCollection` and `Store` for data management, `BlockStdScope` for UI lifecycle, and widget systems for toolbars and menus.
- Real-time collaboration is enabled through Yjs integration in `@blocksuite/affine/store`, providing CRDT-based synchronization.
- The extension loader system allows AFFiNE to register custom blocks and views at runtime without modifying core BlockSuite code.

## Frequently Asked Questions

### What is BlockSuite used for?

BlockSuite is a framework-agnostic library designed for building collaborative, real-time editing applications. It provides modular building blocks—including text editors, lists, embeds, databases, and graphics—along with state management and synchronization capabilities powered by Yjs.

### How does AFFiNE integrate with BlockSuite?

AFFiNE integrates BlockSuite as its underlying editor engine through the `@blocksuite/affine` package. This integration includes using `DocCollection` for workspace management, `BlockStdScope` for editor lifecycle, and various widget packages for UI components like toolbars and slash menus. The source code in [`blocksuite/affine/store/src/index.ts`](https://github.com/toeverything/AFFiNE/blob/main/blocksuite/affine/store/src/index.ts) and [`blocksuite/affine/std/src/index.ts`](https://github.com/toeverything/AFFiNE/blob/main/blocksuite/affine/std/src/index.ts) demonstrates these core integrations.

### Can developers extend BlockSuite with custom blocks?

Yes, developers can extend BlockSuite using the extension loader system defined in [`blocksuite/affine/ext-loader/src/manager.ts`](https://github.com/toeverything/AFFiNE/blob/main/blocksuite/affine/ext-loader/src/manager.ts). This system supports dynamic registration of custom block types, view extensions, and commands at runtime, allowing applications like AFFiNE to add specialized functionality without modifying the core BlockSuite library.

### Does BlockSuite support real-time collaboration?

Yes, BlockSuite supports real-time collaboration through its integration with Yjs (CRDTs) in the `@blocksuite/affine/store` package. This enables multiple users to edit documents simultaneously with automatic conflict resolution, transmitting only binary document deltas rather than full state to optimize network usage.