@codemirror/commands
A collection of editing, selection, deletion, indentation, and undo-history commands with default keymaps for the CodeMirror 6 code editor.
Repository Health
Technical Analysis
@codemirror/commands supplies the editing behavior that most code editors need but @codemirror/view and @codemirror/state deliberately leave out: cursor and selection movement (by character, group, subword, line, page, syntax node, or document boundary), deletion, line manipulation, indentation, character transposition, and an undo/redo history extension. Each behavior is exposed as a plain Command or StateCommand function plus pre-built KeyBinding arrays (standardKeymap, defaultKeymap, emacsStyleKeymap, historyKeymap), so an application wires up editing behavior by spreading a keymap into @codemirror/view’s keymap facet rather than reimplementing cursor and selection logic from scratch.
Because every command is just a function of {state, dispatch} or an EditorView, they compose cleanly with custom key bindings, can be called programmatically outside of a keypress, and interoperate with @codemirror/language for syntax-aware operations like toggleComment, indentSelection, and cursorSyntaxLeft/cursorSyntaxRight. The package is a peer dependency of nearly every CodeMirror 6 setup (including presets like codemirror and basic-setup) and receives frequent point releases fixing selection-association and cursor-placement edge cases.
What You Get
- Cursor and selection commands for character, group, subword, line, page, syntax-node, and document-boundary motion, each with a
select*counterpart for extending the selection - Deletion commands (
deleteCharBackward,deleteGroupForward,deleteLine,deleteTrailingWhitespace, etc.) covering per-character, per-group, and per-line removal in both directions - Line manipulation and indentation commands:
moveLineUp/moveLineDown,copyLineUp/copyLineDown,indentMore/indentLess,indentSelection, and Tab handling viainsertTab/indentWithTab - An undo/redo
history()extension withundo,redo,undoSelection,redoSelection, configurable grouping (newGroupDelay), andinvertedEffectsfor making custom StateEffects undoable - Line and block commenting/uncommenting (
toggleComment,toggleLineComment,toggleBlockComment) driven by language-providedCommentTokens - Pre-built keymaps —
standardKeymap,defaultKeymap(superset with syntax-aware and Alt/Cmd bindings),emacsStyleKeymap, andhistoryKeymap— ready to spread intokeymap.of([...])
Common Use Cases
- Wiring baseline editing behavior (arrow keys, backspace, select-all, undo/redo) into a from-scratch CodeMirror 6 editor via
defaultKeymap - Adding syntax-aware operations such as commenting a selection or expanding the selection to the enclosing syntax node in a code-editing product
- Building a custom keymap (e.g. Emacs- or Vim-flavored bindings) by picking individual command functions like
cursorGroupLeftordeleteToLineEndrather than using the packaged keymaps - Adding an undo history to an embedded config/query/formula editor and exposing undo/redo as toolbar buttons that call the exported
undo/redocommands directly
Under The Hood
Architecture — The package is organized around three files with a clean dependency direction: commands.ts (1,124 lines) defines pure selection/deletion/indentation commands as Command/StateCommand functions built from small composable helpers (moveSel, deleteBy, extendSel) that transform an EditorState’s EditorSelection and dispatch a Transaction; history.ts (399 lines) implements undo/redo as a StateField (historyField_) storing done/undone branches of HistEvents, using transaction annotations (fromHistory, isolateHistory) to distinguish history-replay transactions from normal edits and a time/newGroupDelay-based heuristic to merge adjacent keystrokes into one undo step; comment.ts (201 lines) implements line/block toggling by reading language-provided CommentTokens and computing per-line or per-range comment insertion/removal as a single ChangeSet. commands.ts re-exports both sibling modules so the whole package presents one flat public surface, and standardKeymap/defaultKeymap are assembled at the bottom of commands.ts by concatenating arrays of KeyBinding objects that reference the exported command functions.
Tech Stack — Pure TypeScript (100% of the codebase, 134KB) with @codemirror/state (^6.6.0), @codemirror/view (^6.27.0), @codemirror/language (^6.0.0), and @lezer/common (^1.1.0) as direct dependencies — it sits strictly above state/view and below any language-specific package. Build tooling is CodeMirror’s own @codemirror/buildhelper (cm-buildhelper src/commands.ts) producing dual ESM/CJS output (dist/index.js / dist/index.cjs) with bundled .d.ts types; package.json declares "type": "module" and "sideEffects": false for tree-shaking. Tests run via cm-runtests (the shared CodeMirror test runner, cm-buildhelper’s sibling).
Code Quality — Tests total 1,452 lines across four files (test-commands.ts 259, test-comment.ts 221, test-history.ts 646, webtest-commands.ts 292 for DOM-dependent cases), giving the undo history — the most stateful, edge-case-prone part of the package — by far the heaviest coverage. Every exported command in commands.ts and history.ts carries a ///-prefixed doc comment consumed by CodeMirror’s own doc generator, and internal helpers are small, single-purpose functions (moveSel, rangeEnd, deleteBy) rather than large branching functions, keeping each command’s diff-sized and independently testable. No linter config ships in the repo; consistency is enforced by the shared CodeMirror build tooling and code review norms across the monorepo-like family of packages.
API Design — The public surface is deliberately flat and uniform: nearly every export is either a Command/StateCommand function with the exact signature (target) => boolean, or a readonly KeyBinding[] array, so consumers can mix hand-picked commands and packaged keymaps without adapters. The select* naming convention (mirroring every cursor* command with a same-named select* variant) makes the API’s shape predictable without reading docs. The tradeoff is a large flat namespace — over 60 command exports — with no sub-grouping, so discoverability leans on the README’s categorized command list (Selection / Deletion / Line manipulation / Indentation / Undo History / Commenting) rather than the module structure itself.
Used by 55 apps in this directory
overleaf
Collaboration · Productivity
Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.
peerd
AI Agents
The first AI agent harness native to the browser — a Chrome/Firefox extension that drives your tabs, spins up sandboxed compute (JS notebooks, WASM Linux VMs), and shares what it builds peer-to-peer, with no backend, no telemetry, and BYOK.
Arize Phoenix
Analytics · Devops · Monitoring
Open-source AI observability platform for tracing, evaluating, and debugging LLM applications with built-in intelligence and MCP support.
Portainer
Devops
A lightweight, open-source web UI that puts Docker, Kubernetes, and Podman management within reach of any team—no CLI expertise required.
Rill
Analytics · Data Engineering
The fastest BI tool for humans and agents — define metrics, models, and dashboards as code and query them instantly on ClickHouse or DuckDB.
Rivet
AI Agents · Developer Tools
Stateful actors as a primitive for AI agents, real-time collaboration, and durable execution — with in-memory state, WebSockets, queues, and scheduling built in.
Sanity
CMS
Open-source headless CMS with a fully customizable React Studio, real-time collaborative editing, structured content modeling, and GROQ query language
Scalar
Developer Tools
Beautiful, interactive OpenAPI documentation with a built-in offline-first API client and multi-language code generation — all in one open-source platform.
Sourcebot
AI Code Assistants · Developer Tools · Search
A self-hosted, AI-powered code search engine that indexes every repo across GitHub, GitLab, Bitbucket, Gitea, Gerrit, and Azure DevOps, so both engineers and coding agents can search, browse, and ask questions about your codebase from one place.