Skip to content

Repository files navigation

PDF Chisel

PDF Chisel

Cross-platform desktop PDF editor with WYSIWYG text and image editing.
Fully offline — no cloud, no subscriptions, no account required.


Download

Pick the installer for your operating system:

Operating SystemDownloadNotes
WindowsDownload for WindowsRun the .exe installer and follow the prompts
macOS (Apple Silicon)Download for Mac (M1/M2/M3)Open the .dmg, drag PDF Chisel to Applications
macOS (Intel)Download for Mac (Intel)Open the .dmg, drag PDF Chisel to Applications
LinuxDownload for LinuxMake executable: chmod +x *.AppImage, then run

Not sure which Mac you have? Click the Apple menu () → About This Mac. If the chip says "Apple M1" / "M2" / "M3" etc., choose Apple Silicon. Otherwise choose Intel.

All downloads are also available on the Releases page.


Features

  • Edit text directly on the PDF — double-click any text to modify it
  • Replace images — swap embedded images with your own PNG or JPEG files
  • Undo / Redo — full edit history with Ctrl+Z / Ctrl+Shift+Z
  • Multi-page — navigate, zoom, and edit any page
  • Save & Save As — Ctrl+S overwrites; Ctrl+Shift+S saves a copy
  • Thumbnails — sidebar page previews for quick navigation
  • 100% offline — no internet connection needed, your files never leave your computer
  • Open source — MIT licensed

For Developers

Built with Electron, PDFium (native N-API addon), and TypeScript.

Quick Start

npm install
npm start

Development mode (DevTools open):

npm run dev

Build

# Compile TypeScript only
npm run build
# Build native PDFium addon (requires node-gyp and PDFium headers)
npm run build:native
# Package for current OS
npm run pack
# Create distributable installer
npm run dist

Packaging Targets

PlatformFormatNotes
WindowsMSI (WiX) + NSISelectron-wix-msi for enterprise deployment
macOSDMGHardened runtime, notarised
LinuxAppImageUniversal, no-install

Architecture

src/
├── main/ # Electron main process
│ ├── index.ts # App lifecycle, window creation, CSP enforcement
│ ├── ipc-handlers.ts # IPC handler registration (typed, validated)
│ └── pdfium.ts # PdfiumEngine façade (wraps native addon)
├── preload/ # Preload bridge (contextBridge → window.api)
│ └── index.ts
├── renderer/ # UI (no Node/Electron access)
│ ├── index.html # Document shell with toolbar, canvas viewer
│ ├── styles.css # Dark theme, canvas, overlays
│ └── app.ts # Viewer, zoom/pan, editing, undo/redo
└── shared/ # Types, constants, IPC schema shared across processes
├── constants.ts
└── ipc-schema.ts
native/
└── pdfium/ # C++ N-API addon wrapping PDFium
├── binding.gyp
└── src/

PDFium Engine

The rendering and editing engine is PDFium (Chromium's PDF library), exposed to Node.js via a native N-API addon. The PdfiumEngine TypeScript façade manages document handles, validates inputs, normalises errors, and provides typed async methods.

Key features:

  • Canvas rendering: Pages rendered to RGBA bitmaps via FPDF_RenderPageBitmap
  • LRU bitmap cache: Bounded by MAX_BITMAP_CACHE_BYTES (256 MB default)
  • Render queue: Concurrent renders limited by RENDER_CONCURRENCY_LIMIT
  • Object inspection:listPageObjects returns text/image bounding boxes
  • Text editing:editTextObject modifies glyph content via PDFium edit API
  • Image replacement:replaceImageObject swaps embedded images (PNG/JPEG)
  • Save:FPDF_SaveAsCopy serialisation with dirty-state tracking

Security Model

LayerProtection
nodeIntegrationDisabled — renderer has no Node access
contextIsolationEnabled — preload runs in isolated context
sandboxEnabled — OS-level renderer sandboxing
CSPEnforced via response headers and meta tag
IPCTyped schema; channel allow-list; unknown rejected
NavigationBlocked; window.open denied
Single instanceSecond launch focuses existing window
OfflineNo network calls; auto-update disabled by default

Packaging & Distribution

Build Installers

# Build for current platform
npm run dist
# Build for specific platform
npm run dist:win # Windows NSIS installer
npm run dist:mac # macOS DMG
npm run dist:linux # Linux AppImage

Installers are written to the release/ directory.

Windows MSI (Enterprise)

For enterprise environments requiring MSI packages:

# 1. Build unpacked app first
npm run pack
# 2. Compile MSI (requires WiX Toolset v3)
npm run build:msi

Prerequisites: Install WiX Toolset v3 and ensure the WIX environment variable is set or WiX bin/ is on PATH.

Native Addon in Packaged Builds

The native PDFium addon (pdfium.node + shared library) is automatically extracted from the asar archive via asarUnpack. The addon loader in src/main/pdfium.ts detects packaged mode (app.isPackaged) and resolves the path to app.asar.unpacked/native/pdfium/build/Release/.

Code Signing & Notarization

Windows (Authenticode)

Set the following environment variables before running npm run dist:win:

VariableDescription
CSC_LINKPath to .pfx certificate file (or base64-encoded)
CSC_KEY_PASSWORDCertificate password
WIN_CSC_LINK(optional) Override for Windows-specific cert

electron-builder will sign the EXE automatically when these are set.

macOS (Apple Notarization)

Set the following environment variables:

VariableDescription
CSC_LINKPath to .p12 Developer ID certificate (or base64)
CSC_KEY_PASSWORDCertificate password
APPLE_IDApple ID email for notarization
APPLE_APP_SPECIFIC_PASSWORDApp-specific password (generate at appleid.apple.com)
APPLE_TEAM_ID10-character Team ID from developer.apple.com

The build uses build/entitlements.mac.plist which grants:

  • com.apple.security.cs.allow-jit — required by V8/Chromium
  • com.apple.security.cs.allow-unsigned-executable-memory — required by Electron
  • com.apple.security.cs.disable-library-validation — required for the prebuilt PDFium shared library
Linux

No code signing is typically required for AppImage distribution. For package managers (deb, rpm), GPG signing can be configured separately.

CI/CD Notes

  • Store signing certificates as encrypted secrets in your CI system (GitHub Actions, Azure DevOps, etc.)
  • Never commit .pfx, .p12, or password files to the repository
  • The publish field in package.json is set to null (auto-update disabled). Set it to a GitHub/S3/generic provider when ready to enable auto-updates.

License

MIT

About

Offline desktop PDF editor built with Electron and PDFium. Edit text and replace images in-place. Windows, macOS, and Linux.

Topics

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages