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

@lara-node/pdf

v0.2.1

Published

Laravel-inspired class-based PDF generation for Lara-Node using Puppeteer

Downloads

282

Readme

@lara-node/pdf

Laravel-inspired class-based PDF generation for Lara-Node, powered by Puppeteer.

Inspired by barryvdh/laravel-dompdf.

Installation

npm install @lara-node/pdf
# or
pnpm add @lara-node/pdf

Peer dependencies: express

Puppeteer downloads Chromium automatically on first install.


Quick Start

import { PDF } from '@lara-node/pdf';

// From an HTML string
const pdf = PDF.loadHTML('<h1>Invoice #{{number}}</h1>', { number: 1042 });

// Configure
pdf
  .setPaper('a4', 'portrait')
  .setMargins({ top: '20mm', bottom: '20mm', left: '15mm', right: '15mm' })
  .addPageNumbers();

// Download via Express
app.get('/invoice/:id', async (req, res) => {
  await pdf.download(res, `invoice-${req.params.id}.pdf`);
});

// Save to disk
await pdf.save('/tmp/invoice.pdf');

// Get as Buffer
const buf = await pdf.output('buffer');

// Get as base64
const b64 = await pdf.base64();

Loading HTML

PDF.loadHTML(html, data?)

Create a PDF from an inline HTML string. Supports {{variable}} interpolation.

const pdf = PDF.loadHTML(`
  <!DOCTYPE html>
  <html>
    <head><style>body { font-family: sans-serif; }</style></head>
    <body>
      <h1>Hello, {{name}}!</h1>
      <p>Order total: {{total}}</p>
    </body>
  </html>
`, { name: 'Alice', total: '$99.00' });

PDF.loadView(filePath, data?)

Read an HTML file from disk and interpolate variables.

const pdf = await PDF.loadView('/views/invoice.html', { invoice, company });

PDF.loadFile(filePath)

Read an HTML file from disk without variable interpolation.

const pdf = await PDF.loadFile('/reports/static-report.html');

PDF.loadUrl(url)

Navigate Puppeteer to a URL and capture the rendered page.

const pdf = await PDF.loadUrl('https://example.com/report');

Configuration (Fluent API)

All configuration methods return this, so they can be chained.

Paper & Orientation

pdf.setPaper('a4', 'portrait');   // 'a3' | 'a4' | 'a5' | 'letter' | 'legal' | 'tabloid'
pdf.setOrientation('landscape');

Margins

pdf.setMargins({ top: '20mm', right: '15mm', bottom: '20mm', left: '15mm' });

Viewport

Override Puppeteer's default viewport for responsive layouts.

pdf.setViewport({ width: 1280, height: 900, deviceScaleFactor: 2 });

Scale

Set the CSS print scale factor (0.1 – 2.0).

pdf.setScale(0.9);

Page Ranges

Print only specific pages.

pdf.setPageRanges('1-3, 5'); // pages 1, 2, 3 and 5

Background Colour

pdf.setBackground('#f8f9fa');

Extra CSS

Inject additional styles into the rendered document.

pdf.addStyles(`
  body { font-size: 12pt; }
  table { border-collapse: collapse; }
  td, th { border: 1px solid #ccc; padding: 4px 8px; }
`);

Extra JavaScript

Inject JavaScript that runs in the page before the PDF is captured.

pdf.addScript(`document.querySelectorAll('.no-print').forEach(el => el.remove());`);

Header & Footer

Use Puppeteer's special <span class="pageNumber"> / <span class="totalPages"> classes.

pdf.setHeader(
  `<div style="font-size:9px;text-align:right;width:100%;padding-right:10mm">
     CONFIDENTIAL — {{company}}
   </div>`,
  { height: '15mm' }
);

pdf.setFooter(
  `<div style="font-size:9px;text-align:center;width:100%">
     Page <span class="pageNumber"></span> of <span class="totalPages"></span>
   </div>`,
  { height: '10mm' }
);

Convenience Page Numbers

// Default: "1 / 5"
pdf.addPageNumbers();

// Custom format
pdf.addPageNumbers('Page {pageNumber} of {totalPages}', { height: '12mm' });

Watermark

Overlays a diagonal watermark on every page via CSS ::after.

pdf.setWatermark('CONFIDENTIAL', {
  opacity: 0.12,
  fontSize: 72,
  rotation: -45,
  color: '#cc0000',
});

Document Metadata

pdf.setMetadata({
  title: 'Invoice #1042',
  author: 'Acme Corp',
  subject: 'Monthly Invoice',
  keywords: 'invoice, billing',
  creator: 'Lara-Node PDF',
});

Output

pdf.output(format?)

Returns a Buffer (default) or base64 string.

const buf = await pdf.output();
const buf = await pdf.output('buffer');
const b64 = await pdf.output('base64');

pdf.base64()

Convenience alias for pdf.output('base64').

pdf.save(filePath)

Write the PDF file to disk.

await pdf.save('/var/reports/report-2024.pdf');

pdf.download(res, filename)

Send as an attachment via Express.

await pdf.download(res, 'report.pdf');

pdf.stream(res, filename)

Render inline in the browser (uses Content-Disposition: inline).

await pdf.stream(res, 'report.pdf');

pdf.screenshot(options?)

Capture a screenshot of the rendered HTML page instead of a PDF.

const png = await pdf.screenshot({ type: 'png', fullPage: true });
const jpg = await pdf.screenshot({ type: 'jpeg', quality: 85 });

// Send as image response
res.setHeader('Content-Type', 'image/png');
res.end(png);

Batch Generation

Generate multiple PDFs in parallel.

await PDF.batch([
  { pdf: PDF.loadHTML(template, dataA), filePath: '/tmp/report-a.pdf' },
  { pdf: PDF.loadHTML(template, dataB), filePath: '/tmp/report-b.pdf' },
  { pdf: await PDF.loadView('/views/invoice.html', invoiceData), filePath: '/tmp/invoice.pdf' },
]);

Browser Lifecycle

A singleton Puppeteer browser instance is shared across all PDF operations. Close it when your process exits:

import { closeBrowser } from '@lara-node/pdf';

process.on('SIGTERM', async () => {
  await closeBrowser();
  process.exit(0);
});

Or use the static method:

await PDF.closeBrowser();

Supported Paper Sizes

| Size | Dimensions | |------|-----------| | a3 | 297 × 420 mm | | a4 | 210 × 297 mm | | a5 | 148 × 210 mm | | letter | 216 × 279 mm | | legal | 216 × 356 mm | | tabloid | 279 × 432 mm |


License

MIT