{"id":47634892,"url":"https://github.com/viveknaskar/pdf-kit","last_synced_at":"2026-04-02T00:01:59.285Z","repository":{"id":342187069,"uuid":"1173169551","full_name":"viveknaskar/pdf-kit","owner":"viveknaskar","description":"Free, open-source PDF tools that run entirely in your browser. No watermarks, no sign-up, no server uploads, your files never leave your device.","archived":false,"fork":false,"pushed_at":"2026-03-22T21:34:01.000Z","size":22760,"stargazers_count":33,"open_issues_count":0,"forks_count":7,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-03-23T14:38:57.803Z","etag":null,"topics":["javascript","pdf","pdf-tools"],"latest_commit_sha":null,"homepage":"https://viveknaskar.github.io/pdf-kit/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/viveknaskar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"viveknaskar"}},"created_at":"2026-03-05T04:33:55.000Z","updated_at":"2026-03-22T05:03:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/viveknaskar/pdf-kit","commit_stats":null,"previous_names":["viveknaskar/pdf-kit"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/viveknaskar/pdf-kit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viveknaskar%2Fpdf-kit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viveknaskar%2Fpdf-kit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viveknaskar%2Fpdf-kit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viveknaskar%2Fpdf-kit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/viveknaskar","download_url":"https://codeload.github.com/viveknaskar/pdf-kit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viveknaskar%2Fpdf-kit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31293154,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T21:15:39.731Z","status":"ssl_error","status_checked_at":"2026-04-01T21:15:34.046Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","pdf","pdf-tools"],"created_at":"2026-04-02T00:01:00.104Z","updated_at":"2026-04-02T00:01:59.262Z","avatar_url":"https://github.com/viveknaskar.png","language":"JavaScript","funding_links":["https://github.com/sponsors/viveknaskar"],"categories":[],"sub_categories":[],"readme":"# pdfkit\n\n![pdfkit](public/og-image.png)\n\n![Views](https://visitor-badge.laobi.icu/badge?page_id=viveknaskar.pdf-kit)\n\nLive site: https://viveknaskar.github.io/pdf-kit/\n\nFree, open-source PDF tools that run entirely in your browser. No watermarks, no sign-up, no server uploads, your files never leave your device.\n\nBuilt with vanilla JavaScript, [pdf-lib](https://pdf-lib.js.org/), [PDF.js](https://mozilla.github.io/pdf.js/), and [Vite](https://vitejs.dev/).\n\n---\n\n## Screenshots\n\n### Home\n\n![Home](public/screenshots/home.png)\n\n### Essentials\n\n| Merge PDFs | Split PDF | Compress PDF |\n|:---:|:---:|:---:|\n| ![Merge](public/screenshots/merge.png) | ![Split](public/screenshots/split.png) | ![Compress](public/screenshots/compress.png) |\n\n### Convert\n\n| PDF to JPG | Images to PDF | HTML to PDF |\n|:---:|:---:|:---:|\n| ![PDF to JPG](public/screenshots/pdf2jpg.png) | ![Images to PDF](public/screenshots/img2pdf.png) | ![HTML to PDF](public/screenshots/html2pdf.png) |\n\n### Edit \u0026 Organize\n\n| Organize Pages | Add Text / Sign | Page Numbers |\n|:---:|:---:|:---:|\n| ![Organize](public/screenshots/organize.png) | ![Add Text](public/screenshots/addtext.png) | ![Page Numbers](public/screenshots/pagenums.png) |\n\n| Add Watermark | Encrypt PDF | Extract Text |\n|:---:|:---:|:---:|\n| ![Watermark](public/screenshots/watermark.png) | ![Encrypt](public/screenshots/encrypt.png) | ![Extract](public/screenshots/extract.png) |\n\n---\n\n## Features\n\n- **100% client-side:** all processing happens in the browser using WebAssembly and Canvas APIs\n- **No file uploads:** files are read and written locally; nothing is sent to any server\n- **Works offline:** once loaded, the app functions without an internet connection\n- **No watermarks, no sign-up, no limits**\n- **Drag \u0026 drop** support across all tools\n\n---\n\n## How does it Work?\n\nWhen you upload a file, it never leaves your device. Here is exactly what happens:\n\n1. **The browser reads the file into memory** using the `FileReader` / `ArrayBuffer` API. The file data lives in your browser's RAM, not on any server.\n2. **pdf-lib and PDF.js process it locally** inside your browser tab using JavaScript and WebAssembly.\n3. **The result is generated in memory** as a new `Blob` object, still entirely in RAM.\n4. **You download it** via a temporary local URL (`URL.createObjectURL`) that the browser creates, triggers the download, then immediately revokes.\n5. **When you close the tab**, everything is gone. No trace left anywhere.\n\nNo data is ever sent over the network. There is no backend, no database, and no cloud storage involved. You can turn off your WiFi after the page loads and every tool will still work.\n\n## Tools\n\n### Essentials\n\n| Tool | Description |\n|------|-------------|\n| **Merge PDFs** | Combine multiple PDF files into one. Drag to reorder before merging. |\n| **Split PDF** | Extract selected pages or split every page into a separate PDF. Visual page picker included. |\n| **Compress PDF** | Reduce file size. Most effective on PDFs with embedded images. |\n\n### Convert\n\n| Tool | Description |\n|------|-------------|\n| **PDF to JPG** | Render each PDF page as a JPG image. Choose Standard (72 DPI), High (150 DPI), or Maximum (216 DPI) quality. |\n| **Images to PDF** | Combine JPG, PNG, or WebP images into a single PDF document. |\n| **HTML to PDF** | Paste raw HTML and convert it to a downloadable PDF. |\n\n### Edit \u0026 Organize\n\n| Tool | Description |\n|------|-------------|\n| **Organize Pages** | Drag to reorder pages, rotate 90° CW/CCW, or delete pages with visual thumbnails. |\n| **Add Text / Sign** | Click to place text annotations or freehand-draw a signature on any page. Supports color and font size controls, undo, and multi-page navigation. |\n| **Page Numbers** | Add page numbers with configurable position (top/bottom, left/center/right), format (plain, dash, \"Page N\", \"N of M\"), and starting number. |\n| **Add Watermark** | Stamp a diagonal text watermark on every page. Configurable text and opacity (light 10%, medium 20%, heavy 35%). |\n| **Encrypt PDF** | Password-protect a PDF using pdf-lib's built-in encryption. |\n| **Extract Text** | Extract all text content from a PDF and copy it to the clipboard. |\n\n---\n\n## Tech Stack\n\n| Library | Role |\n|---------|------|\n| [pdf-lib](https://pdf-lib.js.org/) | Create and modify PDFs (merge, split, annotate, encrypt, watermark, page numbers) |\n| [pdfjs-dist](https://mozilla.github.io/pdf.js/) | Render PDF pages to canvas (previews, PDF to JPG, text extraction) |\n| [Vite](https://vitejs.dev/) | Dev server, ES module bundler, and production build tool |\n\nNo frontend framework — plain HTML, CSS, and ES modules.\n\n---\n\n## Requirements\n\n- [Node.js](https://nodejs.org/) v18 or later (v24 LTS recommended)\n- npm (bundled with Node.js)\n\n---\n\n## Setup\n\n```bash\n# Install dependencies\nnpm install\n\n# Start the dev server\nnpm run dev\n```\n\nOpens automatically at `http://localhost:3000`.\n\n## Production Build\n\n```bash\nnpm run build\n```\n\nOutput goes to `dist/`. This is a fully static folder — deploy it anywhere.\n\n```bash\n# Preview the production build locally\nnpm run preview\n```\n\n---\n\n## Testing\n\n```bash\n# Unit tests (Utils.js)\nnpm test\n\n# Unit tests in watch mode\nnpm run test:watch\n\n# E2E tests (requires no other process on port 5173)\nnpm run test:e2e\n```\n\nUnit tests use [Vitest](https://vitest.dev/) with happy-dom. E2E tests use Vitest + [Puppeteer](https://pptr.dev/) and spin up a Vite dev server automatically.\n\n---\n\n## Project Structure\n\n```\npdf-kit/\n├── public/\n│   ├── favicon.svg\n│   ├── og-image.png\n│   └── robots.txt\n├── src/\n│   ├── styles/\n│   │   ├── base.css          # CSS reset, variables, typography\n│   │   ├── layout.css        # Header, footer, hero, tool grid\n│   │   ├── components.css    # Cards, buttons, dropzones, progress bars\n│   │   └── tools.css         # Canvas editor, page previews, toolbars\n│   ├── core/\n│   │   ├── App.js            # App shell HTML, routing, navigation\n│   │   ├── DropZone.js       # Drag-and-drop file handling\n│   │   └── Utils.js          # Shared utility functions\n│   ├── tools/\n│   │   ├── MergePdf.js\n│   │   ├── SplitPdf.js\n│   │   ├── CompressPdf.js\n│   │   ├── PdfToJpg.js\n│   │   ├── ImagesToPdf.js\n│   │   ├── HtmlToPdf.js\n│   │   ├── OrganizePages.js\n│   │   ├── AddTextSign.js\n│   │   ├── PageNumbers.js\n│   │   ├── AddWatermark.js\n│   │   ├── EncryptPdf.js\n│   │   └── ExtractText.js\n│   └── main.js               # Entry point — imports and initializes all tools\n├── tests/\n│   ├── unit/\n│   │   └── utils.test.js     # Unit tests for Utils.js\n│   └── e2e/\n│       ├── setup.js          # Vite dev server setup/teardown\n│       └── app.test.js       # Puppeteer E2E tests\n├── index.html\n├── package.json\n├── vite.config.js\n├── vitest.config.js          # Unit test config\n├── vitest.e2e.config.js      # E2E test config\n└── .gitignore\n```\n\n---\n\n## Adding a New Tool\n\n1. Create `src/tools/YourTool.js` and export an `init()` function that binds event listeners\n2. Add the tool view HTML inside `toolViewsHTML()` in `src/core/App.js`\n3. Add a tool card to the appropriate section grid in the home view (also in `App.js`)\n4. Import and call `init()` in `src/main.js`\n\n---\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviveknaskar%2Fpdf-kit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fviveknaskar%2Fpdf-kit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviveknaskar%2Fpdf-kit/lists"}