π‘ Inspiration
On 27 March, the European Commission confirmed a breach. 350 gigabytes. Confidential documents. Contracts. Cloud infrastructure. The files were on a server. That was enough.
In Switzerland, a data breach doesn't just fine your company. It fines you up to CHF 250,000, personally.
Bounds has no server. Nothing to breach.
π GoCalma's challenge | AI-Powered Privacy Redaction: Own Your Data
Why Bounds
- Data that stays in bounds β nothing crosses the boundary of your device. The whole product promise is that your files never go "out of bounds" to a server.
- Setting bounds on what's visible β redaction is literally drawing a box (a bound) around sensitive information and limiting what can be seen.
What it does
- βοΈ Fully offline β works in airplane mode after first load
- π§ Hybrid AI detection β multilingual BERT NER + 40+ regex patterns, all local
- π Auto-detects PII β names, addresses, IBANs, SSNs, emails, phones, passports, DOB, health data, credit cards
- π 8 UI + document languages β EN, DE, FR, IT, ES, PT, NL, PL
- π· OCR for scanned PDFs β Tesseract.js with spatial word reconstruction for form layouts
- π€ Face detection β universal browser face detection with TinyFaceDetector fallback
- β¬ True redaction β pages rasterised to image, original text layer removed entirely
- ποΈ Reversible encryption β AES-256-GCM vault + .key file, restore original values any time
- π Audit trail β timestamped JSON report, no document content included
- π¦ Batch processing β drop multiple PDFs, processed sequentially with default options
GenAI Integration
The Problem: Organisations want to use ChatGPT, Claude, or custom LLMs to analyse documents but sending unredacted files violates GDPR/HIPAA and exposes data to training pipelines.
The Solution: Bounds sits upstream of GenAI workflows:
Sensitive PDF β Bounds (local redaction) β Redacted PDF β Safe to send to: ββ AI provider for summarisation ββ Custom RAG pipelines ββ Your platform
Generative AI components running entirely in the browser:
- BERT multilingual NER (430MB ONNX) β discriminative AI for named entity detection across 104 languages
- LaMini-Flan-T5-77M (77MB) β generative AI produces plain-language privacy risk summaries: "This document contains 3 names, 2 addresses and 1 IBAN. Risk level: High."
ποΈ How I Built It
The entire pipeline runs in WebAssembly inside the browser. No backend, no server, no environment variables.
Architecture:
@xenova/transformersβ quantised multilingual BERT NER (~430MB ONNX) in Web Worker, cached in IndexedDB after first downloadtesseract.jsβ OCR for scanned PDFs with spatial row reconstruction to handle two-column form layoutspdfjs-distβ text extraction with precise bounding boxespdf-libβ rasterises redacted pages to PNG, rebuilds clean PDF with no text layer- Web Crypto API β AES-256-GCM reversible encryption vault, no library needed
- React 18 + Tailwind + Vite β 4-step wizard UI
- Deployed as fully static site on Vercel
Hybrid detection: regex runs in parallel with NER for structured identifiers (IBANs, credit cards, passports, phone numbers) with deduplication between layers. 40+ regex rules with per-pattern confidence thresholds and label-context lookbehind for form-style documents.
π§ Challenges I Ran Into
- WASM + SharedArrayBuffer: Requires both
Cross-Origin-Opener-Policy: same-originandCross-Origin-Embedder-Policy: require-corpheaders. Easy to miss, hard to debug when it fails silently. - Bounding box alignment: Mapping pdfjs extraction coordinates to pdf-lib render coordinates required careful calibration across different PDF structures.
- OCR form layout: Two-column forms get read column-by-column by Tesseract, so "Emergency contact:" and "Jean Dubois" end up 20 lines apart in the text stream, breaking label-context regex. Fixed by reconstructing reading order from word bounding box positions.
- Progressive loading: Fitting a 430MB model into a UX that doesn't feel broken required progressive loading states, a network request transparency panel, and IndexedDB caching so the download only happens once.
- Face detection cross-browser: Chrome's Shape Detection API requires an experimental flag. Replaced with a universal fallback using TinyFaceDetector via ONNX, so face blurring works in all browsers without flags.

Log in or sign up for Devpost to join the conversation.