@quario/htmlA page
invoice-1042.html
Invoice No. 1042
| Item | Amount |
|---|---|
| Typesetting | US$1,440.00 |
| Folding & gathering | US$320.00 |
| Total | US$1,760.00 |
Reports are data, not code. An LLM drafts the definition; quario computes every number from your data and runs nothing the model writes.
Invoice for Acme — line items for the March work, total in dollars.
validate_report2 problemsvalidate_reportrevised0 problemsrender_reportinvoice-1042.pdf| Item | Amount |
|---|---|
| Typesetting | US$1,440.00 |
| Folding & gathering | US$320.00 |
| Total | US$1,760.00 |
The model wrote the formula. The total came from the data.
Renders wherever JavaScript runs
Sections, bindings, expressions. A format a model can write and a person can read.
plan() rejects a malformed definition and hands back every problem at its path.
quario computes every total from your data, then renders it wherever JavaScript runs — browser, Node, edge, workers.
The same definition gives HTML, PDF, a workbook, or Word.
@quario/html@quario/pdf@quario/xlsx@quario/docxAn agent's output is untrusted, because a prompt injection can hide in it. Engines that compile templates run that output through eval. quario parses expressions into safe closures. It generates no code and evaluates none.
And the model never writes a number. It declares the formula for each figure, and quario computes it from your data. If the model picks the wrong formula, you'll see it in the definition — not buried in the output.
Connect the quario MCP server, or register a tool of your own. The agent passes a definition and gets back every problem at the path it sits at, so it fixes the definition before anything renders.
The server's configuration stays yours: query budgets, link schemes, the data it may read and where it writes. Because the data comes from your side of the boundary, every figure traces back to your systems, not to the model.
→ validate_report { definition } ← 2 problems sort[0].dir: unknown sort direction "descending" detail.columns[1].value [{{ round(@.qty * @.unitPrice }}]: Unexpected end of expression → validate_report { definition } revised ← {"problems":[],"warnings":[]} → render_report { definition, target: "pdf", dataPath: "invoices/1042.json", filename: "invoice-1042" } ← Wrote invoice-1042.pdf (1.8 kB): /srv/reports/invoice-1042.pdf
Make the March invoice for Acme, totals in dollars.
quario-reportsvalidate_report — 1 problem, fixedrender_reportDone — saved invoice-1042.pdf
{
"mcpServers": {
"quario": {
"command": "npx",
"args": ["-y", "@quario/mcp"],
"env": { "QUARIO_LICENSE": "quario_..." }
}
}
}import { writeFile } from 'node:fs/promises'
import { generateText, jsonSchema, stepCountIs, tool } from 'ai'
import { anthropic } from '@ai-sdk/anthropic'
import { quario } from 'quario'
import { pdf } from '@quario/pdf'
import schema from 'quario/schema.json' with { type: 'json' }
const q = quario()
// The agent writes the definition; your code supplies the data.
const draftInvoice = tool({
description: 'Write a quario report definition for an invoice.',
inputSchema: jsonSchema(schema),
execute: async (definition) => {
const { report, problems } = q.plan(definition)
if (!report) return { ok: false, problems } // back to the agent
await writeFile('invoice.pdf', await report.render(pdf(), await getInvoice()))
return { ok: true }
},
})
await generateText({
model: anthropic('claude-sonnet-5'),
tools: { draft_invoice: draftInvoice },
stopWhen: stepCountIs(5),
prompt: 'Make the March invoice for Acme, totals in dollars.',
})import { quario } from 'quario'
import { pdf } from '@quario/pdf'
import definition from './reports/statement.report.json' with {
type: 'json',
}
const q = quario({ locale: 'en-GB', currency: 'EUR' })
const report = q.report(definition) // once, at startup
export async function renderStatement(accountId: string) {
const data = await db.statements.forAccount(accountId)
return report.render(pdf(), data) // HTML · PDF · XLSX · DOCX
}Compile a definition once and render it from a scheduled job, a queue worker, or an API route. The same definition gives HTML, PDF, a workbook, or Word.
If you know bands, groups, and running totals from classic report designers, you already know quario.
How quario lays out bandsA growing set of production-ready quario reports. Each one is a declarative definition — copy it, point it at your data, and render to HTML, PDF, Excel, or Word.
Safer than letting the model write HTML. Lighter than the heavyweight suites. More of a real engine than a PDF hack.
eval in the template engine.quario takes its name from the quarto and the quire — the folded sheet and the gathering of leaves that make a book. Whoever drafts the pages, quario does the folding.
Commercial software with readable source. Evaluate it free for as long as you like. License each production deployment when you ship, then let every user and every agent render without limit.
Agents and users are never counted. You license the deployment, not the people or the bots that use it.