Welcome to FullStack. We use cookies to enable better features on our website. Cookies help us tailor content to your interests and locations and provide other benefits on the site. For more information, please see our Cookies Policy and Privacy Policy.
Generate Pixel Perfect PDF Forms with PDFtk and Node.js
Written by
Michael Godshall
Last updated on:
October 1, 2025
Written by
Last updated on:
October 1, 2025
A recent project at FullStack Labs needed PDF forms to be populated dynamically with requested data from a database. Previous projects required generating basic PDF documents with HTML and CSS, but this project required the forms to be pixel-perfect.
The nature of the project called for a large number of these forms to be generated, which we determined would be a costly endeavor if each form was generated with HTML and CSS.
After some research, my team discovered that this process can be streamlined significantly by creating a fillable PDF template and then programmatically filling in each field when the form is requested.
We hoped to find a pure JavaScript solution for our Node.js app, but the packages we found at the time were poorly documented and difficult to use. Instead, we found PDFtk to be the easiest way to populate fillable PDFs, which provides a CLI for reading and writing to PDF form fields. We also used the node-pdftkpackage which provides a Node.js wrapper for PDFtk.
This article will guide you through the process of bringing the tools and ideas above together in a Node.js application, but the same ideas can be applied to other languages that have their own PDFtk wrappers.
Create a fillable PDF template
The first step is to create a PDF template with fillable form fields. This can be accomplished using Adobe Acrobat Reader DC and the Prepare Form feature.
The advantage of this approach is that it provides non-technical users the ability to create fillable PDF forms on their own which is typically a more economic solution for clients (especially if numerous forms need to be created and maintained). The Prepare Form feature does require a premium subscription to Adobe Acrobat Reader DC, but the cost is negligible compared to the savings on the development side.
When the fillable form is created, a name is assigned to each field that can later be targeted programmatically by a developer with PDFtk.
For the purposes of this article, you can download the 1099-NEC form from the IRS’s website, which contains fillable form fields.
Identify the PDF form fields to populate
When a developer receives a fillable PDF form, PDFtk reads the PDF and identifies the field names that can be populated.
To get started, install pdftk locally with Homebrew.
$ brew install pdftk-java
Then, verify that the installation was successful and that the pdftk command is available.
$ pdftk -version
pdftk port to java 3.1.1 a Handy Tool for Manipulating PDF Documents
Copyright (c) 2017-2018 Marc Vinyals - https://gitlab.com/pdftk-java/pdftkCopyright (c) 2003-2013 Steward and Lee, LLC.
pdftk includes a modified version of the iText library.
Copyright (c) 1999-2009 Bruno Lowagie, Paulo Soares, et al.
This is free software; see the source code for copying conditions. There is
NO warranty, not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Now, run the dump_data_fields command on the 1099-NEC form you downloaded in the previous section to retrieve data for the available form fields.
$ pdftk path/to/f1099nec.pdf dump_data_fields
-
/* Sample output */-
FieldType: Text
FieldName: topmostSubform[0].CopyB[0].CopyBHeader[0].LeftCol[0].f2_1[0]
FieldFlags: 8392704FieldJustification: Left
-
FieldType: Text
FieldName: topmostSubform[0].CopyB[0].CopyBHeader[0].LeftCol[0].f2_2[0]
FieldFlags: 0FieldJustification: Center
FieldMaxLength: 11-
FieldType: Text
FieldName: topmostSubform[0].CopyB[0].CopyBHeader[0].LeftCol[0].f2_3[0]
FieldFlags: 0FieldJustification: Center
FieldMaxLength: 11-
The main information that you need from this output is the FieldName, which tells you how to target the form fields programmatically in your code.
You’ll notice that most of the FieldNames on this form are a bit cryptic, like topmostSubform[0].CopyB[0].CopyBHeader[0].LeftCol[0].f2_1[0], so it might take some trial and error to figure out the actual fields the FieldNames correspond to. If desired, you can also use the Prepare Form feature in Adobe Acrobat Reader DC to inspect or edit the FieldNames so they are more intuitive for development purposes.
Fill out the PDF fields programmatically
1. Add node-pdftk to your project.
$ npm install node-pdftk
2. Create a file called generate1099Form.js, and import node-pdftk.
import pdftk from node-pdftk;
3. Add example payer and contractor objects with relevant data. This can be enhanced later to dynamically load the information from a database.
The 1099-NEC PDF has multiple pages with form fields, but in this example, we are just targeting form fields in the Copy B page. As I noted above, you can use the Prepare Form feature in Adobe Acrobat Reader DC to edit the FieldNames so they are more intuitive for development purposes.
5. Now that you have a fieldMap for the form, you just need to pass it to node-pdftk which will generate a new PDF with the corresponding form fields filled out.
const sourcePdf = 'forms/f1099nec.pdf';
return pdftk
.input(sourcePdf)
.fillForm(fieldMap)
.flatten() /* Removes the form fields to lock the PDF from further edits */ .output() /* Pass an optional file path to save the new PDF locally */ .then(pdfBuffer => pdfBuffer)
.catch(err => {
throw err;
});
6. You can use a framework like Koa or Express to render the pdfBuffer in the browser as a PDF. Here is a streamlined example of what this looks like in Koa:
Congratulations! The final result is a pixel-perfect PDF form!
At FullStack, we understand that building efficient, scalable solutions and creating pixel-perfect PDF forms with tools like PDFtk and Node.js requires not only the right technology but also the right talent. Whether you're looking for skilled engineers to augment your team or need end-to-end project consulting, our experts are ready to help you bring your ideas to life. Partner with us for solutions tailored to your unique business needs. Contact us today to find out how FullStack can support your next initiative.
How do you generate pixel-perfect PDF forms in Node.js?
For this project, we needed to create PDF forms that were pixel-perfect while also dynamically filling them with data from a database. Using HTML and CSS to generate each document would have been too costly and time-consuming. Instead, we used fillable PDF templates combined with PDFtk and Node.js to efficiently produce high-quality, ready-to-use forms at scale.
What are fillable PDF templates, and why use them?
Fillable PDF templates allow you to design a form once and programmatically populate its fields later. Tools like Adobe Acrobat Reader DC’s Prepare Form feature make this possible, even for non-technical users. Each field is given a name, which developers can target when filling out the form with data. This approach is far more efficient than creating separate PDFs for every form, especially when generating documents in bulk.
How does PDFtk work for PDF form generation in Node.js?
PDFtk is a command-line tool for reading and writing PDF form fields. In Node.js, the node-pdftk package provides a lightweight wrapper for working with it. The process involves:
Creating a fillable PDF template with defined field names.
Using PDFtk to identify those fields programmatically.
Passing the correct data into those fields to produce a completed PDF. Because PDFtk handles all the rendering, it ensures every generated PDF is pixel-perfect and consistent with your template.
How do you populate PDF form fields programmatically?
Once you know the field names within your template, you map each one to values in your application—such as payer details, contractor information, or custom data from your database. That mapping is passed to node-pdftk, which fills the fields and returns a complete, locked PDF. From there, you can deliver the document to users, store it securely, or integrate it into automated workflows.
Why use PDFtk and Node.js for pixel-perfect PDF generation?
This approach combines PDFtk’s reliable rendering engine with Node.js’s flexibility for fetching and managing data. It’s ideal for businesses that generate large volumes of PDF forms because it:
Produces pixel-perfect, compliant documents
Reduces development time and manual effort
Supports automation for high-volume scenarios
Delivers consistent results with every generated form
AI is changing software development.
The Engineer's AI-Enabled Development Handbook is your guide to incorporating AI into development processes for smoother, faster, and smarter development.
Enjoyed the article? Get new content delivered to your inbox.
Subscribe below and stay updated with the latest developer guides and industry insights.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.