Skip to content
Inkoxide

Search covers every page and heading of the docs. Use ↑ ↓ and ↵.

Getting started

Install a package and render your first PDF, from React or from JSON.

Edit this page

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.

receipt.pdf
A6 receipt PDF: 'Receipt for Ada Lovelace', three items with prices and a bold total.

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.

OSArchitectures
macOSarm64, x64
Linuxx64 (glibc 2.35+ and musl), arm64 (glibc 2.35+)
Windowsx64

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.