@ox-content/napi
Node.js bindings for Ox Content's Rust core.
Installation
vp install @ox-content/napi
Usage
Parse Markdown to AST
import { parseMarkdown } from "@ox-content/napi";
const markdown = "# Hello World\n\nThis is **bold** text.";
const ast = parseMarkdown(markdown, { gfm: true });
console.log(JSON.stringify(ast, null, 2));
Parse and Render
import { parseAndRender } from "@ox-content/napi";
const markdown = `
# Welcome
- Item 1
- Item 2
- Item 3
| Column A | Column B |
|----------|----------|
| Value 1 | Value 2 |
`;
const result = parseAndRender(markdown, {
gfm: true,
footnotes: true,
tables: true,
});
console.log(result.html);
API
parseMarkdown(content, options?)
Parses Markdown content and returns the AST.
Parameters
content:string- Markdown content to parseoptions:ParseOptions(optional)
Returns
MarkdownAst - The parsed AST
parseAndRender(content, options?)
Parses and renders Markdown to HTML in a single call.
Parameters
content:string- Markdown content to parseoptions:ParseOptions(optional)
Returns
interface RenderResult {
html: string;
frontmatter?: Record<string, unknown>;
toc?: TocEntry[];
}
Options
interface ParseOptions {
/** Enable GitHub Flavored Markdown */
gfm?: boolean;
/** Enable footnotes */
footnotes?: boolean;
/** Enable tables */
tables?: boolean;
/** Enable task lists */
taskLists?: boolean;
/** Enable strikethrough */
strikethrough?: boolean;
}
AST Types
The AST follows the mdast specification:
interface MarkdownNode {
type: string;
children?: MarkdownNode[];
value?: string;
// Additional properties based on node type
}
// Block nodes
type BlockNode =
| "root"
| "paragraph"
| "heading"
| "codeBlock"
| "blockquote"
| "list"
| "listItem"
| "table"
| "tableRow"
| "tableCell"
| "thematicBreak"
| "html";
// Inline nodes
type InlineNode =
| "text"
| "emphasis"
| "strong"
| "inlineCode"
| "link"
| "image"
| "break"
| "delete"
| "footnoteReference";
Search API
The NAPI bindings include a full-text search engine.
buildSearchIndex(documents)
Builds a search index from an array of documents.
import { buildSearchIndex } from "@ox-content/napi";
const documents = [
{
id: "getting-started",
title: "Getting Started",
url: "/getting-started",
body: "Welcome to the documentation...",
headings: ["Installation", "Quick Start"],
code: ["npm install package"],
},
];
const indexJson = buildSearchIndex(documents);
searchIndex(indexJson, query, options?)
Searches a serialized index.
import { searchIndex } from "@ox-content/napi";
const results = searchIndex(indexJson, "getting started", {
limit: 10,
prefix: true,
});
// results: Array<{
// id: string;
// title: string;
// url: string;
// score: number;
// matches: string[];
// snippet: string;
// }>
extractSearchContent(source, id, url, options?)
Extracts searchable content from Markdown source.
import { extractSearchContent } from "@ox-content/napi";
const markdown = "# Hello World\n\nThis is content.";
const doc = extractSearchContent(markdown, "hello", "/hello", { gfm: true });
// doc: {
// id: 'hello',
// title: 'Hello World',
// url: '/hello',
// body: 'This is content.',
// headings: ['Hello World'],
// code: [],
// }
Performance
Ox Content is positioned both as a document generator and as a high-performance Markdown toolkit. The numbers below focus on the Markdown engine side.
Latest local benchmark sweep on 2026-04-24 with Node v24.15.0 on Apple M5 Pro. The tables below show median results from 7 local runs of the benchmark harness for the large 48.7 KB case.
Parse Only (48.7 KB)
| Library | ops/sec | avg time | throughput |
|---|---|---|---|
@ox-content/napi |
2337 | 0.43 ms | 111.20 MB/s |
md4x (napi) |
958 | 1.04 ms | 45.56 MB/s |
md4w (md4c) |
884 | 1.13 ms | 42.06 MB/s |
markdown-it |
631 | 1.58 ms | 30.04 MB/s |
marked |
385 | 2.60 ms | 18.33 MB/s |
remark |
33 | 29.97 ms | 1.59 MB/s |
Parse + Render (48.7 KB)
| Library | ops/sec | avg time | throughput |
|---|---|---|---|
Bun.markdown.html |
3376 | 0.30 ms | 160.67 MB/s |
md4x (napi) |
3167 | 0.32 ms | 150.73 MB/s |
@ox-content/napi |
2599 | 0.38 ms | 123.66 MB/s |
md4w (md4c) |
2253 | 0.44 ms | 107.21 MB/s |
markdown-it |
628 | 1.59 ms | 29.91 MB/s |
marked |
381 | 2.62 ms | 18.15 MB/s |
micromark |
36 | 28.16 ms | 1.69 MB/s |
remark |
29 | 34.97 ms | 1.36 MB/s |
Reproduce with:
node benchmarks/bundle-size/parse-benchmark.mjs
In this latest local release-build sweep, Ox Content stays ahead for parse-only throughput. The parse+render comparison now includes md4x (napi), where Bun and md4x lead the table and Ox Content remains close behind while still serving as the native core for the full documentation pipeline.
The benchmark includes md4w (md4c) and md4x (napi) by default and adds Bun.markdown.html automatically when bun is available.