How to Vibe Code a PDF
Sometimes, I want to make a decent-looking PDF without dealing with Abobe, Figma, Canva, Word, or any of the other hundreds of technologies for creating PDFs.
Fortunately, it's now quite easy to vibe code PDFs with images and complex layouts. As an example, here's a speaker kit one-pager that I recently made.
This PDF was created with Cursor.
Designing PDFs with CSS
Using a browser's built-in print tooling, you can export any web page as a PDF. Often, the layout and spacing on these pages is on a spectrum from ugly to unreadable. But the CSS media selector for print gives developers control over print layouts.
In 2021, Tailwind CSS introduced a print modifier with version 3.0. This modifier can be applied to all classes within Tailwind. This enables precise control over the PDF layout.
LLMs are extremely good at writing Tailwind CSS. Fortunately, my experience is that they are also pretty good at writing Tailwind code with the print: modifier.
Step-by-step PDF creation
I created the example PDF above using Cursor with the default Composer model. End-to-end, the process took less than 10 minutes, though I already had most of the content ready and I borrowed bits of layout from my personal website.
Here are the steps:
- Scaffold a basic setup with Tailwind CSS. I used Next.JS but you could also just use basic HTML.
- Prompt the agent to use the
print:modifier within Tailwind CSS to build the core PDF, keeping in mind the standard 8.5 by 11 inch page size. - Run your dev server and load your page on localhost.
- Use your print shortcut (⌘P on Mac) to preview the page.
- Iterate as needed.
- Download the PDF (tip: turn off the "Headers and footers" option on Chrome for a clean export).
This is a pretty janky way of making PDFs. But with LLM assistance, janky setups can still be fast to operate. And compared to designing an equivalent PDF using one of the standard tools (none of which I am particularly skilled with), it is a fast and convenient way to make good quality documents and reusable templates.