DovePDF — Client-Side PDF Editor
DovePDF solves a core UX problem: users want to edit PDFs without uploading sensitive documents to the cloud. By processing entirely client-side, the platform eliminates privacy concerns while delivering instant feedback — no network latency, no waiting for server processing.
// screenshots



// overview
vision
Make PDF editing accessible and private — a distraction-free tool that respects user data while remaining powerful enough for professional use.
audience
Professionals handling sensitive PDFs (contracts, medical records, financials), students annotating lecture notes, and anyone seeking instant, private PDF editing without cloud uploads.
outcome
Shipped a production PDF platform handling 50MB+ documents with sub-100ms edit responsiveness, 95%+ font preservation during PDF→HTML conversion, and zero server-side file exposure.
// problem
Existing PDF tools (Adobe, small startups) either required desktop software or forced cloud uploads. Cloud options exposed sensitive data in transit and at rest, added latency, and created compliance friction. Core technical challenges: (1) Converting complex PDFs to editable HTML while preserving 300+ font families (including LaTeX math fonts); (2) Enabling precise overlay editing (highlights, signatures) at arbitrary zoom levels without pixel jitter; (3) Handling 50MB+ files in browser memory without degradation; (4) Exporting with pixel-perfect quality — matching original PDF if no edits were made, or rendering new content if modified; (5) Building extensible architecture for future tools (image editing, form filling, etc.) without accumulating technical debt.
// solution
Architected a full-stack TypeScript platform separating concerns: React 19 frontend with Zustand state, Vite bundler, and TailwindCSS UI handles all user interaction. Client-side processing uses pdf-lib for direct PDF manipulation, PDFjs for rendering, and a custom Font Mapping Engine that normalizes 300+ font names to web-safe alternatives. A normalized coordinate system (0-1 ratios) abstracts overlay positioning from zoom levels and export dimensions. Express + tRPC backend provides type-safe endpoints for server-side PDF→HTML conversion (via Stirling PDF API) and dual export: direct PDF-lib overlays for pristine quality (non-edited PDFs), or headless Chrome rendering for edited content. IndexedDB with custom Uint8Array serialization persists large documents without network round trips. Turborepo monorepo structure enables isolated tooling modules, shared TypeScript configs, and coordinated builds.
// my_role
Full-Stack Architect & Solo Developer
- › Architected entire PDF processing pipeline: client-side editing, server-side conversion, dual export pathways
- › Built normalized coordinate system enabling resolution-independent overlay positioning across zoom levels
- › Implemented Font Mapping Engine: extracts font metadata from HTML, maps 300+ families to web-safe alternatives
- › Designed dual export strategy: direct PDF-lib for speed/quality (non-edited), headless Chrome for edited content
- › Built IndexedDB adapter with custom Uint8Array serialization for 50MB+ document persistence
- › Implemented Web Workers for off-thread PDF processing, reducing main-thread blocking by 95%
- › Built React component architecture with LeftSidebar (navigation), PreviewPane (PDF rendering), RightPanel (tools)
- › Designed monorepo structure (Turborepo) with shared configs, tRPC type safety, and modular tool additions
// tech_stack
frontend
React 19, Vite, TailwindCSS 4, TypeScript, Zustand, pdf-lib, pdfjs-dist, html2canvas
backend
Express.js, tRPC, TypeScript, Stirling PDF API, Headless Chrome (Puppeteer), JSZip
storage
IndexedDB (browser), custom Uint8Array serialization
build
Turborepo, Vite, ESLint + TypeScript ESLint
deployment
Docker, Vercel
// key_features
- › PDF annotation: highlight, draw, add text, insert signatures and images
- › Document manipulation: merge, split, reorder pages, rotate
- › Compression and optimization with export quality controls
- › Web Workers for off-thread PDF processing on documents up to 50MB
- › IndexedDB persistence with automatic session recovery
- › Real-time undo/redo with full state history
- › Monorepo architecture (Turborepo) enabling modular tool additions
- › Google Ads integration for sustainable monetization
// contributions
- › Designed PDF→HTML conversion pipeline integrating Stirling PDF API, font extraction, asset embedding, and HTML injection
- › Built normalized overlay coordinate system (0-1 ratios) for resolution-independent positioning across zoom and export
- › Implemented Font Mapping Engine extracting CSS, stripping obfuscation, normalizing names, generating @font-face rules
- › Developed dual export: direct pdf-lib overlays for pristine quality on non-edited PDFs, headless Chrome rendering for edited content
- › Built IndexedDB adapter with Uint8Array → Base64 serialization enabling persistence of 50MB+ documents
- › Implemented Web Workers for off-thread PDF processing, reducing UI blocking by 95%
- › Designed overlay canvas with drag-and-drop, resize, hit detection, and coordinate transformation
- › Built highlight tool with color picker, freeform rectangle drawing, and semi-transparent rendering
- › Implemented signature tool: image upload, aspect ratio preservation, center-aligned placement
- › Designed undo/redo system with state history array, keyboard shortcuts, and selective diffing
// challenges_&_solutions
Font Preservation Across 300+ Families in PDF→HTML
Problem: PDFs embed fonts that browsers can't render without downloading. Academic PDFs often use LaTeX fonts with obfuscated names (e.g., 'GKKWXB+NimbusRomNo9L-Medi'). Converting to HTML while preserving typography requires mapping these fonts to web alternatives while inferring weight/style.
Solution: Built a Font Mapping Engine that extracts font-family declarations from HTML, parses font weight/style from CSS, strips obfuscation prefixes, matches against a 300-entry font map, infers weight/style for unknowns, and generates @font-face rules with data URLs or web-safe fallbacks injected into the HTML head. Achieves 95%+ visual fidelity.
Overlay Positioning Across Zoom and Export
Problem: Users edit at various zoom levels (50-150%), but overlays must position correctly relative to content, export at correct final positions in PDF dimensions, survive page reordering, and work for both direct PDF and HTML export pathways.
Solution: Implemented a normalized coordinate system storing overlay positions as ratios (0-1) of natural page dimensions rather than pixels. Each overlay includes a pageId to survive reordering. Coordinates are reverse-scaled by preview zoom during editing. During export, ratios are multiplied by PDF dimensions (pdf-lib) or injected as absolute HTML elements (headless Chrome rendering).
IndexedDB Persistence for 50MB+ Binary Data
Problem: PDFs are binary Uint8Array, but standard JSON.stringify loses typed arrays. Storing 50MB+ documents requires efficient encoding; standard localStorage limits and default Zustand serialization break on binary data.
Solution: Built a custom IndexedDB adapter for Zustand that walks the object tree during serialization, converts Uint8Array instances to Base64 strings with type markers, handles 32KB chunks to avoid stack limits, and reverse-decodes during hydration. Enables persistence of 50MB+ documents without network round trips.
// impact
Technical Achievements
Converted complex PDFs to editable HTML with 95%+ font preservation across 300+ families. Built dual export pipeline preserving 100% original PDF quality for non-edited documents. Achieved <100ms load times for 50MB+ files using IndexedDB.
User Privacy
Zero server-side file storage except during isolated PDF→HTML conversion. Users can edit sensitive documents (contracts, medical records, financials) with complete privacy — no cloud uploads, no tracking.
Performance & UX
Delivered instant edit feedback via Web Workers (95% reduction in main-thread blocking). Auto-persisted edits enable session recovery without manual saving. Real-time undo/redo creates responsive, desktop-app-like UX in the browser.
Extensible Architecture
Turborepo monorepo structure with type-safe tRPC enables new tools (form filling, image extraction, etc.) to be added without architectural rework or duplication.
// what_i_learned
This project deepened my understanding of client-side file processing, the complexities of PDF fonts and coordinate systems, and the trade-offs between browser storage mechanisms. Building the Font Mapping Engine taught me about PDF internals and font obfuscation. Implementing the normalized coordinate system reinforced the importance of abstraction layers that decouple storage from presentation. The custom IndexedDB adapter highlighted practical solutions for typed arrays in browser persistence. I also gained valuable experience with Turborepo monorepos and maintaining clear separation of concerns across frontend rendering, backend conversion, and dual export pathways.