Getting started
Install a package and render your first PDF, from React or from JSON.
With React
npm install @inkoxide/render
To style with Tailwind classes (className), as the example does, add:
npm install @inkoxide/tailwind
Save this as receipt.tsx:
/** @jsxRuntime automatic */
import { Document, Page, renderToFile, Text, View } from '@inkoxide/render';
function Receipt({ customer, lines }: { customer: string; lines: { name: string; amount: number }[] }) {
const total = lines.reduce((sum, l) => sum + l.amount, 0);
return (
<Document title={`Receipt for ${customer}`}>
<Page size="A6" className="p-8 text-xs text-gray-900">
<Text className="text-lg font-bold">Receipt</Text>
<Text className="mb-4 text-gray-500">for {customer}</Text>
{lines.map((l) => (
<View key={l.name} className="flex-row justify-between border-b border-gray-200 py-1.5">
<Text>{l.name}</Text>
<Text>${l.amount.toFixed(2)}</Text>
</View>
))}
<View className="mt-3 flex-row justify-between font-bold">
<Text>Total</Text>
<Text>${total.toFixed(2)}</Text>
</View>
</Page>
</Document>
);
}
renderToFile(
<Receipt
customer="Ada Lovelace"
lines={[
{ name: 'Espresso', amount: 3.2 },
{ name: 'Almond croissant', amount: 4.5 },
{ name: 'Sparkling water', amount: 2 },
]}
/>,
'receipt.pdf',
);
Run it with npx tsx receipt.tsx. The fonts (Inter, Noto Sans, Roboto Mono) ship with the
package, and @inkoxide/tailwind brings the Tailwind compiler. More examples, each with its source and its PDF, are in the playground.

Switch to Layout for the boxes the engine laid out.
Drawn by the engine’s debug option, sizes in points.
With JSON
import { readFileSync, writeFileSync } from 'node:fs';
import { registerFont, render } from 'inkoxide';
registerFont('Inter-Bold', readFileSync('Inter-Bold.ttf'));
const doc = {
version: 1,
fonts: [{ id: 'Inter-Bold', family: 'Inter', weight: 700 }],
pages: [
{
size: { width: 595.28, height: 841.89 },
margin: { top: 56, right: 56, bottom: 56, left: 56 },
children: [{ type: 'text', runs: [{ text: 'Hello, PDF', font: 'Inter-Bold', size: 28 }] }],
},
],
};
writeFileSync('hello.pdf', await render(JSON.stringify(doc)));
The document tree is a fully resolved description of boxes, text, images and tables, as JSON or
MessagePack. @inkoxide/schema has its TypeScript types and JSON Schema.
Platforms
Prebuilt binaries; npm installs the one for the current platform. Every package needs Node.js 22 or later and is an ES module.
| OS | Architectures |
|---|---|
| macOS | arm64, x64 |
| Linux | x64 (glibc 2.35+ and musl), arm64 (glibc 2.35+) |
| Windows | x64 |
In browsers (current Chrome, Edge, Firefox and Safari), the engine is WebAssembly
(@inkoxide/wasm), and @inkoxide/render/browser renders in a Web Worker; see
In the browser.
Synced from README.md in the inkoxide repository.
