← All Work

PaperPilot

Browser-based PDF editor with 10+ annotation tools

Next.jsReactTypeScriptpdf.jspdf-libKonvaZustand
PDF editingCanvas UXBrowser-native apps
PaperPilot screenshot
PaperPilotshipped

What it is

A browser-based PDF editor with 10+ annotation tools — text, highlights, shapes, freehand drawing, sticky notes, stamps, signatures, images, and watermarks. No plugins, no subscriptions, runs entirely in the browser.

The Problem

Existing PDF editors are either desktop-only, require paid subscriptions, or lack modern web-native features. A lightweight, open-source web-based PDF editor that runs entirely in the browser would make document annotation accessible to anyone with a web browser.

My Role

Built the complete application from scratch — PDF rendering with pdf.js, annotation layer with Konva canvas, state management with Zustand (with undo/redo via zundo), export/import with pdf-lib, and responsive UI with Next.js App Router.

Approach

Uses pdf.js for rendering, Konva + react-konva for the annotation canvas layer, pdf-lib with pdf-lib/fontkit for modification and export with custom fonts, and Zustand with zundo for state management with undo/redo. Architecture separates rendering, annotation, and export concerns cleanly so each can be modified independently. Supports export, print, and share via Web Share API.

Hardest Decision

Choosing Konva over SVG for the annotation layer. Canvas-based rendering performs better with many annotations and provides smoother freehand drawing, but requires careful handling of hit detection and z-order management that SVG provides for free. The tradeoff was worth it for the performance characteristics.

Status

Live at paperpilot.ochiengpaul.com. Full annotation toolkit with 10+ tools, export, print, and Web Share API support. Open source on GitHub.

What I'd Change

Would implement collaborative editing with CRDTs for real-time multi-user annotation, and add server-side PDF processing for features that require full document re-rendering.

Stack

Next.jsReactTypeScriptpdf.jspdf-libKonvaZustand