Siddharth-Khattar/redacta
Free AI-powered PDF redaction and pseudonymisation tool. Permanently redact or de-identify PII in text and images. 100% client-side, BYOK, open source. GDPR/HIPAA/CCPA compliant.
Redacta
AI-powered PDF redaction and pseudonymisation, entirely in your browser.
Describe what to redact in plain language. AI identifies it. MuPDF removes it permanently.
Your documents never leave your device.
How It Works
flowchart LR
A["Upload PDF"] --> B["Describe what\nto redact"]
B --> C["AI identifies\ntargets"]
C --> D["MuPDF applies\nredactions"]
D --> E["Download\nredacted PDF"]
style A fill:#1c1c20,stroke:#d9534f,color:#e2dfd8
style B fill:#1c1c20,stroke:#d9534f,color:#e2dfd8
style C fill:#1c1c20,stroke:#d9534f,color:#e2dfd8
style D fill:#1c1c20,stroke:#d9534f,color:#e2dfd8
style E fill:#d9534f,stroke:#d9534f,color:#fff
- Upload a PDF via drag-and-drop or file picker
- Describe what to redact in plain language (e.g. "all personal names and phone numbers")
- AI analyses every page and identifies exact text matches and sensitive images
- Choose to permanently redact (black out) or pseudonymise (replace with realistic fakes)
- Download the redacted document with original formatting preserved
Everything happens client-side. The PDF is processed by MuPDF compiled to WebAssembly, and AI providers are called directly from your browser using your own API key. No backend. No server. No data leaves your machine.
Features
Redaction & Pseudonymisation
- Natural language redaction : describe what to censor, not where it is
- Pseudonymisation mode : replace real PII with realistic fictional alternatives (names, addresses, IDs) instead of blacking out, preserving document readability
- Permanent or visual : irreversible text destruction or black-box overlays
- Image redaction : detect and redact photos, signatures, logos, and screenshots embedded in PDFs with configurable fill colours and labels
AI Models
- Multi-provider support : bring your own Gemini or OpenAI API key
- 5 models : Gemini 2.5 Flash, 3.0 Flash, 3.1 Pro · GPT-5.4, GPT-5.4 Mini
- Configurable thinking depth : minimal to high reasoning for complex documents
- Live cost estimation : token counts and USD cost displayed after each run
Workspace
- Split-pane viewer : original and redacted PDFs side by side, resizable
- Post-processing controls : adjust highlight colours, image fill, and label visibility after redaction without re-running AI
- Dark & light themes : respects system preference, toggleable
- Per-provider key management : separate API keys for each provider, stored locally
Supported Models
| Model | Provider | Thinking Levels | Best For |
|---|---|---|---|
| Gemini 2.5 Flash | Low · Medium · High | Fast, cost-effective redaction | |
| Gemini 3.0 Flash | Minimal · Low · Medium · High | Balanced speed and accuracy | |
| Gemini 3.1 Pro | Low · Medium · High | Complex documents, highest accuracy | |
| GPT-5.4 | OpenAI | Low · Medium · High | High-quality reasoning |
| GPT-5.4 Mini | OpenAI | Low · Medium · High | Fast OpenAI alternative |
Pricing (per million tokens)
| Model | Input | Output | Thinking |
|---|---|---|---|
| Gemini 2.5 Flash | $0.15 | $0.60 | $0.60 |
| Gemini 3.0 Flash | $0.50 | $3.00 | $3.00 |
| Gemini 3.1 Pro | $2.00 | $12.00 | $12.00 |
| GPT-5.4 | $2.50 | $15.00 | $15.00 |
| GPT-5.4 Mini | $0.75 | $4.50 | $4.50 |
Prices fetched live from OpenRouter with a 6-hour cache. Falls back to bundled defaults if unavailable.
Quick Start
Prerequisites
- Bun (or Node.js 18+)
- A Gemini API key and/or OpenAI API key
Run locally
make setup # Install dependencies
make dev # Start dev server (http://localhost:5173)Enter your API key when prompted.
Production build
make build # TypeScript check + production build
make preview # Build + serve locallyArchitecture
graph TD
subgraph Browser["Browser (client-side only)"]
UI["React 19 + Vite 6"]
subgraph Engine
PDF["MuPDF WASM\nText extraction +\nimage detection +\nredaction"]
AI["Provider SDK\nGemini + OpenAI\nStreaming + retry"]
PRC["Pricing module\nOpenRouter + fallback"]
end
UI --> Engine
end
AI -->|"HTTPS"| GEMAPI["Gemini API"]
AI -->|"HTTPS"| OAIAPI["OpenAI API"]
PRC -->|"HTTPS"| ORAPI["OpenRouter API"]
Browser -->|"Static files"| HOST["Any Static Host"]
style Browser fill:#1c1c20,stroke:#30303a,color:#e2dfd8
style Engine fill:#222228,stroke:#30303a,color:#e2dfd8
style UI fill:#222228,stroke:#30303a,color:#e2dfd8
style PDF fill:#222228,stroke:#d9534f,color:#e2dfd8
style AI fill:#222228,stroke:#4285f4,color:#e2dfd8
style PRC fill:#222228,stroke:#30303a,color:#e2dfd8
style GEMAPI fill:#4285f4,stroke:#4285f4,color:#fff
style OAIAPI fill:#10a37f,stroke:#10a37f,color:#fff
style ORAPI fill:#30303a,stroke:#30303a,color:#e2dfd8
style HOST fill:#30303a,stroke:#30303a,color:#e2dfd8
The entire application compiles to static files that can be served by any static hosting provider. There is no server-side code.
Privacy & Security
| Concern | How it's handled |
|---|---|
| PDF content | Processed in-browser via WASM. Never uploaded anywhere. |
| API keys | Stored per-provider in localStorage. Sent only to the respective AI provider. |
| AI requests | Direct browser-to-API calls. No proxy, no middleman. |
| Redacted output | Exists only in browser memory until downloaded. |
| Analytics / tracking | None. Zero telemetry. |
| CSP | Strict Content-Security-Policy. Only allows Gemini API and OpenRouter. |
| Security headers | X-Frame-Options: DENY, nosniff, strict-origin-when-cross-origin referrer policy. |
Development
Commands
| Command | Description |
|---|---|
make setup |
Install dependencies |
make dev |
Dev server with hot reload |
make build |
TypeScript check + production build |
make preview |
Build + preview production bundle |
make format |
Auto-format with Biome |
make lint |
TypeScript + Biome checks |
make check |
Format + lint (full quality gate) |
make clean |
Remove node_modules and dist |
Tech Stack
| Layer | Technology |
|---|---|
| Framework | React 19 |
| Build | Vite 6 |
| Language | TypeScript 5.7 |
| Styling | Tailwind CSS 4 |
| Animation | Motion (Framer Motion) |
| PDF Engine | MuPDF 1.27 (WASM) |
| AI Providers | Google GenAI SDK, OpenAI (HTTP) |
| Routing | Wouter |
| Icons | Lucide React |
| Lint / Format | Biome |
| Hosting | Any static host (Vercel, Netlify, Cloudflare Pages, etc.) |
Project Structure
frontend/
├── public/
│ ├── brand/ Icon + lockup SVGs (dark, light, transparent)
│ ├── favicon.svg Browser tab icon
│ ├── apple-touch-icon.png iOS home screen icon
│ ├── og-image.png Social sharing preview (1200×630)
│ └── robots.txt Crawler directives
├── src/
│ ├── engine/
│ │ ├── types.ts Shared types, error class, image/redaction settings
│ │ ├── pdf.ts MuPDF WASM: text extraction, image detection, redaction
│ │ ├── orchestrator.ts Pipeline: extract → identify → redact → cost
│ │ ├── pricing.ts OpenRouter pricing fetch + 6-hour cache
│ │ ├── providers/
│ │ │ ├── types.ts Provider interface and model definitions
│ │ │ ├── registry.ts Model catalog and provider factory
│ │ │ ├── shared.ts Shared prompt building and response parsing
│ │ │ ├── gemini.ts Google Gemini streaming client + retry
│ │ │ └── openai.ts OpenAI HTTP client + retry
│ │ └── prompts/
│ │ ├── index.ts Prompt selector (redaction vs pseudonymisation)
│ │ ├── redaction.ts System prompt for PII identification
│ │ └── pseudonymisation.ts System prompt for PII replacement
│ ├── hooks/
│ │ └── useProviderKeys.ts Per-provider localStorage key management
│ ├── api/
│ │ └── redaction.ts Adapter: engine to UI contract
│ ├── lib/
│ │ ├── pdf-store.ts IndexedDB PDF persistence across routes
│ │ └── utils.ts Shared utilities (cn, etc.)
│ ├── components/
│ │ ├── Header.tsx Navigation, Ko-fi, GitHub link, theme toggle
│ │ ├── ApiKeyModal.tsx Multi-provider API key management
│ │ ├── PromptPanel.tsx Prompt input, model/mode/thinking selectors
│ │ ├── PdfPanel.tsx PDF viewer (iframe-based)
│ │ ├── ProcessingPanel.tsx Progress indicator with scan animation
│ │ ├── ResultPanel.tsx Results + post-processing controls
│ │ ├── RedactionWorkspace.tsx Split-pane layout orchestration
│ │ ├── DownloadBar.tsx Download controls
│ │ ├── RedactaLogo.tsx SVG logo component
│ │ ├── ScanOverlay.tsx Animated scan line effect
│ │ ├── hooks/
│ │ │ ├── use-screen-size.ts Responsive breakpoint detection
│ │ │ └── use-debounced-dimensions.ts Debounced resize handling
│ │ └── ui/
│ │ └── pixel-trail.tsx Interactive cursor trail effect
│ ├── pages/
│ │ ├── LandingPage.tsx Hero, feature pills, upload CTA, trust marquee
│ │ └── WorkspacePage.tsx Workspace orchestration
│ ├── App.tsx Router, theme, API key modal
│ ├── index.css Tailwind theme tokens (dark + light)
│ └── main.tsx Entry point
├── index.html Meta tags, structured data, noscript fallback
├── vite.config.ts
└── package.json
Makefile Dev workflow commands
License
MIT · Siddharth Khattar, 2026