Skip to content

Generating PDF agreements using Lambda and HTML

We have a number of Account Agreement PDFs that we need to generate for each user. Until we are ready to use tools like DocuSign or IronClad (which represent a significant financial investment for a startup), we've opted to generate our own. Here we will walk through our interim solution that involves generating PDF agreements with AWS Lambda and HTML Templates.


What problem are we trying to solve?

Generating custom PDF documents in a serverless environment can be a bit challenging. One of the basic documents that we need to create is an ACH agreement for users and companies that we are transferring funds with. We will walk through how we are doing it at Xiggit using AWS Lambda, Handlebars, and Chromium for Lambda / Puppeteer.

Creating our HTML Template

To start, we'll want to create an HTML Template. We'll use the Handlebars library to allow us to customize the document. Here is the template we use. Create a file of your own and save it into a file called templates/ach_agreement.handlebars.


Preprocess using Handlebars

After you install the Handlebars library, you can pre-process the template into a parsed JavaScript file.

First, install the handlebar library using npm or yarn:

yarn add handlebars
npm install handlebars

Then, you can use the handlebars cli to preprocess your template:

node_modules/handlebars/bin/handlebars templates/ach_agreement.handlebars -f app/templates/ach_agreement.js -c handlebars/runtime

  • The first parameter is the path to our template (templates/ach_agreement.handlebars)
  • The -f switch provides the output path to our parsed template file (app/templates/ach_agreement.js)
  • The -c switch tells Handlebars which runtime to use (handlebars/runtime in our case)

Create the PDF using Handlebars and Chromium / Puppeteer

First, you'll want to load the pre-processed template using the Handlebars SDK:

const _document = Handlebars.templates['ach_agreement']({
  companyLegalName: 'Acme, Inc',
  bankName: 'Hometown Bank',
  routingNumber: '123456789',
  accountMask: '0000'

Next, we'll need to initialize our headless puppeteer browser:

const browser = await chromium.puppeteer.launch({
  args: chromium.args,
  defaultViewport: chromium.defaultViewport,
  executablePath: await chromium.executablePath,
  headless: chromium.headless,
  ignoreHTTPSErrors: true

const page = await browser.newPage();

Finally, we need to set the page content to our parsed HTML document:

await page.setContent(_document, {
  waitUntil: 'networkidle0',

We use the waitUntil: 'networkidle0' configuration option to tell Puppeteer to wait until the document finishes loading before it processes.

Once the page is loaded, we use puppeteer to create a PDF of the processed document:

const pdf = await page.pdf({
  format: 'Letter',

This returns a binary pdf document that we can finish processing. We use the format: 'Letter' configuration option to tell Puppeteer to use a Letter page layout when creating the PDF. Here is the full snippet of the code:

Deploying our code

As mentioned in our other Blog posts, Xiggit is a 100% serverless application, and we deploy our code using the Serverless Framework. Due to the size of Chromium and the Puppeteer tools, we opted to deploy it via a Lamda Layer. Here is the snippet of our Serverless deployment file including our function and the layer:

We're using shelfio's chrome-aws-lambda-layer as a pre-built layer. You can build your own, but that is beyond the scope of this article.

What's next?

Once you've created the PDF binary, you can do any number of things with it. In our case, we save the PDF to a user-specific folder in an S3 bucket and write a record in a QLDB Database to track the file. This gives us the opportunity to track the document in an immutable and transparent journal, securely share the document with the user, and provide access via our internal portals.

Thoughts? Comments? Please share them with us below.

If you're a small business, or a startup, and are looking to offer your employees an affordable retirement option (especially if you have to deal with CalSavers compliance!), give Xiggit a look! We'd love to partner with you on your employees' journey to financial wellness!

Leave a Comment