DEV Community

Sheaf
Sheaf

Posted on

I almost added a PDF library. A print stylesheet was enough.

I was about to add a PDF library to our project. Then I remembered every browser already has one.

Here's the situation. We make Sheaf, a time tracking and invoicing app. After a week with basically no visitors, we decided to build a few small free tools that people actually search for. The first one was an invoice generator: fill in a form, get a PDF, no account.

My first plan was the usual one. Send the form to the server, render a PDF there, send the file back.

Then I started listing what that meant. A PDF library. Fonts. A server route. Rate limits, because now anyone can make our server do work. And people's client names, addresses and amounts flowing through our backend, for a free tool.

That's a lot of stuff for a page that's supposed to be simple.

So I tried the lazy option instead: window.print() and a print stylesheet.

The preview on the page is already a nice looking invoice, built from normal HTML. When you print, I hide everything except that preview:

@media print {
  @page { margin: 14mm; }
  header, footer, form, .buttons { display: none !important; }
  .invoice { box-shadow: none; padding: 0; }
}
Enter fullscreen mode Exit fullscreen mode

The person clicks Download PDF, the print window opens, they pick "Save as PDF", done. The browser does the font rendering, the page breaks and the file. On phones it goes through the share sheet.

A few things I didn't expect:

Nothing to store means nothing to worry about. The form saves to localStorage so your details are there next time. Nothing leaves the browser, so there's no privacy policy paragraph to write and no data to protect.

It's an easy promise to keep. The page says "Your invoice stays in this browser", and it's true by design, not because of a policy. A lot of free invoice tools ask for your email first. This one can't, because there's nowhere to send it.

It made the next tools easy. The time card calculator and the hourly rate calculator use the same idea: plain HTML, a bit of JavaScript, localStorage, print CSS. Each one took an afternoon.

The one downside: you can't control the browser's own header and footer (the date and URL in the margins). Most browsers have a checkbox to turn them off, and that's fine for an invoice.

If you're about to add a PDF library, try a print stylesheet first. It might be all you need.

Here's the generator if you want to see it working: free invoice generator.

What's something you almost overbuilt before finding the simple version?

Top comments (0)