Library / SDK
toeverything/blocksuite avatar
toeverything/blocksuite

BlockSuite: a CRDT editor toolkit where AFFiNE gets no privileged access

🧩 Content editing tech stack for the web - BlockSuite is a toolkit for building editors and collaborative applications.

6,086 stars568 forksTypeScriptMPL-2.0

At a glance

What is it?
BlockSuite is the TypeScript editor stack extracted from AFFiNE, built on Yjs at the data layer and shipped as web components. Its interesting constraint is architectural: the consumer application and the vendor application consume the same components with equal rights, and the root package caps Node below version 23.
Who is it for?
Use BlockSuite if you want editor infrastructure rather than an editor: a CRDT store, a command layer and web components you can adopt one at a time. Before adopting, check the version you would pin, because v0.22.4 was published on 2025-07-01 while the last push was on 2026-11-02, and read the early stage warning that the component and extension surface is still being refined.
Can I use it commercially?
Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • toeverything/blocksuite6,086 ★ · +64
Star history
Repository2026-09-232026-11-13
toeverything/blocksuite6k6.1k

64 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Collaboration is in the data layer, not bolted on as a plugin

Most editors treat real-time collaboration as an optional plugin you attach later. BlockSuite takes the opposite position: `@blocksuite/store` is the data layer for modelling collaborative document states and it is built natively on the Yjs CRDT library, so every document it manages arrives with collaboration and time travel already present.

The stated reason is data flow. The project links an article on that CRDT-native data flow as the argument.

Below that layer sit two more capabilities that depend on the same choice. Incremental updates mean an edit does not resend the whole document, and decentralised synchronisation is built on a document streaming mechanism. If your backend already speaks Yjs updates, that is the shape to design around.

Commands are the editing hooks, blocks are the document units

The document is a block tree. You define custom blocks and inline embeds, and everything the editor can do to that tree goes through a command mechanism that the project compares to React hooks, but scoped to document editing instead of rendering. The stated benefit is type-safe complex editing logic.

The three feature claims in the README that are worth separating are the ones about scope. State scheduling across multiple documents means one page can drive edits in another. Reusing one document in multiple editors means two mounted editors can show and edit the same tree. And incremental updates sit underneath both, so those cross-document and multi-editor arrangements do not turn into full-document writes.

PageEditor and EdgelessEditor share one rich text engine

Two editors ship in the presets. `PageEditor` is the block-based document editor. `EdgelessEditor` is a graphics editor with opt-in canvas rendering, and it keeps the same rich text capabilities as `PageEditor` rather than reimplementing them.

That sharing is deliberate at the package level too. `@blocksuite/inline` holds minimal rich text components for inline editing, and its documented capability is splitting rich text content sitting in different block nodes into different inline editors, which is what makes complex content composable and, in the project's words, removes much of the complexity of traditional rich text editing.

The third path is to skip both editors. The vanilla framework underneath is usable on its own, so a team that needs a document model nobody else has can build an editor from scratch on the same store and command layer. That is the reason the framework packages are published separately from the preset editors.

AFFiNE consumes BlockSuite as a peer, not as a privileged host

BlockSuite came out of the AFFiNE knowledge base, and the project draws the comparison to Monaco Editor inside VSCode while flagging one difference. BlockSuite is not generated from the AFFiNE codebase. It is maintained independently, on a different stack: AFFiNE uses React, BlockSuite uses web components, and every component including the editors is a native web component.

From that the project derives two boundaries. AFFiNE and every other consumer reuse and extend BlockSuite through components with no privileges, and components stay reusable whether the host application uses React or something else.

That boundary has a cost worth naming. Two editor front ends maintained against the same store means the framework optimises for the intersection, so if your product needs a behaviour AFFiNE never wanted, you will be extending a component designed to stay generic. The upside is that you can adopt one component without adopting the product around it.

The engines field excludes Node 23, and Yarn 4 is pinned for you

The repository root is a private package that exists to host the workspace, not to be installed. It declares the toolchain and the supported runtime:

json
  "engines": {
    "node": ">=18.19.0 <23.0.0"
  },
  "packageManager": "[email protected]",
  "workspaces": [
    "packages/**/*",
    "docs"
  ],

Node 23 and anything above 22 is out of range, which matters if your platform pins a newer runtime. Yarn 4.7.0 is declared as the package manager and `.yarn/` plus `.yarnrc.yml` and `yarn.lock` are checked in, so the version is not a suggestion. Workspaces cover `packages/**/*` and the docs site.

For a first run, `yarn dev` starts the playground workspace and `yarn preview` serves its build. The quick start path in the docs starts from the preset editors in `@blocksuite/presets` rather than from the framework packages.

Commands, changesets and a canary tag decide what reaches npm

Publishing is scripted rather than manual, and the scripts show the whole path:

json
    "build": "tsc -b tsconfig.json --verbose",
    "ci:version": "changeset version && yarn install --no-frozen-lockfile",
    "ci:publish:canary": "yarn build:packages && yarn workspaces foreach -Ap --no-private npm publish --access public --tag canary",

Version numbers come from changesets, so a pull request carries a changeset and `changeset version` rewrites the manifests before anything is published. A parallel canary path exists with `changeset version --snapshot canary` and a `canary` dist tag, which is how a build gets out before it is a release. Every published workspace is filtered with `--no-private`, so the private root never reaches the registry.

The quality gates around that are visible too: `.commitlintrc.json` for conventional commit messages, `.husky/` installed by a `postinstall` script, prettier run through `lint-staged` on staged files, and a `.size-limit.cjs` budget checked with the size-limit preset.

Snapshots and transformers carry documents in and out of other formats

Persistence runs through a block snapshot API, and format compatibility runs through transformers on top of it. Markdown and HTML are the two named formats, which means importing an existing document is a transformer call and not a screen scrape.

If your plan involves a format as a source of truth rather than an import format, test whether the conversion round trips first.

Decentralised synchronisation is described through document streaming.

The project calls itself early stage while the commit log moves daily

The README carries a construction marker stating that BlockSuite is in its early stage, with components and extension capabilities still under refinement, and invites feedback. Take that at face value when planning an adoption: the component surface is the part that changes.

The repository is not archived and the last push was on 2026-11-02, so the work is current. The release tags tell a slower story: v0.19.5 on 2024-12-19, v0.21.0 on 2025-04-07, and v0.22.4 on 2025-07-01, all still below version 1. Licence is MPL-2.0, which covers the files you modify in a covered work and leaves the rest of your application alone.

Playwright and a size-limit budget sit in the development dependencies.

Editorial conclusion

Use BlockSuite if you want editor infrastructure rather than an editor: a CRDT store, a command layer and web components you can adopt one at a time. Before adopting, check the version you would pin, because v0.22.4 was published on 2025-07-01 while the last push was on 2026-11-02, and read the early stage warning that the component and extension surface is still being refined.

Frequently asked questions

What is BlockSuite used for?

It is a toolkit for building editors and collaborative applications. You can reuse the PageEditor and EdgelessEditor presets, extend them with components, or build a new editor on the underlying vanilla framework and store package.

Does BlockSuite support real-time collaboration?

Yes, and it is built into the data layer rather than added as a plugin. The @blocksuite/store package is built on the Yjs CRDT library, which brings real-time collaboration and time travel to every document.

Which Node versions does BlockSuite support?

The root package requires Node 18.19.0 or newer and below 23.0.0, and it pins Yarn 4.7.0 as its package manager. Node 23 and later fall outside that range.

Is BlockSuite coupled to the AFFiNE codebase?

No. BlockSuite originated in AFFiNE but is maintained independently and is not generated from that codebase. AFFiNE uses React while BlockSuite uses web components, and both consume the components with equal rights.

How does BlockSuite import markdown or HTML documents?

Persistence goes through the block snapshot API and format conversion goes through transformers. Markdown and HTML are the two formats the project names.

Official sources

  1. License: MPL-2.0
  2. Project website
  3. README
  4. Releases
  5. toeverything/blocksuite on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/toeverything-blocksuite.svg)](https://hysenlabs.com/projects/toeverything-blocksuite)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/toeverything-blocksuite.svg)](https://hysenlabs.com/projects/toeverything-blocksuite)

Was this useful?