Node package
jsonpress is a native Node-API addon around jsonpress-core. It runs the
same Rust renderer in-process, so Node callers can use custom expression
functions — something the HTTP API deliberately does not accept.
Build inside this repository
cd crates/jsonpress-node
bun install
bun run build # napi build --platform --release
bun run test
The build produces native.js (the loader), native.d.ts and a platform
binary such as jsonpress.linux-x64-gnu.node. Those outputs are
ignored by git; publish them (or per-platform prebuilds) with the package.
Use
const { render } = require('jsonpress')
const pdf = render({
template, // ReportDefinition, version 2
rows: [{ CUSTOMER: 'Acme Ltd' }],
output: 'pdf', // pdf | docx | xlsx | excel | csv
functions: {
// Arguments arrive already evaluated, in source order.
shout: ([value]) => String(value).toUpperCase(),
},
})
fs.writeFileSync('report.pdf', pdf)
A template can then use shout(CUSTOMER) in any text, detail or note
expression.
PDF font families use the same JSONPRESS_FONTS catalog and template
font_family as the server; see deploy.md.
CSV output escapes spreadsheet formula-leading fields by default. Set
csvSafe: false in the render request only for trusted machine-to-machine
consumers that require unmodified CSV values.
Custom function contract
- A function receives one argument: an array of the evaluated argument strings.
- It must return a string. Returning another type is an error.
- Throwing an error fails the render and propagates to the caller.
- Functions run synchronously on the Node thread while the renderer evaluates. Keep them fast and side-effect-free.
- A function that is neither built in nor provided is an error; the render does not silently produce blank output.
- For large reports, run
renderinside aworker_threadsworker so the main event loop stays free.
The package is synchronous by design: Node-API callbacks must run on the thread that owns the JavaScript environment. The HTTP API remains the right choice when custom functions are not needed.
Publishing
The addon must be built per platform. @napi-rs/cli supports prebuilds and
GitHub Actions; publish the native.js loader plus the matching .node
binaries for each target (Linux/macOS/Windows, x64/arm64).