Back to Insights
From Prompt to Template: Why I Built a Bilingual Document Engine for Corporate Workflows
katibbilingualai-toolsdocumentsmarketplaceopen-sourcecorporategcc

From Prompt to Template: Why I Built a Bilingual Document Engine for Corporate Workflows

Asking an LLM to write the same NDA every Monday is a tax. katib trades full-document generation for variable filling — 10× to 100× fewer tokens, identical output every time, bilingual EN+AR by default.

Published April 30, 2026 min read
Jasem Neaimi

Jasem Neaimi

AI Collaboration Researcher

The first time I noticed the pattern, I was generating the same one-page NDA for the third time in a month. New counterparty, same template, same clauses, same bilingual mirror. I asked Claude to draft it. Two thousand tokens out, one revision, four hundred more. A clean PDF that took another twenty minutes in Word to look print-ready. By the end of the year I would do this dozens of times — across NDAs, MoUs, service agreements, tax invoices, progress reports, and a CV refresh I couldn't bring myself to handle in Word again.

Each individual ask felt cheap. The aggregate was not. And every output looked almost right until a colleague opened it and found the bilingual columns drifting, the page break in the wrong place, or the signature block mirrored the wrong way for Arabic.

This is the document tax. Most corporate teams pay it without naming it. The fix isn't a better prompt. The fix is to stop prompting for documents at all.

The Pattern That Doesn't Scale

Here's what most people do today when they need a corporate document:

  1. Open Claude / ChatGPT / a chat interface
  2. Ask: "Write me an NDA / invoice / progress report"
  3. Pay tokens for every word the model generates
  4. Read it, tweak it, ask for revisions, pay tokens again
  5. Copy-paste into Word or Google Docs
  6. Spend twenty minutes fixing layout, fonts, page breaks, signatures
  7. Manually generate an Arabic version, fix it, mirror the layout, reconcile the bilingual gaps

The fundamental issue isn't the LLM. The LLM is fine. The issue is that you're using a generative tool to produce something that should be filled, not generated.

A standard NDA is 95% structure and 5% variables. The structure is the same every time — recitals, definitions, confidentiality clause, term, governing law, signatures. The variables are the names, dates, jurisdictions, and a handful of negotiated terms. Generating the structure on every render means re-paying for content you already had.

What I Built Instead

katib is an open-source document engine that flips the workflow.

Templates are written once, in code. They're versioned, tested, deterministic. Every render produces the same output, byte-for-byte. The LLM's role shrinks from "draft the entire document" to "fill these eight variables." Token cost drops from thousands per render to tens.

The shift looks like this:

Prompting an LLMRendering a katib template
Tokens per render2,000–5,000 (output)50–200 (variables only)
DeterminismNew prose every timeIdentical output every time
Layout fidelityMarkdown → manual cleanupPrint-grade A4 PDF, page breaks correct
Bilingual supportTranslate after, fix mirroringEN + AR ship in the same template, mirrored RTL by default
VersioningNone — each chat is a one-offEvery template versioned, every change tracked
ReuseCopy-paste from past chatskatib render legal-nda --lang ar

A single template renders the same document for the hundredth client at the same cost as the first.

A katib-rendered NDA template — print-grade A4 typography, structured sections, lorem ipsum filling every variable. The structure is fixed in code; only the bracketed fields change at render time.

What "Bilingual by Default" Actually Means

Most "bilingual" PDF tooling means: the engine renders English, you swap the strings to Arabic, you fix the layout that broke, and you publish two PDFs.

katib templates carry both languages as a primary surface. Each template ships:

  • An en.html and an ar.html rendering, both maintained by the template author
  • Proper RTL layout — Arabic columns flow right-to-left, signature blocks mirror, headers reverse, numerals localize
  • Arabic typography routed through the appropriate font pipeline (Cairo for digital body, IBM Plex Arabic for editorial, 29LT Bukra for display where the template asks for it)
  • A single katib render <recipe> --lang ar flag that produces a complete Arabic PDF — not a translation, a co-equal rendering

The same NDA template rendered in English and Arabic — section numbers mirror, the body flows right-to-left, lists reverse, headings reset to the right margin. Same template, two co-equal renderings.

This matters more in the GCC than anywhere else. A Dubai-based finance team issuing invoices needs both versions in 80% of cases. A Saudi legal team drafting MoUs ships them bilingually for the Ministry. A UAE Federal Tax Authority compliant invoice has bilingual requirements baked into the format. Treating Arabic as an afterthought means the Arabic version is always the one that breaks.

Forty-Four Packs, Today

The marketplace at jneaimi.com/katib ships forty-four packs as I write this. Eleven templates plus thirty-three components. The templates cover the recurring corporate workflows:

  • Legal: NDAs, MoUs, service agreements
  • Finance: UAE FTA-compliant tax invoices, quotes
  • Operations: Progress reports, executive summaries
  • Personal: CVs, biographical pages
  • Editorial: Long-form articles, news cover pages

Four templates from the marketplace, rendered side by side — an NDA, a tax invoice, a progress report, and a CV. Each one fills the same way: the structure is the template; only the bracketed variables change.

The components are the building blocks templates compose from — letterheads, signature blocks, multi-party signature blocks, charts, timelines, table-of-contents pages, two-column layouts, executive summary blocks, financial summary cards. Want a custom report shape your firm uses? Compose it from existing components in fifty lines of YAML. Submit it as a marketplace PR and it ships for everyone.

Templates are versioned. Components are versioned. Every install is reproducible. A pack you install today renders the same document a year from now.

You Can Build Your Own — and Brand Them

The marketplace shows what's shipped today. But katib is just as much a tool for making templates, components, and brand profiles — and the brand layer changes how every component renders.

  • /katib component new <name> opens an AI-assisted builder for new building blocks — custom signature blocks, sector-specific charts, layouts your firm uses. Submit it to the marketplace as a PR, or keep it in your local cache.
  • /katib recipe new <name> scaffolds a new template by composing existing components. Write the YAML, render the PDF.
  • Brand profiles are YAML files that set your colors, fonts, logo, author identity, and page background. Pass --brand acme and every component renders in ACME's identity. Same template, different look — without forking the template.

This matters more than it sounds. A consulting firm working with ten clients needs ten brand profiles, not ten template forks. The same NDA renders one way for the law firm, another for the client, a third for the regulator. Brands are profiles, not branches — what you don't specify inherits the domain default, so partial overrides ship cleanly.

The Architecture, Briefly

Two pieces. The engine lives at @jasemal/katib on npm. One command installs it: npx @jasemal/katib install. It's bilingual-aware, brand-aware, and produces print-grade PDFs through WeasyPrint — A4 by default, real margins, real page breaks, real OpenType ligatures for Arabic.

The marketplace lives at jneaimi.com/katib, served as a subpath of this site. Pack blobs sit on Cloudflare R2 (immutable, content-addressed by version). The registry index is Postgres on Coolify. Installing a pack is one line: katib pack install jneaimi/legal-nda. Resolution hits the registry over HTTPS, downloads the .katib-pack blob from R2 (free egress), and writes it to your local user-tier component cache.

The whole thing is deliberate in what it does not do. It doesn't have a chat interface. It doesn't have a wysiwyg editor. It doesn't ship a SaaS dashboard. The unit of work is katib render, called from a terminal or from another tool. It plays well with Claude Code or any other agent — the agent fills variables, katib renders the document.

What Stopped Me From Shipping This Sooner

I built the engine in a focused sprint. The marketplace took longer to open — not for engineering reasons, but because of the bilingual quality bar.

Rendering crisp English PDFs from HTML is a solved problem. Rendering crisp Arabic — with proper character shaping, numeral localization, RTL layout flow, mirrored components, and bilingual recipes that feel native in both languages — is not. WeasyPrint handles a lot but not everything. Arabic typography in print-grade PDFs requires opinionated decisions about which font ships with which template, how dialect markers translate to print, when to use Western vs Arabic numerals, how to handle inline English terms in Arabic prose.

Every shortcut I tried left the Arabic version visibly worse than the English. The version of katib I shipped is the one where I stopped trying to be clever and built each side of the template properly.

What This Doesn't Replace

It doesn't replace prompting an LLM for novel content. If you need a custom one-off cover letter for a unique role, ask Claude to write it — that's what generative AI is for. If you need a fresh blog post on a topic you've never covered, prompt away.

It also doesn't replace your existing document automation if you have one. If your firm has a perfectly working DocuSign + Word template stack, keep it. katib is for the workflows where you've been reaching for an LLM as a substitute for templates because templates were too expensive to build properly.

It replaces the specific failure mode where:

  • You're regenerating the same shape of document repeatedly
  • The bilingual EN+AR requirement makes existing templates painful
  • The output needs to be print-grade PDF, not Markdown or a Word file
  • You've been tolerating layout cleanup time as a cost of doing business

If three of those four describe you, katib is built for you.

How to Try It

Two commands. The engine, then a sample template:

npx @jasemal/katib install
katib pack install jneaimi/tutorial
katib render tutorial --lang ar

The PDF lands at ~/Documents/katib/. Open it. Compare it to whatever your last LLM-generated bilingual document looked like.

Browse the full catalog at jneaimi.com/katib. Source on GitHub. Marketplace submissions are open — if your team has a recurring document shape, package it once and stop re-prompting it forever.

The document tax was always optional. We just hadn't built the alternative yet.

Get new insights

Subscribe for the latest research and frameworks, delivered to your inbox.

From Prompt to Template: Why I Built a Bilingual Document Engine for Corporate Workflows