कागज़Kagazpaper tools

MIT licensed · no build step · no framework

Contribute

Kagaz is deliberately boring to work on. There is no toolchain, no bundler, no node_modules to install before you can see a change. Clone it, open a file in your browser, and you are developing.

Getting set up

git clone https://github.com/namastevis/kagaz.git
cd kagaz
python3 -m http.server 8000
# open http://localhost:8000

The small web server is only needed because pdf.js loads its worker as a separate file, which browsers block on file://. Any static server will do.

How the code is laid out

index.html            the landing page
merge-pdf/index.html  one tool, one self-contained file
split-pdf/index.html
compress-pdf/index.html
pdf-to-jpg/index.html
certificate/index.html
shared/kagaz.css      every page shares this stylesheet
shared/kagaz.js       browser helpers: drop zones, downloads, canvas, messages
shared/ops.js         the PDF logic — deliberately DOM-free
vendor/               pdf-lib, pdf.js, JSZip, fontkit — vendored, never a CDN
tests/stress.mjs      throws deliberately broken PDFs at shared/ops.js

Three rules keep it that way, and they are the only ones:

  1. One tool is one HTML file. Markup, styles specific to it, and its logic all live together. You should be able to understand a tool without opening anything else.
  2. Nothing may be fetched from another origin. No CDN, no font service, no analytics. The entire premise of Kagaz is that opening it makes no network requests, and a contributor adding a Google Font would quietly break that.
  3. PDF logic goes in shared/ops.js, not in the page. That file has no DOM references, so it runs in Node and can be tested. Anything needing a canvas is passed in as an argument.

Adding a new tool

  1. Copy merge-pdf/index.html to your-tool/index.html. It is the simplest of the four.
  2. Change the title, description, canonical URL and the copy below the fold. The slug should be what a person would actually type into a search box — rotate-pdf, not rotator.
  3. Put the actual PDF manipulation in shared/ops.js as a function that takes bytes and returns bytes.
  4. Add a card to the grid on the landing page and a link in every tool's footer list.
  5. Add a case to tests/stress.mjs.

Things worth building

Roughly in order of how useful they would be, with the easiest first.

Good first issues

Harder, and more interesting

Please don't

Running the tests

node tests/stress.mjs

This throws deliberately awful PDFs at shared/ops.js — zero-byte files, truncated files, a JPEG renamed to .pdf, encrypted documents, a two-thousand-page monster, pages of impossible sizes — and checks that each one fails cleanly with a message a human could act on, rather than crashing or producing a broken file.

There is also an in-browser test page that runs the same battery against the real browser code, including the image compression that Node cannot exercise. Open it after any change.

Buy me a chai

Kagaz has no server, so it costs me almost nothing to run — a domain renewal and the evenings that go into it. It is free, unlimited and ad-free, and it will stay that way whether or not anyone sends me anything.

If it saved you an evening of fighting with a website that wanted your bank statement uploaded to it, a chai is a nice thing to do.

That Razorpay link is the only outbound link on this site that leads anywhere commercial, and nothing loads from it unless you click. No payment script runs on these pages.

Who made this

I'm Amit Jena — mathematics and computer science by training, design by accident. I build things that turn data and documents into something a person can use. Kagaz is the documents half; the rest lives next door.