API overview
@ferriki/core provides a tested, HTML-focused subset of Shiki's direct
highlighting API for Node.js. This page is the map; the complete reference,
with every type and error code, is
docs/ferriki-api.md.
One-shot functions
Each one uses the shared singleton and returns a Promise; pass a highlighter as the first argument and it returns synchronously.
| Function | Returns |
|---|---|
codeToHtml(code, options) | Escaped HTML with Shiki's line and token structure |
codeToHtmlWithCss(code, options) | { html, css } with nested classes and a stylesheet |
getLastGrammarState(code, options) | A serializable state to continue highlighting later |
Highlighters
| Factory | Notes |
|---|---|
createHighlighter(options) | Resolves loaders and promises, then returns |
createHighlighterCoreSync(options) | Accepts already resolved registrations only |
getSingletonHighlighter(options) | The instance the one-shot functions use |
A highlighter carries the methods above plus loadLanguage, loadTheme (and
their Sync forms), getLoadedLanguages, getLoadedThemes,
resolveLangAlias and dispose.
Highlighter options
Factory options include langs, themes, langAlias, transformers,
assets and regexPrefilter. With regexPrefilter: true (the default),
standard grammars load prepared regex packages and restore Eager scanner
optimizations. Missing packages fall back to source; custom and dynamic
patterns prepare locally. Set regexPrefilter: false to skip the prepared
packages and disable the prefilter. Matching and colors stay the same.
This is a creation-time option, including the singleton's first creation;
it is not a HighlightOptions field.
The prepared-package measurements separate restoration from execution. Top-level shorthand functions reuse the singleton and do not create a fresh highlighter for each code block.
Highlight options
The common ones: lang, theme or themes, defaultColor,
cssVariablePrefix, styleMode, mergeWhitespaces, mergeSameStyleTokens,
tabindex, rootStyle, structure, meta, grammarState and
includeExplanation. tokenizeTimeLimit (500 ms per line by default) and
tokenizeMaxLineLength limit per-line tokenization work. The time budget is
best-effort: Ferriki checks it between tokenizer matching passes and after each
pass returns. A pass can run one or more synchronous regex searches, which
cannot be interrupted and may exceed the configured budget. An overrun is
reported as stopped-early tokenization.
Errors
Every user-facing failure is a ShikiError with a stable code
(ERR_USAGE, ERR_UNSUPPORTED, ERR_NATIVE_LOAD, ERR_ASSET,
ERR_RESOURCE_LIMIT, ERR_INTERNAL). Failures inside the native engine are
its subclass FerrikiError, so existing instanceof ShikiError checks keep
working.
For nested scopes, unchanged theme files, and CSS-only theme switching, see Class-based output.
Assets and asynchronous loading
The package ships language and theme catalog metadata, not the grammar and
theme payloads. createHighlighter, loadLanguage, loadTheme, and one-shot
calls download missing payloads from the release-pinned asset host, verify
their SHA-256 digests, and cache them. Calls on a loaded highlighter are
synchronous. Configure assets: { remote: false } or
FERRIKI_ASSETS_REMOTE=0 to use a populated cache without network access;
assets.baseUrl and FERRIKI_ASSETS_BASE_URL select a mirror.
Build-time macros
code() from @ferriki/core/macro and <Code /> from
@ferriki/core/react/macro are markers that @ferriki/vite replaces with
highlighted HTML and CSS during a Vite 8 build. Build-time macros
covers the setup, the macro forms and their rules.