Part of Ferramenta, a family of Rust tools.
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 lists each change.
Why Ferriki
- One engine, two languages. The
ferrikicrate is the highlighter,@ferriki/coreruns it through a native addon, and Ferromark 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. - Build-time macros in Vite 8. With
@ferriki/vite,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. - Class-based output with nested scopes.
styleMode: "classes"renders grammar scopes as nested spans for stylesheet themes.codeToHtmlWithCssderives the CSS from unchanged TextMate themes, and a theme map switches throughdata-ferriki-themewithout highlighting again. Inspired by GitHub's PrettyLights and starry-night. - Native highlighting, small installs. Ferroni, 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.
- Continuity. Shiki's
codeToHtml, highlighters, singleton,themesmap and custom grammars keep their call shapes, and the@shikijs/transformersnotation 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 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 for
the timing boundary and the singleton's reuse behavior.
Install and highlight
import from "@ferriki/core";
const html = await ;
use ;
// 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 covers mirrors and offline builds.
What you get
| Feature | Details |
|---|---|
| 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: tokens, line HTML, class HTML; Ferromark's ferriki feature |
| Vite build-time macros | @ferriki/vite: 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 and the migration guide.
Documentation
- ferriki.dev: guides and benchmarks
- API reference, class-based highlighting, asset loading
- Inline code macros, code example authoring
- Rust API and Ferromark, troubleshooting
Contributing
See CONTRIBUTING.md for the build, the test lanes and the
repository layout, and adr/ for the decisions.
License
Licensed under either of MIT or Apache-2.0 at your option.
More from Ferramenta
Ferramenta — A family of Rust tools.
Engines
| Tool | Job |
|---|---|
| ferroni | Oniguruma-compatible regex engine |
| ferromark | Markdown to HTML, sanitized by default |
| ferrolex | Spell checking for text and code |
| ferrocat | Translation catalog engine |
| ferralk | Glob matching and parallel filesystem walking |
| ferrugo | PDF previews for untrusted files |
Applications
| Tool | Job |
|---|---|
| palamedes | Internationalization for TypeScript applications |
| dalo | Your team's agent setup, versioned like code |
| ardo | Documentation sites built with React |