codemirror-lang-nix

A Lezer-based Nix language mode for CodeMirror 6, adding syntax highlighting, indentation, and folding for Nix expressions.

Library
npm
v6.0.1
18stars
MIT License

Repository Health

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

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
55/100Fair
Architecture78
Code Quality40
Innovation55
Learning Curve45

@replit/codemirror-lang-nix is a CodeMirror 6 language package that adds first-class support for the Nix expression language, the configuration language behind the Nix package manager and NixOS. It ships a Lezer grammar for Nix’s expression syntax — functions, let/in and with blocks, attribute sets, lists, string interpolation, paths, and the full Nix operator precedence table — along with external tokenizers for Nix’s quoted and indented string literals.

Built by Replit for the browser-based Nix editing experience on their platform, the package wires the grammar into CodeMirror’s language-data system: syntax-aware indentation for parentheses, attribute sets, lists, and let/in blocks; code folding for attribute sets, lists, and let bindings; and highlight tags mapped to Lezer’s standard tag set so any CodeMirror theme picks up correct colors automatically. A small set of snippet completions for let and with statements rounds out the editing experience.

What You Get

  • A full Lezer grammar for Nix’s expression syntax, covering functions, let/in, with, assert, attribute sets, lists, and the complete binary/unary operator precedence table
  • External tokenizers for Nix’s quoted (”…”) and indented (” … ”) string literals, including string interpolation and escape sequences
  • Pre-configured indentation rules for parenthesized expressions, attribute sets, lists, and let/in blocks
  • Code folding support for attribute sets, lists, and let bindings
  • Syntax highlighting via Lezer’s standard highlight tags, so any CodeMirror theme renders Nix code with correct colors out of the box
  • Snippet-based autocomplete for let ... in and with statements

Common Use Cases

  • Adding Nix syntax highlighting to a browser-based IDE or REPL, as Replit does for editing .nix files and flake.nix configurations
  • Building a web-based Nix playground or documentation site with an interactive, highlighted code editor
  • Embedding a lightweight Nix code viewer in developer tooling built on CodeMirror 6
  • Extending a CodeMirror-based editor to support Nix alongside other languages in a polyglot code environment

Under The Hood

Architecture The package is a single-purpose CodeMirror language extension organized around three files under src/: syntax.grammar (the Lezer grammar source, compiled at build time into a parser table via @lezer/generator), tokens.ts (external tokenizers handling context-sensitive string lexing the declarative grammar can’t express directly — Nix’s quoted and indented strings with interpolation), and index.ts (wires the compiled parser into an LRLanguage, attaches indentation/folding/highlight NodeProps, and exports a nix() LanguageSupport factory plus snippet-based autocomplete). There is no runtime dependency injection or app lifecycle — it’s a pure, stateless extension factory following CodeMirror 6’s standard language-package shape, so changing the core grammar means regenerating the compiled parser and touching only index.ts’s NodeProp wiring, while tokens.ts stays isolated since it only implements the ExternalTokenizer callbacks the grammar declares as external.

Tech Stack TypeScript compiled to a dual ESM/CJS build via @codemirror/buildhelper’s cm-buildhelper CLI, with an exports map and generated .d.ts types. Core integration points are peerDependencies (not bundled runtime deps) on the @codemirror/* v6 family (state, view, language, autocomplete) and @lezer/* (common, highlight, lr) — consumers must already have CodeMirror 6 installed. Dev tooling includes @lezer/generator to compile the grammar, vite for a local dev/ playground (paired with a custom node ./dev/watch.cjs watch script), and npm-run-all to orchestrate parallel dev tasks. There is no server or database component — this is a pure browser-side editor extension.

Code Quality No test files exist anywhere in the repo, despite package.json wiring a “test”: “cm-runtests” script — cm-runtests discovers fixture-based grammar test files, and none are present, so test coverage is effectively zero. Source is compact (four files, roughly 250 lines combined) and largely declarative; the grammar and tokenizer have no error handling beyond what the ExternalTokenizer contract requires. Typing is straightforward and consistent, using imported types from @codemirror/language and @lezer/highlight with no use of any. There is no CI configuration and no linter or formatter wired into the scripts.

What Makes It Unique The package’s specific contribution is a working Nix grammar for Lezer — Nix’s syntax (indented strings, path literals, search-paths like <nixpkgs>, with/let/inherit/rec, and Nix’s particular operator precedence for //, ++, ?, and ->) is unusual enough that no generic configuration-language highlighter handles it correctly, and this grammar encodes those Nix-specific productions and precedence rules directly. That said, it implements an existing language spec using the standard Lezer/CodeMirror language-package pattern followed by dozens of other @codemirror/lang-* packages, so the engineering approach itself is entirely conventional for the ecosystem.

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