terminalskills/skills

pdfkit

>- Generate PDF documents programmatically with PDFKit — add text, images, vector graphics, tables, headers/footers, and custom fonts. Use when tasks involve creating invoices, reports, certificates, or any structured PDF output from application data in Node.js.

First seen Mar 13, 2026

Installation

$ npx skills add terminalskills/skills --skill pdfkit

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from terminalskills/skills · top by installs.

npx skills add terminalskills/skills

Browse all from terminalskills/skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 146
License LICENSE
Default branch main
Open issues 1
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0.0
LicenseApache-2.0
CompatibilityNode.js 14+
More metadata
author
terminal-skills
version
1.0.0
category
documents
tags
["pdf","pdfkit","reports","invoices","node"]

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 5,067 B
  • docs SUMMARY.md 275 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 7 installs

SKILL.md

PDFKit

Programmatic PDF generation for Node.js. Streaming architecture — write to files or HTTP responses.

Setup

# Install PDFKit for PDF generation.
npm install pdfkit
npm install -D @types/pdfkit

Basic Document

// src/pdf/basic.ts — Create a simple PDF with text and save to file.
import PDFDocument from "pdfkit";
import fs from "fs";

const doc = new PDFDocument({ size: "A4", margin: 50 });
doc.pipe(fs.createWriteStream("output.pdf"));

doc.fontSize(24).text("Monthly Report", { align: "center" });
doc.moveDown();
doc.fontSize(12).text("Generated on " + new Date().toLocaleDateString());
doc.moveDown(2);
doc.fontSize(11).text(
  "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
  "Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
  { align: "justify", lineGap: 4 }
);

doc.end();

Tables

// src/pdf/table.ts — Draw a table with headers and rows.
// PDFKit has no built-in table; draw it with lines and positioned text.
import PDFDocument from "pdfkit";

export function drawTable(
  doc: PDFKit.PDFDocument,
  headers: string[],
  rows: string[][],
  startY: number
) {
  const colWidth = (doc.page.width - 100) / headers.length;
  const rowHeight = 25;
  let y = startY;

  // Header row
  doc.font("Helvetica-Bold").fontSize(10);
  headers.forEach((header, i) => {
    doc.text(header, 50 + i * colWidth, y, { width: colWidth, align: "left" });
  });

  y += rowHeight;
  doc.moveTo(50, y).lineTo(doc.page.width - 50, y).stroke();

  // Data rows
  doc.font("Helvetica").fontSize(10);
  for (const row of rows) {
    y += 5;
    row.forEach((cell, i) => {
      doc.text(cell, 50 + i * colWidth, y, { width: colWidth, align: "left" });
    });
    y += rowHeight;

    // Page break if needed
    if (y > doc.page.height - 100) {
      doc.addPage();
      y = 50;
    }
  }
}

Images and Graphics

// src/pdf/graphics.ts — Add images, draw shapes, and use vector graphics.
import PDFDocument from "pdfkit";
import fs from "fs";

const doc = new PDFDocument();
doc.pipe(fs.createWriteStream("report.pdf"));

// Embed an image
doc.image("logo.png", 50, 50, { width: 150 });

// Draw a colored rectangle
doc.rect(50, 250, 200, 100).fill("#3498db");

// Draw a circle
doc.circle(400, 300, 50).fill("#e74c3c");

// Draw a line
doc.moveTo(50, 400).lineTo(550, 400).dash(5, { space: 5 }).stroke("#999");

doc.end();

Headers and Footers

// src/pdf/headers.ts — Add repeating headers and footers with page numbers.
import PDFDocument from "pdfkit";
import fs from "fs";

export function createDocWithHeaderFooter(title: string, outputPath: string) {
  const doc = new PDFDocument({ size: "A4", margin: 50, bufferPages: true });
  doc.pipe(fs.createWriteStream(outputPath));

  // Write content across multiple pages
  doc.fontSize(20).text(title, { align: "center" });
  doc.moveDown(2);
  for (let i = 0; i < 200; i++) {
    doc.fontSize(11).text(`Line ${i + 1}: Sample content for the report.`);
  }

  // Add headers and footers to all pages
  const pageCount = doc.bufferedPageRange().count;
  for (let i = 0; i < pageCount; i++) {
    doc.switchToPage(i);

    // Header
    doc.fontSize(8).fillColor("#999")
      .text(title, 50, 20, { align: "left" })
      .text(new Date().toLocaleDateString(), 50, 20, { align: "right" });

    // Footer with page number
    doc.text(`Page ${i + 1} of ${pageCount}`, 50, doc.page.height - 30, {
      align: "center",
    });
  }

  doc.end();
}

Custom Fonts

// src/pdf/fonts.ts — Register and use custom fonts for branded documents.
import PDFDocument from "pdfkit";
import fs from "fs";

const doc = new PDFDocument();
doc.pipe(fs.createWriteStream("branded.pdf"));

// Register custom font
doc.registerFont("Inter", "./fonts/Inter-Regular.ttf");
doc.registerFont("Inter-Bold", "./fonts/Inter-Bold.ttf");

doc.font("Inter-Bold").fontSize(24).text("Branded Report");
doc.font("Inter").fontSize(12).text("Using custom Inter font throughout.");

doc.end();

Streaming to HTTP Response

// src/pdf/stream.ts — Generate PDFs on the fly and stream to Express responses.
import PDFDocument from "pdfkit";
import type { Response } from "express";

export function streamPdf(res: Response, title: string) {
  const doc = new PDFDocument();
  res.setHeader("Content-Type", "application/pdf");
  res.setHeader("Content-Disposition", `attachment; filename="${title}.pdf"`);

  doc.pipe(res);
  doc.fontSize(20).text(title);
  doc.end();
}