<link rel="stylesheet" href="/assets/fonts/jetbrains-mono/jetbrains-mono.css" />
All posts

How I built a lab of 13 PDF and AI tools that work together

The lab on this site came from a concrete need: I wanted a test bench for the technologies I use with clients, and I wanted it to be useful to people who work with documents every day. Today it has 13 tools — viewer, PDF editor, OCR, scanner, translation, summary, legal PDF search, AI slides and more — in seven languages. This is how I built it.

The problem and the constraints

  • Low cost: a NestJS backend on a small cloud service, no dedicated infrastructure.
  • Privacy: wherever possible, files must not leave the user's device.
  • Seven languages and SEO: every tool must be findable on Google in every language.
  • Anonymous tools: no mandatory sign-up, so protection against abuse.

Choice 1: in the browser when possible, on the server when needed

The viewer, the PDF editor (merge, split, rotate, watermark) and the first stage of OCR run entirely in the browser with pdf.js and pdf-lib: the document is never uploaded. The server only steps in when it's unavoidable: calls to AI models, heavy OCR with Tesseract, format conversions.

Choice 2: text first, then OCR

Each page is first queried for its text layer. Below 40 characters I treat it as a scan and send it to OCR; the same threshold applies in the browser and on the server, so both paths give consistent results. OCR is slow, so there's a cap of 20 pages per document.

Choice 3: limits stated, not hidden

Long documents are split into blocks for the AI. Beyond 15 blocks I'd rather truncate and tell the user than let time and cost explode on a pathological file:

// Hard cap on blocks per document: beyond it the file is
// truncated honestly instead of exploding latency and cost.
const chunks = allChunks.slice(0, this.MAX_CHUNKS); // 15
const truncated = allChunks.length > this.MAX_CHUNKS;
// "truncated" goes back to the UI: the user is told, not surprised

Choice 4: tools linked by a workspace

The real value lies in chains: scanner → OCR → translation, search → summary. That's why I added a workspace that hands one tool's result to the next without downloading and re-uploading files. I described it in detail in this article.

Choice 5: AI quotas

Anonymous tools plus calls to AI models are a dangerous mix for the budget. On top of the per-minute limit I added a daily cap per IP address and a global daily token budget, with an emergency kill switch. Without them, a single automated script could burn a month's budget in an hour.

The mistakes I learned the most from

  • My own security headers blocked my own preview. Helmet's defaults forbid showing backend responses in an iframe from another origin: I had to open a targeted exception, only on that route and only for my frontend.
  • On phones the PDF preview showed only the first page. Mobile browsers' native viewer often does that: on mobile I now render pages with pdf.js, through a proxy with a closed list of allowed domains to prevent abuse.
  • Sources must be verified live. For the legal PDF search I kept Internet Archive, Project Gutenberg, arXiv and Europe PMC; other promising sources were dropped because, when actually tested, they returned HTML pages rather than PDFs.
  • Titles in a single language. For weeks the tool pages had fixed titles and descriptions, almost all in English: the versions in other languages were effectively invisible to Google.

The result

Thirteen tools in seven languages, with prerendered pages for every language and most processing done in the browser. But the most useful result is another: a repertoire of proven solutions — PDF handling, OCR, AI quotas, safe proxies, i18n — that I reuse in client projects.


In short

Building the lab taught me three things: process in the browser everything you can, state limits instead of hiding them, and protect every resource that costs money. If you have a project that works with documents or AI, get in touch: I've probably already tackled a similar problem.

💬 Reader notes

0 notes

Write a note

Share your opinion, a suggestion or a compliment

Latest notes

No notes yet. Be the first to comment!