Skip to content

Add local PDF compression and improve PDF editing UX - #2

Merged
surajverma merged 35 commits into
masterfrom
feature/pdf-toolkit-compression
Sep 5, 2026
Merged

surajverma merged 35 commits into
masterfrom
feature/pdf-toolkit-compression

Conversation

@surajverma

@surajverma surajverma commented Sep 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

This follow-up improves the PDF Toolkit around the most common PDF workflows while keeping all processing local in the browser.

PDF compression

  • Adds three local compression modes with explicit tradeoffs
  • Lossless / structural uses bundled qpdf WebAssembly to recompress streams and PDF structure while preserving selectable text, links, forms and document structure
  • Balanced · 150 DPI uses bundled PDF.js to render each page locally and rebuild it as JPEG-backed PDF pages
  • Strong · 96 DPI uses the same local rendering path at lower resolution/stronger JPEG compression for smaller upload/email files
  • Balanced/Strong are intentionally flattened modes: selectable text, links, forms, bookmarks, accessibility structure and digital signatures are not preserved
  • Shows original size, compressed size and percentage reduction
  • Does not download a larger file when compression cannot improve the original
  • Compression is capped at 100 MB; flattened modes also have page/pixel limits for browser stability
  • Adds progress feedback while PDF.js renders pages

Browser compatibility

  • qpdf worker/runtime/WASM assets are prepared as same-origin files under public/qpdf/ before dev/build to avoid Next 16/Turbopack file:/// worker companion URLs
  • PDF.js worker is likewise prepared under public/pdfjs/
  • Generated runtime assets are not committed to Git

Merge workflow

  • Adds a Remove button for every uploaded PDF
  • Adds Clear all
  • Keeps reorder controls
  • File picker resets after selection so the same file can be re-added after removal

Editing workflow

  • Adds an explicit PDF to edit or compress selector when multiple PDFs are loaded
  • Renames the ambiguous Page operations section to Edit pages in a PDF
  • Adds inline explanations for Extract/Reorder, Delete and Rotate
  • Explains that Split every page to ZIP creates one single-page PDF per source page and does not use the page-selection field
  • Metadata editing follows the selected working PDF

Dependencies and verification

  • Adds qpdf-run for structural compression
  • Adds pdfjs-dist for reliable browser-side flattened compression
  • package-lock.json is generated through npm rather than hand-edited
  • Production audit remains clean: npm audit --omit=dev reports 0 vulnerabilities
  • CI gates high/critical production dependency advisories with npm audit --omit=dev --audit-level=high

All PDF files remain on the user's device; no upload/API service is introduced.

Copilot AI lite review requested due to automatic review settings September 5, 2026 13:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new compression feature likely cannot load its worker/WASM assets with the current URL strategy, which would cause compression to fail at runtime.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR expands the PDF Toolkit’s core workflows by adding browser-local PDF compression (qpdf/WASM) and improving multi-PDF UX so users can explicitly choose which PDF is being edited/compressed while keeping merge behavior order-based.

Changes:

  • Added qpdf-run based compression modes (lossless/balanced/strong) with size reporting and “don’t download larger output” behavior.
  • Improved multi-PDF UX: remove per file, clear all, re-add same file, and explicit “working PDF” selector for edit/compress/metadata.
  • Updated dependencies and version bump to include qpdf-run.
File summaries
File Description
src/app/pdf-toolkit/page.tsx Adds local qpdf/WASM compression and reworks the PDF selection/editing UX for multi-file workflows.
package.json Bumps app version and adds qpdf-run dependency.
package-lock.json Regenerates lockfile to include qpdf-run and version bump.
Review details
  • Files reviewed: 4/5 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/app/pdf-toolkit/page.tsx Outdated
Comment thread src/app/pdf-toolkit/page.tsx

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There are verified issues that can cause dev-time unhandled promise rejections, state update clobbering in React, and missing gitignore coverage for generated public/pdfjs/ assets.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

src/app/pdf-toolkit/page.tsx:237

  • removeFile uses setFiles(next) computed from the render-time files array. If another setFiles update is queued (e.g., a quick reorder click followed immediately by remove before React commits), this non-functional update can clobber the other update and restore stale state.
  const removeFile = async (key: string) => {
    const next = files.filter(item => fileKey(item.file) !== key);
    setFiles(next);
    setMessage('');

  • Files reviewed: 9/11 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread src/components/PwaRegistration.tsx
@surajverma
surajverma merged commit 5feda78 into master Sep 5, 2026
1 check passed
@surajverma
surajverma deleted the feature/pdf-toolkit-compression branch September 5, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants