Part of [Ferramenta](https://ferramenta.dev), a family of Rust tools.
# Ferriki
[](https://oss.sebastian-software.com) [](https://github.com/sebastian-software/ferriki/actions/workflows/ci.yml)
[](./.github/workflows/ci.yml)
[](./LICENSE-MIT)
[](https://nodejs.org)
[](https://www.npmjs.com/package/@ferriki/core)
[](https://crates.io/crates/ferriki)
[](https://docs.rs/ferriki)
Ferriki is a native syntax highlighter for Node.js and Rust. Shiki brought
editor-grade highlighting to the web; Ferriki keeps its HTML API, grammars and
themes and runs them on a Rust port of VS Code's TextMate tokenizer, so Rust
programs, Node.js and Vite builds share one engine. Ferriki is in beta: until
1.0, a minor release can change the API, and the
[changelog](node/ferriki/CHANGELOG.md) lists each change.
## Why Ferriki
1. **One engine, two languages.** The [`ferriki`](https://crates.io/crates/ferriki)
crate is the highlighter, `@ferriki/core` runs it through a native addon,
and [Ferromark](https://ferromark.dev) uses it to highlight Markdown and MDX
fences natively. Shiki runs on JavaScript, with Oniguruma in WebAssembly or
a JavaScript regex engine, and has no Rust form.
2. **Build-time macros in Vite 8.** With [`@ferriki/vite`](node/vite/README.md),
`code()` and `<Code />` become highlighted HTML and CSS during the build; the
browser receives no grammar and no engine. Only modules that import a macro
are touched. Shiki's official content integrations work on Markdown; it has
no build-time macro for components.
3. **Class-based output with nested scopes.** `styleMode: "classes"` renders
grammar scopes as nested spans for stylesheet themes. `codeToHtmlWithCss`
derives the CSS from unchanged TextMate themes, and a theme map switches
through `data-ferriki-theme` without highlighting again. Inspired by
GitHub's PrettyLights and [starry-night](https://github.com/wooorm/starry-night).
4. **Native highlighting, small installs.**
[Ferroni](https://ferroni.dev), Oniguruma in Rust, runs grammar patterns as
written. Each platform's addon is its own optional package, and grammars and
themes download on first use from a release-pinned CDN, verified by SHA-256
and cached.
5. **Continuity.** Shiki's `codeToHtml`, highlighters, singleton, `themes` map
and custom grammars keep their call shapes, and the `@shikijs/transformers`
notation plugs in as is. A pinned, unmodified mirror of Shiki v4.4.3's tests
and the vscode-textmate v9.3.2 oracle check this in CI.
**Load once. Highlight block after block.** For a CMS, documentation server or
site build, keep one highlighter with its loaded languages and themes. On our
14-file Blacksmith corpus, Ferriki produced the same HTML as both Shiki
engines and ran **4.7× faster than Shiki/WASM on Linux x86-64** and **5.5× on
macOS ARM64** with reused highlighters. These are measured corpus totals,
not a guarantee for every workload. The [benchmarks](https://ferriki.dev/evidence/benchmarks)
include both hosts, JSON/Astro, first-use timings and committed raw reports.
Keep the default regex prefilter for repeated work. For a short-lived process,
`regexPrefilter: false` in Node or `.with_regex_prefilter(false)` in Rust avoids
prefilter construction. In the recorded Node full-corpus run, it shortened first
use by 35–37% but made repeated highlighting take 51–68% longer. See
[choosing the prefilter](docs/ferriki-api.md#choosing-the-regex-prefilter) for
the timing boundary and the singleton's reuse behavior.
## Install and highlight
```sh
npm install @ferriki/core # Node.js
npm install @ferriki/core @ferriki/vite # Vite 8, one shared version
cargo add ferriki --features remote # Rust
```
```js
import { codeToHtml } from "@ferriki/core";
const html = await codeToHtml("const answer = 42;", { lang: "typescript", theme: "github-dark" });
```
```rust
use ferriki::{Highlighter, RemoteAssets, RenderOptions, StandardAssetCatalogs, render_html};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut highlighter = Highlighter::builder()
.with_assets(StandardAssetCatalogs::remote(RemoteAssets::default())?)
.load_languages(["rust"])
.load_themes(["github-dark"])
.build()?;
let tokens = highlighter.highlight("fn main() {}", "rust", "github-dark")?;
println!("{}", render_html(&tokens, &RenderOptions::default()));
Ok(())
}
```
```tsx
// vite.config.ts
import react from "@vitejs/plugin-react";
import { ferriki } from "@ferriki/vite";
export default { plugins: [ferriki({ theme: "github-dark" }), react()] };
// Example.tsx: the build replaces <Code /> with highlighted HTML and its CSS.
import { Code } from "@ferriki/core/react/macro";
export const Example = () => <Code language="ts" source={`const answer = 42;`} />;
```
The first use of a language or theme downloads it, verifies it and caches it;
[asset loading](docs/asset-loading.md) covers mirrors and offline builds.
## What you get
| HTML output | `codeToHtml` with Shiki's markup, inline styles and escaped source |
| Class-based CSS output | `styleMode: "classes"`, or `codeToHtmlWithCss` for `{ html, css }` |
| Single and multi-theme | `theme`, or a `themes` map switched by CSS variables or `data-ferriki-theme` |
| Transformers | Shiki's hooks and decorations, including the `@shikijs/transformers` notation |
| 260 grammars, 65 themes | Loaded on demand and cached; a mirror or warm cache serves offline builds |
| Custom grammars and themes | TextMate JSON with aliases and injections, validated before use |
| Rust crate and Ferromark | [`ferriki`](https://docs.rs/ferriki): tokens, line HTML, class HTML; Ferromark's `ferriki` feature |
| Vite build-time macros | [`@ferriki/vite`](node/vite/README.md): `code()` and `<Code />` on Vite 8 |
| Platforms | Node.js 22.13.0 or newer, ESM-only; Linux x64/arm64 (glibc, musl), macOS arm64, Windows x64/arm64 |
## Compatibility
Ferriki pins one release of each upstream, currently Shiki v4.4.3 and
vscode-textmate v9.3.2. Both are mirrored unmodified and checked in CI, and
every Shiki test is classified as supported, deferred or out of scope. HTML is
the Node output: transformer callbacks receive token and HAST data, and the
Rust crate returns tokens. Ferriki runs in Node.js and Rust; browsers get its
build-time output. See the [compatibility policy](docs/compatibility.md) and
the [migration guide](docs/migrations/shiki-to-ferriki.md).
## Documentation
- [ferriki.dev](https://ferriki.dev): guides and [benchmarks](https://ferriki.dev/evidence/benchmarks)
- [API reference](docs/ferriki-api.md), [class-based highlighting](docs/class-highlighting.md), [asset loading](docs/asset-loading.md)
- [Inline code macros](docs/inline-code-macros.md), [code example authoring](docs/code-example-authoring.md)
- [Rust API and Ferromark](docs/rust-api.md), [troubleshooting](docs/troubleshooting.md)
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md) for the build, the test lanes and the
repository layout, and [`adr/`](adr/README.md) for the decisions.
## License
Licensed under either of [MIT](./LICENSE-MIT) or [Apache-2.0](./LICENSE-APACHE)
at your option.
### <a href="https://ferramenta.dev"><img src="https://raw.githubusercontent.com/sebastian-software/ferramenta/main/app/assets/brand/logo-light.svg" width="24" height="24" alt="" /> More from Ferramenta</a>
[Ferramenta](https://ferramenta.dev) — A family of Rust tools.
**Engines**
| [ferroni](https://ferroni.dev) | Oniguruma-compatible regex engine |
| [ferromark](https://ferromark.dev) | Markdown to HTML, sanitized by default |
| [ferrolex](https://github.com/sebastian-software/ferrolex) | Spell checking for text and code |
| [ferrocat](https://ferrocat.dev) | Translation catalog engine |
| [ferralk](https://github.com/sebastian-software/ferralk) | Glob matching and parallel filesystem walking |
| [ferrugo](https://github.com/sebastian-software/ferrugo) | PDF previews for untrusted files |
**Applications**
| [palamedes](https://palamedes.dev) | Internationalization for TypeScript applications |
| [dalo](https://dalo.sh) | Your team's agent setup, versioned like code |
| [ardo](https://ardo-docs.dev) | Documentation sites built with React |
---
<p align="center">
<a href="https://oss.sebastian-software.com"><img src="https://raw.githubusercontent.com/sebastian-software/oss.sebastian-software.com/main/app/assets/logo-software.svg" alt="Sebastian Software" width="160" /></a><br />
TypeScript, React & Rust consulting<br />
Experts in Agentic Software Development<br />
<a href="https://sebastian-software.de">Work with us</a> · <a href="https://oss.sebastian-software.com">More open source</a>
</p>
<p align="center">Copyright © 2026 Sebastian Software GmbH</p>