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

Go
69%
MIT

hoop

Monitoring · Security

836

A wire-protocol gateway that enforces data masking, command blocking, approval workflows, and full session recording for engineers and AI agents accessing production infrastructure.

View details
86
Repo Health
80
Technical
64
Dependency
Built with
Go 69%
Clojure 13%
Updated 6 days ago
TypeScript
68%
MIT

Hoppscotch

Developer Tools

80,676

A lightweight, offline-capable API development ecosystem for testing HTTP, GraphQL, WebSocket, MQTT, and SSE endpoints across web, desktop, and CLI.

View details
91
Repo Health
83
Technical
62
Dependency
Built with
TypeScript 68%
Vue 24%
Updated 1 weeks ago
TypeScript
97%
MIT

HyperDX

Analytics · Developer Tools · Monitoring

9,963

Open source observability platform that unifies logs, traces, metrics, and session replays on ClickHouse — now the core of ClickStack.

View details
89
Repo Health
83
Technical
64
Dependency
Built with
TypeScript 97%
Updated 6 days ago
TypeScript
91%
Apache 2.0

HyperFrames

AI Design Tools · AI Development

70,938

Turn plain HTML and CSS into deterministic, pixel-perfect MP4 videos — authored by humans or AI agents, rendered by headless Chrome and FFmpeg.

View details
84
Repo Health
83
Technical
65
Dependency
Built with
TypeScript 91%
Updated 6 days ago
TypeScript
100%
Apache 2.0

ILLA Builder

Design Tools · Developer Tools · Low Code Platforms

12,333

Open-source low-code platform for building internal tools with drag-and-drop UI, reactive data bindings, and real-time collaboration.

View details
55
Repo Health
71
Technical
63
Dependency
Built with
TypeScript 100%
Updated 5 months ago
TypeScript
96%
Other

Infisical

Devops · Security

29,961

The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.

View details
91
Repo Health
84
Technical
64
Dependency
Built with
TypeScript 96%
Updated 6 days ago
TypeScript
77%
Other

Joplin

Note Taking

56,853

The privacy-first, open-source note-taking app with end-to-end encrypted sync, AI assistance, and a powerful plugin ecosystem across every platform.

View details
93
Repo Health
87
Technical
60
Dependency
Built with
TypeScript 77%
JavaScript 14%
Updated 1 weeks ago
TypeScript
52%

Kener

Devops · Monitoring

5,216

Stunning, self-hosted status pages with real-time uptime monitoring, incident management, and multi-channel notifications in a single Docker container.

View details
87
Repo Health
76
Technical
66
Dependency
Built with
TypeScript 52%
Svelte 45%
Updated 1 weeks ago
TypeScript
44%
MIT

Kuku

Note Taking

230

A local-first, open-source Markdown knowledge workspace for macOS — plain files, personal wiki and Second Brain workflows, AI-assisted diffs, and encrypted sync, built as an Obsidian alternative.

View details
77
Repo Health
67
Technical
67
Dependency
Built with
TypeScript 44%
Rust 41%
Updated 1 weeks 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