codemirror-indentation-markers

Adds Ace- and Monaco-style indentation guide lines to CodeMirror 6 editors, highlighting the active nesting block as you type.

Library
npm
v6.5.3
89stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
30/100Needs Attention
Development Activity0
Maintenance0
Community44
Maturity56
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
59/100Fair
Architecture76
Code Quality48
Innovation55
Learning Curve55

@replit/codemirror-indentation-markers is a CodeMirror 6 extension that renders vertical indentation guide lines directly in the editor, using a heuristic similar to what Ace and Monaco use to infer indent levels from surrounding code rather than requiring language-specific fold data. It ships as a single ViewPlugin that recomputes guides only for the visible viewport, keeping large-file editing fast.

Built by Replit for its own browser-based IDE, the extension exposes a small configuration surface — marker thickness, active-block highlighting, first-column visibility, and separate light/dark colors — through a CodeMirror Facet, so it merges cleanly with other extensions in a shared EditorState.

What You Get

  • Indentation guide lines rendered via layered CSS background gradients on each line, avoiding a DOM element per marker
  • Active-block highlighting that traces the current selection’s enclosing indented scope
  • Independently themeable light/dark marker colors, including a separate color for the active block
  • Two marker length modes — full-scope markers or markers that terminate at the last non-empty line
  • Configurable marker and active-marker thickness in pixels
  • Viewport-scoped recomputation, so decoration work only touches lines currently visible

Common Use Cases

  • In-browser IDEs - product teams embedding CodeMirror 6 (as Replit does for its own browser IDE) add matching indent guides without shipping a heavier full IDE component
  • Python and YAML editors - since indentation carries syntactic meaning in these languages, editors add indent guides so users can spot misaligned blocks at a glance
  • Documentation and notebook playgrounds - lightweight web-based code cells (tutorials, docs sites, interactive playgrounds) get the same visual scanning aid as desktop editors
  • Design-system parity with desktop editors - teams building a web-based code editor add indentation markers to match expectations set by VS Code and other Monaco-based tools

Under The Hood

Architecture The extension is a single CodeMirror 6 ViewPlugin (IndentMarkersClass in src/index.ts) that recomputes decorations on doc, viewport, indent-unit, or active-line changes and renders them as Decoration.line classes with inline CSS custom properties. Configuration flows through a CodeMirror Facet (src/config.ts) that merges per-instance option objects with sensible defaults. The core indentation algorithm is isolated in IndentationMap (src/map.ts), which builds a line-number-to-indent-level map on demand, walking forward/backward through the document to resolve empty-line indentation and to find the start/end of the active block from the cursor position. Low-level line/column helpers live separately in src/utils.ts. This separation — plugin lifecycle, configuration, indentation algorithm, and utilities each in their own file — keeps the single responsibility of each part clear despite the small overall codebase.

Tech Stack Written entirely in TypeScript (strict mode) against CodeMirror 6’s @codemirror/state, @codemirror/view, and @codemirror/language packages, declared as peer dependencies so consumers control the exact CodeMirror version. It’s built with @codemirror/buildhelper’s cm-buildhelper, which produces both ESM and CommonJS output plus type declarations from a single src/index.ts entry point, matching the dual-module convention other CodeMirror 6 packages use. A Vite-powered dev/ folder serves as a live demo/playground during development.

Code Quality The source is fully typed with explicit interfaces (IndentEntry, IndentationMarkerConfiguration) and consistent JSDoc comments on nearly every method in map.ts and utils.ts, explaining non-obvious heuristics like empty-line indent inference. However, no test files or CI workflow configuration exist in the repository despite package.json wiring a test script to CodeMirror’s shared cm-runtests runner (which expects comment-based test blocks) — so automated verification is set up but not populated. Naming is consistent and there’s no evidence of swallowed errors, but the lack of any executed tests is a real gap for a rendering-heavy extension.

What Makes It Unique The project doesn’t invent a new indentation algorithm — its README is explicit that it mirrors the heuristic already used by Ace and Monaco — but it’s a rare from-scratch backport of that heuristic to CodeMirror 6, which lacks a built-in indent-guide extension. The empty-line handling in IndentationMap.add() (deciding whether a blank line continues, increments, or drops indentation based on its neighbors) is where most of the actual complexity in an otherwise small codebase lives.

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

Search