CodeMirror State

Immutable document, selection, and transaction data structures for the CodeMirror code editor

Library
npm
v6.7.6
83 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
31 /100 Needs Attention
Development Activity 4
Maintenance 0
Community 40
Maturity 60
Momentum 20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
75 /100 Good
Architecture 85
Code Quality 78
Innovation 80
Learning Curve 55

@codemirror/state is the core data-modeling package behind the CodeMirror 6 code editor. It defines the EditorState, an immutable persistent object that combines a Text document, an EditorSelection, and any extension-defined fields into a single snapshot, updated only by producing a new Transaction rather than mutating in place.

Beyond the document/selection pair, the package exposes the Facet and StateField mechanisms that let extensions plug typed, computed values into the state, a RangeSet data structure for efficiently mapping tagged ranges (like decorations or diagnostics) through edits, and a rope-like Text implementation for fast indexing and structure-sharing updates on large documents. It has no rendering logic of its own — @codemirror/view and language packages build on top of it — which makes it usable in headless contexts (e.g. server-side linting or diffing) as well as inside the browser editor.

What You Get

  • EditorState: the immutable snapshot combining doc, selection, and extension state, updated only via state.update(...) transactions
  • Text: a rope-style immutable document representation with efficient line/offset indexing and structure-sharing edits
  • EditorSelection / SelectionRange: multi-range cursor and selection modeling with built-in mapping through changes
  • Facet and StateField: the extension points other CodeMirror packages (and third-party plugins) use to add typed, computed configuration and state
  • ChangeSet / ChangeDesc: a compact, invertible representation of document edits used to map positions and ranges across a change
  • RangeSet / RangeSetBuilder: an efficient tagged-range data structure for decorations, gutter markers, and diagnostics that stays correct across edits
  • Compartment: a mechanism for reconfiguring a slice of extensions at runtime without rebuilding the whole state

Common Use Cases

  • Building a CodeMirror 6-based code or text editor and needing the underlying document/selection/transaction model
  • Writing a CodeMirror extension (language mode, linter, autocompletion source) that needs to add its own StateField or Facet
  • Implementing collaborative editing or undo/redo on top of CodeMirror’s transaction and ChangeSet primitives
  • Running headless document diffing, transformation, or position-mapping logic (e.g. applying LSP edits) without loading the DOM-based view layer
  • Tracking decorations, diagnostics, or annotations that must stay correctly positioned as a document is edited, via RangeSet

Under The Hood

Architecture — @codemirror/state has no DOM or rendering code; it is a pure data-modeling layer consumed by @codemirror/view and language packages. The central class, EditorState (src/state.ts), is an immutable object holding a Configuration (the resolved set of extensions), a Text document, an EditorSelection, and a values array indexed by dynamically-assigned slot addresses for extension-defined StateFields. State transitions happen exclusively through Transaction objects (src/transaction.ts): state.update(spec) resolves a TransactionSpec into changes, a new selection, and any StateEffects, then produces both the new EditorState and the Transaction that describes how it was reached, enabling undo history and collaborative-editing extensions to replay or invert steps. Cross-cutting configuration flows through Facet and Compartment (src/facet.ts), a dependency-injection-like system where extensions register facet inputs and other code reads a single combined facet value, with Compartment allowing a subset of extensions to be swapped at runtime via a dedicated reconfigure effect.

Tech Stack — Written entirely in TypeScript (100% of repo bytes per GitHub’s language breakdown) targeting ES modules, with type: module in package.json and dual import/require entry points (dist/index.js / dist/index.cjs) built via the shared @codemirror/buildhelper tool. Its only runtime dependency is @marijn/find-cluster-break, a small grapheme-cluster-boundary helper used by the Text and char modules for UTF-16/codepoint-aware indexing — the package otherwise avoids external dependencies entirely, keeping it embeddable in any JS environment.

Code Quality — The test/ directory holds 7 suites (test-state, test-text, test-facet, test-selection, test-rangeset, test-charcategory, test-change; ~1,468 lines) exercised via the cm-runtests script, covering the core EditorState, Text, Facet, ChangeSet, and RangeSet behaviors against ~3,880 lines of source. Source files favor small, single-responsibility modules (change.ts, facet.ts, rangeset.ts, text.ts, transaction.ts, selection.ts) with consistent TSDoc /// comments preceding nearly every exported type and method, which are extracted directly into the published API reference. Internal-only members are explicitly marked @internal, and the EditorState class enforces immutability by convention (constructor is private; state is only produced via create/update), with the code and its comments explicitly warning against direct mutation.

API Design — The public surface is small and orthogonal: one way to build a state (EditorState.create), one way to change it (state.update), and a handful of composable primitives (Facet, StateField, Compartment, RangeSet) that every higher-level CodeMirror package builds on. Method names read close to plain English (state.field(f), tr.state, text.lineAt(pos)), and TypeScript generics make StateField<T>/Facet<Input, Output> usage type-safe end-to-end. The tradeoff is a real conceptual learning curve — understanding facets, compartments, and transaction specs requires reading the reference docs before writing a non-trivial extension, though the official docs and CodeMirror’s own language/view packages serve as thorough worked examples.

Used by 73 apps in this directory

Clojure
57%
Other

Metabase

Analytics

49,827

The open-source BI platform that lets anyone ask questions and build dashboards without writing SQL — with an embedded analytics SDK and AI-powered query assistant included.

View details
95
Repo Health
84
Technical
62
Dependency
Built with
Clojure 57%
TypeScript 38%
Updated 6 days ago
TypeScript
88%
MIT

Mistle

AI Agents · Developer Tools

95

Self-hostable platform for running autonomous coding agents in isolated, credentialless sandboxes with brokered credentials, reusable snapshots, and event-driven triggers.

View details
50
Repo Health
76
Technical
70
Dependency
Built with
TypeScript 88%
Rust 11%
Updated 4 weeks ago
TypeScript
92%
Other

n8n

Automation · No Code Platforms

208,437

Code when you need it, UI when you don't — the workflow automation platform built for technical teams who refuse to choose.

View details
95
Repo Health
87
Technical
62
Dependency
Built with
TypeScript 92%
Updated 1 weeks ago
Go
67%
MIT

nginx ignition

Developer Tools · Devops

2,141

A modern web UI for nginx that eliminates config file editing with visual virtual hosts, SSL automation, Docker integrations, and real-time traffic analytics.

View details
74
Repo Health
80
Technical
67
Dependency
Built with
Go 67%
TypeScript 28%
Updated 2 weeks ago
TypeScript
99%
Other

NocoBase

Low Code Platforms · No Code Platforms

24,686

Open-source AI + no-code platform that lets coding agents and people collaborate to build business systems fast on proven infrastructure.

View details
94
Repo Health
81
Technical
63
Dependency
Built with
TypeScript 99%
Updated 6 days ago
Go
63%
MIT

Obot

AI Agents · Mcp

1,120

An open-source MCP platform for organizations — host MCP servers, run MCP registries, monitor usage, and build agents and chatbots on top of the Model Context Protocol from one self-hosted deployment.

View details
88
Repo Health
70
Technical
70
Dependency
Built with
Go 63%
Svelte 21%
TypeScript 15%
Updated 1 weeks ago
Ruby
63%
MIT

OnetimeSecret

Security

2,970

Generate self-destructing single-use links to share passwords and sensitive data without leaving traces in inboxes or chat logs.

View details
92
Repo Health
81
Technical
72
Dependency
Built with
Ruby 63%
TypeScript 24%
Updated 6 days ago
TypeScript
97%
GPL 3.0

OpenKnowledge

Code Editors · Knowledge Management · Note Taking

4,674

A beautiful, local-first markdown IDE that turns any git repo into a live collaborative workspace for humans and AI coding agents like Claude, Codex, and OpenCode.

View details
80
Repo Health
89
Technical
64
Dependency
Built with
TypeScript 97%
Updated 6 days ago
TypeScript
90%
MIT

OpenClaw

AI Agents · AI Assistants

392,894

An open-source AI assistant that runs on your own hardware and meets you in Discord, Slack, WhatsApp, iMessage, Telegram, and 20+ other channels, with native apps for every major platform.

View details
88
Repo Health
88
Technical
66
Dependency
Built with
TypeScript 90%
Updated 6 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers