Building a PDF generation service using Nextjs and React PDF

Balogun Wahab
3 min readNov 28, 2024

--

A screenshot of Expense AI’s expense report template
Expense AI Report template

Introduction

PDF generation is a common requirement in expense management applications, but implementing it efficiently can be challenging. At Expense AI, we recently transformed our PDF generation system from a backend-heavy approach to a more maintainable, frontend-focused solution.

In this article, I’ll share our journey, the challenges we faced, and how we leveraged Next.js and React PDF to build a robust PDF generation service.

The Legacy System: What Wasn’t Working

Our initial PDF generation system relied on:

  • Adonis.js edge template engine
  • Tailwind CSS for styling
  • Puppeteer for rendering

While functional, this setup presented several critical challenges:

  1. Slow Build Times: The Puppeteer’s large size caused deployment timeouts.
  2. Poor Developer Experience: Limited IDE support for Adonis.js edge templates.
  3. Performance Issues: Complex reports with images frequently timed out

The Solution: A Dedicated PDF Service

To address these pain points, we decided to create a separate PDF generation service using Next.js. This approach allowed us to:

  • Leverage modern web development tools
  • Improve development experience
  • Enhance performance and reliability

Technical Implementation

We chose to combine react-pdf-tailwind with react-pdf to maintain compatibility with our existing Tailwind CSS templates. The implementation involved three key components:

UI Primitives

The UI Primitives implementation creates a bridge between Tailwind CSS and React PDF components. Here’s what’s happening:

Usage Example

In the example below, we register the font and then use the UI primitives to compose the PDF document.

API Integration

The API endpoint orchestrates the PDF generation and delivery process through a streamlined approach. It dynamically renders components based on response status, converting them into PDF streams for efficient delivery.

With proper content-type headers and cache control, the endpoint ensures reliable PDF delivery while maintaining unique file identification through timestamp-based naming. Here’s the implementation:

Architecture Overview

Our new system follows a clear sequence:

  1. The user initiates report generation with filter parameters
  2. The backend encrypts parameters and generates a secure URL
  3. The mobile app requests a PDF preview
  4. Report service fetches and processes data
  5. PDF is generated and delivered to the user
Expense AI Report Sequence Diagram

Results and Impact

Improvements

  • Build time reduced from 20 minutes to 3 minutes
  • Eliminated timeout issues
  • Better system architecture and maintainability

Limitations and Considerations

  • React-pdf has limited styling options e.g. grid layout is not supported.
  • Limited HTML elements e.g. The table element isn’t supported so we implemented the table layout using flex-box.
    This led to inconsistency/unexpected behavior in the report layout.

Technical Considerations

  • React PDF compatibility required downgrading to Next.js 14
  • Potential future migration to Express.js for better memory management depending on Next.js memory usage.

Conclusion

Our migration to this new PDF generation service brought substantial improvements to both development workflow and performance. However, before adopting React PDF for your projects, carefully evaluate whether its capabilities align with your needs. Consider factors such as:

  • The complexity of your PDF layouts
  • Your styling requirements (especially if you heavily rely on grid layouts or tables)
  • Your team’s familiarity with React and Tailwind
  • While React PDF worked well for our use case at Expense AI, other solutions like PDFKit, wkhtmltopdf, or Puppeteer might be more suitable depending on your specific requirements.

If you found this article helpful, I’d appreciate your claps and shares! 👏

Want to see this PDF generation service in action? Check out Expense AI — we’re helping businesses streamline their expense management with features like this and many more.

Feel free to connect with me on LinkedIn for more tech insights and discussions. Drop a comment below if you have any questions or experiences to share!

Additional Resources

React PDF — https://react-pdf.org/
React PDF Tailwind — https://www.npmjs.com/package/react-pdf-tailwind

--

--

Balogun Wahab
Balogun Wahab

Written by Balogun Wahab

A human who writes code and likes to make amazing things happen.