Skip to content

jvarn/acroform-builder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AcroForm Builder

A macOS, Windows, and Linux desktop + web app for visually creating interactive PDF forms (AcroForms). Drag and drop field widgets onto any PDF background, configure properties, and export a fully interactive PDF compatible with Adobe Acrobat and other PDF viewers.

Features

  • Upload any PDF as a background template
  • Place form fields by dragging onto the canvas: Text, Number, Checkbox, Radio, Dropdown, Calculated, Hidden (calc holder), Static Label
  • Configure each field's appearance (border, background, transparency), typography (font, size, weight, colour), and behaviour (required, read-only, calculations)
  • Multi-select fields with Shift+Click or Cmd/Ctrl+Click — edit shared properties in one go
  • Drag-to-reorder fields in the sidebar
  • Duplicate single or multiple selected fields
  • Radio buttons grouped by name — place individual buttons anywhere on the page
  • Calculated fields using built-in functions (Sum, Mean, Min, Max, Count, Product, Median) or custom JavaScript
  • Hidden fields for intermediate multi-step calculations (invisible but participate in calc order)
  • Export to a fully-compliant interactive PDF (AcroForm)
  • Export project as JSON
  • File > Save (Cmd+S) and File > Export PDF (Cmd+E) in the native app menu
  • Desktop app via Electron (macOS, Windows, Linux)
  • Web dev mode with Vite HMR (npm run dev)

Download

Download installers for macOS (universal), Windows, or Linux (deb/AppImage) from the releases page.

Tech Stack

Layer Technology
Client React 19, Vite, TypeScript, Tailwind CSS, Zustand, react-rnd, @dnd-kit
Server Node.js, Express, better-sqlite3
PDF rendering pdfjs-dist (preview), pdf-lib (export)
Shared schema Zod (@acroform/shared workspace)
Desktop Electron
Build electron-builder

Development Setup

# Install all workspace dependencies
npm install

# Start Vite dev server + Express API concurrently (web mode)
npm run dev

Open http://localhost:5173

# Start in Electron (opens native window, connects to Vite + Express)
npm run electron:dev

Build (Desktop App)

npm run electron:build

Produces platform installers in electron/release/:

  • macOS: .dmg (universal, Apple Silicon + Intel)
  • Windows: .exe NSIS installer
  • Linux: .AppImage and .deb

CI builds for all three platforms are triggered automatically on v* tags via GitHub Actions.

Architecture

/client        React SPA
  /src/features/editor
    Editor.tsx         Top-level editor shell, save/export, IPC listener
    PdfCanvas.tsx      PDF page preview (pdfjs-dist, 1.5× scale); hosts FieldOverlays as children
    FieldOverlay.tsx   Draggable/resizable field widget (react-rnd)
    FieldList.tsx      Sidebar field list with drag-to-reorder (@dnd-kit)
    PropertiesPanel.tsx Field property editor (single & multi-select)
  /src/store/editorStore.ts  Zustand state (project, selectedFieldIds, actions)

/server        Express REST API
  /src/services/compiler.service.ts  PDF compilation (pdf-lib)
  /src/services/projects.service.ts  CRUD via better-sqlite3
  /src/db/index.ts                   SQLite connection + schema init

/shared        Zod schemas shared between client and server
  /src/schema/project.ts  All field type definitions + Project schema

/electron      Electron main process
  /src/main.ts     Starts Express (production), creates BrowserWindow, builds File menu
  /src/preload.ts  Exposes electronAPI.onMenuAction() to renderer via contextBridge

Coordinate System

Fields are stored in canvas pixels at 1.5× scale (matching pdfjs-dist rendering scale). Field overlays are positioned relative to the canvas element inside PdfCanvas, so y=0 = canvas top.

The compiler divides all coordinates by CANVAS_SCALE = 1.5 to get PDF points, then flips the Y axis (PDF_y = pageHeight - canvas_y - field_height) because PDF origin is bottom-left while the browser is top-left.

Data Flow

React UI → Zustand store → REST API (Express, default port 3001) → SQLite (projects.db)
                                                    ↘ pdf-lib (PDF export)

Prerequisites

  • Node.js 20 or later
  • npm 10 or later
Platform Minimum version
macOS Ventura (Sequoia recommended)
Windows Windows 10 x64
Linux Ubuntu 22.04+ or equivalent (x64)

Linux in a VM or container: The Electron sandbox may not work in environments without Linux user namespace support (UTM, QEMU, Docker, WSL2). If the app crashes immediately with a SIGTRAP, run it with:

acroform-builder --no-sandbox

Generating the App Icon

The icon was generated and committed at electron/buildResources/icon.icns. To regenerate it (macOS only — requires iconutil):

cd electron
npm run generate-icon

Contributing

Contributions are welcome. Please open an issue before starting large changes.

Workflow

  1. Fork the repository and clone your fork
  2. Create a branch: git checkout -b my-feature
  3. Make changes and test with npm run electron:dev
  4. Open a pull request against main

Code conventions

  • TypeScript strict mode throughout all workspaces
  • Shared data structures live in shared/src/schema/ as Zod schemas — add new field types there first
  • Client components use Tailwind CSS utility classes; avoid inline styles except for drag-region and dynamic values
  • Electron IPC uses webContents.send('menu-action', actionName) strings — add new actions to both main.ts and the relevant renderer component
  • Match the style of surrounding code; no linter is currently configured

Reporting issues

Please use GitHub Issues and include:

  • OS and version (e.g. macOS 15.3, Windows 11, Ubuntu 24.04)
  • Steps to reproduce
  • Expected vs actual behaviour
  • Browser/Electron console output if relevant

License

MIT