One of the first features I worked on when starting my career was AIM’s PDF generation tool. It was time to migrate “From PDFMonkey to AIM Monkey,” moving off of PDFMonkey’s SaaS product to our own solution. We had to figure out a way to maintain the same templates we used with PDFMonkey while reverse-engineering the server-side logic. This was quite the challenge on its own; we managed to eventually do it, but ended up with extra friction and a huge loss of productivity.

From PDFMonkey to AIM Monkey: Building Internal Tools That Truly Help

The Downgrade: “From PDFMonkey to AIM Monkey”

PDF Monkey offered a developer portal, where you could have a side-by-side view of the template code you were working on and a preview of the PDF on the other side.

From PDFMonkey to AIM Monkey

It had its own cons (long waiting time, frequent errors, etc); nevertheless, losing it was a huge blow to developer productivity.

Now there was no quick way to preview the results of your template code as you wrote it, the only apparent way was to run the manually every time.

There was also no history of reports generated, where you could quickly get test data from.

Developers need a tool where they can develop, test, iterate, and commit. All things that were provided by PDF Monkey

If It Exists, It’s Doable

After successfully replacing the functionality of being able to generate PDFs from liquid templates, I was confident I could replace the great DX experience they offered was an even better one. Here is how I did it.

The challenging components

In the Backend

  1. To generate a PDF, we first combine the report data with the liquid template code, generating an HTML page. We then transform into a PDF using a headless browser with Puppeteer.
  2. Templates are just text files that we can edit and read with Node’s file system operations.
  3. Allowing the result to be returned as either HTML or PDF will allow switching between quick previews or final (but slower) previews.

In the Frontend

  1. We need a text editor, thankfully, there are lots of available open source editors that can be used on the web, of those, I picked the ACE editor.
  2. Displaying the HTML preview could be simply done with an <iframe/>, simple and quick, without any need for packages.
  3. Displaying PDFs could be done with react-pdf, a wrapper around Mozilla’s PDF.js, a PDF viewer for the browser.

And Here Is How It Came Together

From PDFMonkey to AIM Monkey

The Benefits

  1. I got to do it!
  2. Way faster previews 30s -> 200ms, that’s 150x, Lots of time and frustration saved with better DX.
  3. Eliminated quotas imposed by the previous SaaS and prevented timeout issues, both previously out of our control.
  4. Saved some money.
  5. The ability to run this app locally allowed us to introduce version control, being able to easily commit, revert, and use git to our benefit.
  6. This experience led to ideas that greatly helped the occurrence of user-reported issues. (We made a decision that reversed some of our tech debt.)

In conclusion, transitioning from PDFMonkey to AIM’s internal solution was a challenging yet rewarding journey. While the initial shift introduced friction and productivity loss, it ultimately allowed us to create a more efficient, customizable tool tailored to the needs of our developers. With the AIM system, we not only gained the ability to preview templates faster and locally but also eliminated the external dependencies that caused timeouts and limited our flexibility. This migration wasn’t just about replicating functionality—it was about improving the developer experience (DX), enabling faster iterations, and providing better version control with local capabilities. By building AIM, we turned a difficult situation into an opportunity for growth, ensuring our team now has the tools they need to be more productive and proactive in solving user-reported issues. AIM has truly transformed the way we work, paving the way for more streamlined and effective internal tools.