The core knows nothing about shipped languages. createHighlighter() builds a name and alias registry from explicit LanguageDefinition objects. The root entry constructs the same registry with every shipped definition.
A language returns ordered, non-overlapping character ranges with semantic token classes. Untokenized characters are preserved as plain text.
Most languages use priority-ordered regular expressions. Three cases use small stateful scanners because regex-only matching loses necessary context:
This is the package's complexity boundary. It deliberately does not implement TextMate repositories, captures, scopes, backreferences, or a general recursive grammar DSL.
Embedding means one language delegates a character range to another registered language:
Dependencies remain optional. Importing HTML alone highlights markup. Registering HTML and JavaScript additionally highlights script bodies. This keeps the module graph explicit and tree-shakeable.
JavaScript template interpolation is recursive rather than merely embedded. A template string owns its string chunks, then ${...} delegates back to the script tokenizer. Nested templates repeat the same process.
The recursion depth has a small guard for pathological input. Normal nesting does not allocate a parser or grammar object.
Tokenization and rendering are separate:
Themes are CSS variables over stable semantic classes. Theme selection never changes tokenization or duplicates markup.
The target is valid code commonly published in documentation, not every legal program. A supported behavior needs:
New language support should be isolated, useful on real docs, and cheap enough to remain optional. A request that requires a general grammar engine belongs in Shiki, highlight.js, or Prism instead.