Part of Ferramenta, a family of Rust tools.
Beautiful code. Head start included. Ferriki brings native, Oniguruma-compatible syntax highlighting to docs, blogs, and CMS content. Precompiled CDN packages are ready for production and enabled by default for standard grammars. Use familiar Shiki-style HTML calls in Node.js, call the Rust API directly, or prepare component examples with Vite 8 macros.
Native Oniguruma compatibility and precompiled delivery work together in Ferriki's production default. Standard language packages carry compiled regex programs and optimized static scanner automata alongside the syntax definition. The optimization becomes part of the download. Matching stays in Ferroni's native, Oniguruma-compatible engine, with no translation into JavaScript RegExp. Capture-dependent end and while patterns remain dynamic to preserve TextMate behavior.
Powered by Ferroni 2.8, we move static regex compilation and Eager scanner preparation into the asset pipeline. The CDN delivers that prepared work alongside the grammar. Each new process restores the scanners it needs, with their static optimizations already in place.
Keep the disk cache between builds and you keep the download, the unpacked packages, and the preparation. Prepared packages are the default with prefiltering on. Missing packages fall back to source, and dynamic patterns remain local. Only requested languages and required dependencies load; optional code-fence languages stay optional.
Sponsored by Sebastian Software, which currently covers Ferriki's CDN costs.
The payoff shows up at both ends: first HTML takes about half the time of Source Eager, while repeated highlighting keeps Eager's execution speed. In our fourteen-file Blacksmith corpus, Prepared starts within 6% of the unoptimized Source Off path on both hosts.
| Same 14-file corpus, same HTML as Shiki/WASM | Linux x86-64 | macOS ARM64 |
|---|---|---|
| First HTML vs. Shiki/WASM | 4.2× faster | 5.5× faster |
| Repeated highlighting vs. Shiki/WASM | 3.7× faster | 4.4× faster |
Measured October 27, 2026 with Ferriki 1.3.0 and Ferroni 2.8.0. First HTML includes imports, setup, and rendering in a fresh process with the asset and decoded caches already populated; downloads, first cache fill, and process creation are excluded. These are highlighting measurements, not total build times. See every mode, machine, and raw result.
| If you build with… | Start with… | Guide |
|---|---|---|
| Node.js | npm install @ferriki/core |
Node.js package guide |
| Rust | cargo add ferriki --features remote |
Rust API guide |
| Vite 8 and React | npm install @ferriki/core @ferriki/vite |
Vite macros guide |
Ferriki requires Node.js 22.13.0 or newer and uses ESM. npm installs the matching optional native package for Linux x64/arm64 (glibc or musl), macOS Apple Silicon, or Windows x64/arm64; keep optional dependencies enabled.
Install the package in your project:
npm install @ferriki/coreLanguage and theme payloads download from the release-pinned CDN on first use, are verified with SHA-256, and are cached locally. For offline builds, populate the cache ahead of time or use a mirror. See asset loading.
Save this complete ESM file as highlight.mjs, then run node highlight.mjs:
import { writeFile } from "node:fs/promises";
import { codeToHtml } from "@ferriki/core";
const html = await codeToHtml("const answer = 42;", {
lang: "javascript",
theme: "github-dark",
});
await writeFile("highlighted.html", html);
console.log("Saved highlighted.html. Open it in a browser to preview your code.");For a documentation build or CMS worker, create a highlighter with the languages and themes you need, then keep it around for the blocks you render. Calls with loaded languages and themes are synchronous. Create one highlighter per worker, and dispose it when that worker shuts down.
import { createHighlighter } from "@ferriki/core";
const highlighter = await createHighlighter({
langs: ["typescript", "rust", "css"],
themes: ["github-light", "github-dark"],
});
try {
const html = highlighter.codeToHtml("const answer: number = 42;", {
lang: "typescript",
theme: "github-dark",
});
console.log(html);
} finally {
highlighter.dispose();
}Prepared scanners add download weight. Here is the tradeoff for the same requested languages, including their required dependencies:
| Language | Grammar-only CDN payload | Total with prepared scanners |
|---|---|---|
| Rust | 18 kB | 58 kB · 3.2× |
| TypeScript | 0.54 MB | 4.65 MB · 8.6× |
| Markdown | 61 kB | 1.97 MB · 32.2× |
Grammar-only is Ferriki's unoptimized grammar payload; Prepared keeps that payload and adds compiled programs and automata. Sizes are decimal and exclude themes and HTTP overhead. Optional fenced-code languages are not loaded. Keep the cache to reuse these downloads; decoded data takes additional disk space. See the exact sizes and source-definition comparison.
Memory looks good in the new capture, too. After 600 documents across twelve loaded languages, Prepared's whole-process RSS was 45% lower than Shiki/WASM on both hosts. For the large TypeScript workload, it was 67–69% lower. These are medians from six isolated processes per contender and workload, with identical HTML. See the memory measurements.
The catalog covers TypeScript, JSX and TSX, Vue, Svelte, Astro, and Angular; Rust, Python, Go, Java, C/C++, and C#; Markdown, MDX, SQL, JSON, YAML, and TOML; and build tools from shell scripts and Docker to Terraform and Nix.
TextMate grammars follow the context inside your code: embedded JavaScript and CSS in HTML, component expressions, tagged templates, and registered languages in Markdown fences. The catalog contains 67 standard entries for languages and formats, plus 27 support grammars for embeddings and injections, with 65 themes. Register custom TextMate grammars for syntax outside the curated catalog. Browse the coverage and examples.
| Need | Ferriki provides |
|---|---|
| Shiki-shaped HTML | codeToHtml, highlighters, singleton helpers, and transformer callbacks for Node.js |
| Stylesheet-driven themes | Nested TextMate scope classes, generated CSS, and theme maps that switch without highlighting again |
| A grammar of your own | Ferriki's curated catalog plus custom TextMate grammars, aliases, and injections; see the grammar guide |
| Code in Vite components | code() and React <Code /> macros that prepare highlighted output at build time on Vite 8 |
| Native Rust highlighting | The ferriki crate: tokens, line HTML, and class-based HTML |
Import @ferriki/core/macro or @ferriki/core/react/macro in the modules whose
examples you want prepared. The build delivers highlighted output, and React
<Code /> uses a small framework-free presentation module in the browser.
Grammar payloads stay on the build side; see the Vite guide
for the quickstart, SSR behavior, and limits.
Enable the remote asset catalog with cargo add ferriki --features remote.
This small program highlights a Rust function and prints HTML:
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(())
}Ferriki follows semantic versioning: breaking changes to its public API require a major version; see the changelog. It pins Shiki v4.4.3 and vscode-textmate v9.3.2 as behavioral references. Shiki's tests run unchanged from a pinned mirror, each classified as supported, deferred, or out of scope; the tokenizer is checked against the full vscode-textmate oracle. Node's public output is HTML, while transformer callbacks can inspect token and HAST data. The Rust crate exposes tokens and HTML rendering. See the compatibility policy and Shiki migration guide.
- ferriki.dev: guides and benchmarks
- API reference, class-based highlighting, and asset loading
- Inline code macros and code example authoring
- Rust API and Ferromark, plus troubleshooting
See CONTRIBUTING.md for the build, test lanes, and repository
layout, and adr/ for the decisions behind the project.
Licensed under either of MIT or Apache-2.0 at your option.
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 |
TypeScript, React & Rust consulting
Experts in Agentic Software Development
Work with us · More open source
Copyright © 2026 Sebastian Software GmbH