npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@shad0wz7/nestjs-pdf

v2.3.2

Published

A NestJS library for generating PDFs with Puppeteer and Handlebars.

Readme

nestjs-pdf

A small NestJS library to generate and manipulate PDFs using Puppeteer and multiple template engines, including Handlebars, EJS, Pug, MJML, Nunjucks, Eta and Mustache.

Main features:

  • Generate PDFs from HTML, Handlebars, EJS, Pug, MJML, Nunjucks, Eta or Mustache templates
  • Concurrency limiting for Puppeteer jobs (p-limit)
  • Add signature fields based on a text anchor in an existing PDF
  • Simple API (module and service) to integrate easily into a Nest application

Installation

To add the library inside your project :

npm install @shad0wz7/nestjs-pdf
# or
pnpm add @shad0wz7/nestjs-pdf
# or
yarn add @shad0wz7/nestjs-pdf

# If using the local source, from the other project:
pnpm add ../path/to/nestjs-pdf

Quick start

Import the module and configure it in your Nest application:

To use a template engine, you need to install the corresponding package as a dependency in your project:

  • For Handlebars: npm install @gboutte/nestjs-hbs
  • For EJS: npm install ejs
  • For Pug: npm install pug
  • For MJML: npm install mjml
  • For Nunjucks: npm install nunjucks
  • For Eta: npm install eta
  • For Mustache: npm install mustache
import { Module } from '@nestjs/common';
import { NestjsPdfModule } from 'nestjs-pdf';

@Module({
  imports: [
    NestjsPdfModule.forRoot({
      // default Puppeteer / PDF options
      headless: true,
      pdfOptions: { format: 'A4' },
    }),
  ],
})
export class AppModule {}

Inject the service and generate a PDF:

import { Controller, Get } from '@nestjs/common';
import { NestjsPdfService } from 'nestjs-pdf';

@Controller()
export class AppController {
  constructor(private readonly pdfService: NestjsPdfService) {}

  @Get('pdf')
  async getPdf() {
    const html = '<h1>Hello</h1><p>PDF generated by nestjs-pdf</p>';
    const buffer = await this.pdfService.generatePdfFromHtml(html);
    return buffer; // return a Buffer / Uint8Array depending on your controller
  }
}

Use a Handlebars template (string or file):

const template = '<h1>{{title}}</h1><p>{{content}}</p>';
const pdf = await pdfService.generatePdfFromTemplateHbsString(template, {
  title: 'T',
  content: '...',
});
const pdf = await pdfService.generatePdfFromTemplateHbsFile(filePath, {
  title: 'T',
  content: '...',
});

Add a signature field to an existing PDF (anchor-based):

const originalPdfBytes = await this.pdfService.generatePdfFromHtml(html);
const modifiedPdf = await pdfService.addSignatureFieldSignatureDebtorRaw(
  originalPdfBytes,
  'SignatureDebtor',
  '__SIG_DEBTOR_ANCHOR__',
);

If the anchor is not found, the signature field will be added at a default position.

Warning: if you encounter issues like "Failed to load pdfjs-dist." Make sure to install @napi-rs/canvas as a dependency in your project, as it's required by the library for PDF manipulation.

Options and configuration

The library exposes Puppeteer options via the PuppeteerParameters interface (see src/puppeteer/puppeteer-parameters.interface.ts). You can configure:

| | Description | |-----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | pdfOptions | The pdf options can be found on: https://pptr.dev/api/puppeteer.pdfoptions. Native Puppeteer options for page.pdf | | hbsOptions | The handlebars can be found on @gboutte/nestjs-hbs as it use a peer dependency and not handlebars directly | | ejsOptions | The ejs options can be found on EJS documentation | | pugOptions | The pug options can be found on Pug documentation | | mjmlOptions | The mjml options can be found on MJML documentation | | nunjucksOptions | The nunjucks options can be found on Nunjucks documentation | | etaOptions | The eta options can be found on Eta documentation | | mustacheOptions | The mustache options can be found on Mustache documentation | | browser | The browser to use for the PDF generation. By default: Browser.CHROMIUM. Allowed values Browser.CHROMIUM, Browser.CHROMEHEADLESSSHELL, Browser.CHROME, Browser.FIREFOX, Browser.CHROMEDRIVER (Official documentation of Browser) | | browserTag | The version of the browser to use for the PDF generation. By default: BrowserTag.LATEST if Browser is CHROMIUM else BrowserTag.STABLE. Allowed values BrowserTag.STABLE, BrowserTag.LATEST, BrowserTag.BETA, BrowserTag.DEV, BrowserTag.CANARY | | browserInstallBaseUrl | The baseUrl used for the installation of the browser. This baseUrl is passed to the install method of @puppeteer/browsers | | headless | Define if you want to use chromium headless or not, or the old headless version (shell). By default it's true. Allowed values: true,false,"shell" | | useLockedBrowser | Define if you want to use the locked version of the browser. By default it's false. Allowed values: true,false | | buildId | You can force the build id. Should be string | | cleanupBrowserCacheOnExit | Define if you want to clean up the browser cache folder on exit. By default it's true. Allowed values: true,false | | extraPuppeteerArgs | It passes some extra arguments to Puppeteer's launch method. You can check the default args at bellow. Should be string[] | | executablePath | The path to the browser executable to use. If not specified, Puppeteer will install Chromium in cache dir. (useLockedBrowser is useless with this param specified) |

these are the default extra arguments passed to Puppeteer:

[
  '--autoplay-policy=user-gesture-required',
  '--disable-background-networking',
  '--disable-background-timer-throttling',
  '--disable-backgrounding-occluded-windows',
  '--disable-breakpad',
  '--disable-client-side-phishing-detection',
  '--disable-component-update',
  '--disable-default-apps',
  '--disable-dev-shm-usage',
  '--disable-domain-reliability',
  '--disable-extensions',
  '--disable-features=AudioServiceOutOfProcess',
  '--disable-hang-monitor',
  '--disable-ipc-flooding-protection',
  '--disable-notifications',
  '--disable-offer-store-unmasked-wallet-cards',
  '--disable-popup-blocking',
  '--disable-print-preview',
  '--disable-prompt-on-repost',
  '--disable-renderer-backgrounding',
  '--disable-setuid-sandbox',
  '--disable-speech-api',
  '--disable-sync',
  '--hide-scrollbars',
  '--ignore-gpu-blacklist',
  '--metrics-recording-only',
  '--mute-audio',
  '--no-default-browser-check',
  '--no-first-run',
  '--no-pings',
  '--password-store=basic',
  '--use-gl=swiftshader',
  '--use-mock-keychain',
  '--disable-accelerated-2d-canvas',
  '--no-zygote',
  '--disable-gpu',
];

You can use forRootAsync(...) if you need to provide configuration asynchronously.

Tests

This repository includes unit and integration tests (Jest). To run the tests:

pnpm run test
pnpm run test:e2e

Contributing

If you want to contribute:

  • Open an issue to discuss the change
  • Fork the repo, create a feature/fix branch, then open a PR
  • Follow Conventional Commits for automated releases

License

MIT — see the LICENSE file.