Skip to content

Implement PDF Knife: Client-side PDF manipulation web app#1

Merged
Ghostwillower merged 6 commits intomainfrom
copilot/build-pdf-knife-web-app
Dec 8, 2025
Merged

Implement PDF Knife: Client-side PDF manipulation web app#1
Ghostwillower merged 6 commits intomainfrom
copilot/build-pdf-knife-web-app

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Dec 8, 2025

Built a vanilla JS web application for merging, reordering, rotating, and editing PDFs entirely in the browser with no server dependencies.

Implementation

Core Architecture

  • index.html - Structure with upload controls and page grid container
  • style.css - Responsive grid layout with drag-and-drop visual feedback
  • script.js - Page management using unified array: {id, sourceIndex, pageNumber, rotation, pdfDoc}

Libraries (local)

  • pdf.js (ES module) - Canvas-based thumbnail rendering
  • pdf-lib (UMD) - PDF assembly and export

Key Features

  • Multi-PDF upload with aggregated page view
  • HTML5 native drag-and-drop for reordering
  • CSS transform for rotation preview, setRotation() for actual PDF modification
  • copyPages() workflow: load → reorder → rotate → assemble → download

Technical Details

ES module integration:

// Import pdf.js as module
import * as pdfjsLib from './lib/pdf.min.mjs';

// Access pdf-lib from window (loaded via script tag)
const { PDFDocument, degrees } = window.PDFLib;

Page state management maintains source references for later assembly:

pages = [{
  id: 0,
  sourceIndex: 0,        // Which uploaded PDF
  pageNumber: 1,         // Original page number
  rotation: 90,          // Current rotation
  pdfDoc: PDFDocument,   // Source document reference
  thumbnail: Canvas      // Rendered preview
}]

Screenshots

Empty state:
Empty state

Working with pages:
Pages loaded

Rotation applied:
After rotation

Page deletion:
After deletion

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • cdnjs.cloudflare.com
    • Triggering command: /usr/bin/curl curl -L -o pdf.min.js REDACTED (dns block)
  • unpkg.com
    • Triggering command: /usr/bin/curl curl -L -o pdf.min.js REDACTED (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

Build a client-side web app called “PDF Knife” that can upload multiple PDFs, display page thumbnails, allow drag-and-drop reordering, page deletion, and rotation, and export a new combined PDF.
Requirements:

Use vanilla HTML/CSS/JS (no framework).

Use pdf.js for rendering thumbnails and pdf-lib for assembling the output PDF.

After uploading 1+ PDFs, load each using PDFDocument.load, generate thumbnails with pdf.js, and create a unified “pages” array containing objects: {id, sourceIndex, pageNumber, rotation, pdfDoc}.

Show all pages in one scrollable grid; each page card shows the thumbnail, page number, delete button, and rotate button.

Implement drag-and-drop reordering with native HTML5 DnD. Updates must reorder the pages array.

Clicking rotate updates rotation by +90° and visually rotates the thumbnail using CSS.

Delete removes the page object from pages array and re-renders.

“Download PDF” button creates a new PDFDocument, copies pages from their source PDF via copyPages, applies rotation, and exports as output.pdf using a browser download.

All processing must be client-side only; no backend.

Include a simple clean UI (top bar with Upload, Clear All, Download PDF).

Write all code in separate files: index.html, style.css, script.js.

Minimize dependencies and keep the UI minimal and modern.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 5 commits December 8, 2025 19:59
Co-authored-by: Ghostwillower <153353690+Ghostwillower@users.noreply.github.com>
Co-authored-by: Ghostwillower <153353690+Ghostwillower@users.noreply.github.com>
Co-authored-by: Ghostwillower <153353690+Ghostwillower@users.noreply.github.com>
Co-authored-by: Ghostwillower <153353690+Ghostwillower@users.noreply.github.com>
Co-authored-by: Ghostwillower <153353690+Ghostwillower@users.noreply.github.com>
Copilot AI changed the title [WIP] Build client-side web app for PDF Knife Implement PDF Knife: Client-side PDF manipulation web app Dec 8, 2025
Copilot AI requested a review from Ghostwillower December 8, 2025 20:14
@Ghostwillower Ghostwillower marked this pull request as ready for review December 8, 2025 20:22
Copilot AI review requested due to automatic review settings December 8, 2025 20:22
@Ghostwillower Ghostwillower merged commit 717554d into main Dec 8, 2025
@Ghostwillower Ghostwillower deleted the copilot/build-pdf-knife-web-app branch December 8, 2025 20:22
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements PDF Knife, a client-side web application for manipulating PDFs (merging, reordering, rotating, and deleting pages) entirely in the browser without server dependencies.

Key Changes:

  • Created a vanilla JavaScript web app using pdf.js for rendering thumbnails and pdf-lib for PDF assembly
  • Implemented HTML5 drag-and-drop for page reordering with visual feedback
  • Added page rotation (90° increments) with CSS transforms for preview and pdf-lib for actual PDF modification

Reviewed changes

Copilot reviewed 6 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
index.html Defines the app structure with navbar controls and page grid container
style.css Provides responsive grid layout with drag-and-drop styling and rotation classes
script.js Implements core functionality: PDF loading, thumbnail rendering, drag-and-drop, rotation, and export
package.json Declares dependencies for pdf.js and pdf-lib libraries
README.md Documents features, installation, usage, and technical architecture
USAGE.md Provides quick start guide and troubleshooting tips
.gitignore Excludes node_modules and package-lock.json

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +79 to +80
thumbnail: thumbnail,
pdfjsPage: page
Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

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

The pdfjsPage property is stored in each page object but is never used in the codebase. This stores potentially large objects in memory unnecessarily. Consider removing this property unless it's needed for future functionality.

Suggested change
thumbnail: thumbnail,
pdfjsPage: page
thumbnail: thumbnail

Copilot uses AI. Check for mistakes.
/* Pages Grid */
.pages-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
Copy link

Copilot AI Dec 8, 2025

Choose a reason for hiding this comment

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

[nitpick] The magic number 200px for minimum card width lacks context. Consider defining this as a CSS custom property (e.g., --card-min-width: 200px) at the root level for easier maintenance and consistency with the responsive breakpoint at line 267 which uses 150px.

Copilot uses AI. Check for mistakes.
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.

3 participants