GigaPDF is a multi-tenant PDF editing platform with a stateless API layer, S3-compatible storage, and real-time collaboration. The system separates interactive editing (documents/elements) from persistent storage (stored documents/versions).
+------------+ +--------------+ +---------------+
| Web / Admin|----->| FastAPI API |----->| PostgreSQL |
| Mobile App | | (REST + WS) | | (data + auth) |
+------------+ +------+-------+ +---------------+
|
+---------> Redis (cache, queues)
|
+---------> S3 (document versions)
- REST API: Document CRUD, export, storage, search, billing.
- WebSocket: Real-time collaboration, cursors, element locks.
- Services: Encapsulated business logic (storage, billing, collaboration, semantic search embeddings).
- Celery: Async jobs (preview proxying, embeddings, batch operations).
- All PDF processing runs through the in-house
@qrcommunication/gigapdf-lib(read/write/edit, redaction, AcroForm, annotations, OCR, HTML/CSS→PDF via a native JS interpreter, Office↔PDF conversion, rasterisation, crypto/signatures, image codecs). No third-party PDF binary (Tesseract, poppler, LibreOffice, Ghostscript, Chromium/Playwright, mupdf, pdf-lib) is required. - The same WASM module runs in two places. In the browser it powers the live
editor (page rasterisation and direct text editing). In the Next.js API
routes (Node) it runs the heavy, privacy-sensitive operations server-side:
OCR (
/api/pdf/ocr), Office/HTML conversions (/api/office/*,/api/pdf/convert), signing, encryption, redaction and preview rendering. Documents are never sent to a third-party service. The FastAPI backend persists results and computes embeddings locally for semantic search.
- Web App: Main editor UI and user dashboard.
- Admin App: Tenant and user administration.
- Mobile App: Expo-based client for viewing and simple workflows.
- The edited page is rasterised by the engine without its text
(
renderPageNoText): the background keeps all non-text content (vector art, gradients/shadings, images, annotations) pixel-perfect. - The real text is drawn on top as live, editable text in its embedded font and true colour — there is no flattened text image and no colour mask, so editing works directly over any background (gradients included).
- Embedded fonts are served to the browser with a synthesised, valid
cmapand all required tables, so the original glyphs render 1:1 even when the embedded subset's character map is missing or corrupt. - Single-page and continuous (Word-like) views share the same
EditorCanvascomponent, so editing behaves identically. In the continuous view the focused page is a full editor; other pages are fast, read-only page bitmaps.
- Every element parsed from the PDF — text, images and vector shapes — is
addressable by a single unified engine index. Move/resize/delete are
applied in place (
transformElement/removeElement) — lossless, no image re-compression or shape re-draw. Geometry/rotation changes that can't be expressed as a pure affine fall back to redact + re-add. - Vector restyle (fill/stroke/width/dash and opacity) is baked in place
via
setPathStyle; image/element opacity viasetElementOpacity(both use a page/ExtGState). Shapes are excluded from the background raster (renderPageExcluding) and drawn as live, visible Fabric overlays, so restyling is WYSIWYG with no stale preview (same model as text). - Stacking order is baked natively via
reorderElement(op-range splice that re-emits the element's effective graphics state, so appearance is preserved). - Layers are an editor-side construct (not PDF OCGs): create/rename/reorder,
assign elements, lock/hide a whole layer (cascades to member elements). Layers
- element→layer membership are persisted per stored document via
GET/PUT /api/v1/storage/documents/{id}/layers(opaque JSONB), keyed by the element's deterministic id so they survive a reload.
- element→layer membership are persisted per stored document via
- PostgreSQL: Core data, users, tenants, permissions, metadata.
- Redis: Cache, rate limits, async job queues.
- S3-Compatible: Immutable versions of edited PDFs.
- documents: Session documents and element state during editing.
- stored_documents: Persistent saved documents in S3.
- document_versions: Version history with storage keys.
- tenants/users: Multi-tenant ownership and quotas.
- User edits a document (elements stored in the DB).
- On save, the API renders/exports and stores a version in S3.
- Metadata is updated in PostgreSQL, version history is recorded.
- Clients join a document room via WebSocket.
- Cursor and element updates are broadcast to peers.
- Element locks prevent conflicting edits.
- app/: FastAPI backend, services, models, tasks.
- apps/web: Next.js editor UI.
- apps/admin: Admin dashboard.
- apps/mobile: Expo mobile app.
- packages/: Shared UI and editor packages.
- database/: SQL bootstrap migrations and setup scripts.
- migrations/: Alembic migrations.
- PostgreSQL 17 (+ pgvector): Primary database and semantic search index.
- Redis: Cache, queue, rate limiting.
- S3: Long-term document storage.
- fastembed: Local, offline multilingual embeddings (no external API).
No third-party PDF/OCR binary (Tesseract, poppler, LibreOffice, Ghostscript, Chromium/Playwright, fontforge) is required — all PDF processing is handled by the in-house gigapdf-lib (Rust → WASM).
- Local: uvicorn + pnpm dev + local PostgreSQL/Redis.
- Prod: Containerized or Ploi-based deployment.