CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-pdfkit

A PDF generation library for Node.js with comprehensive text, graphics, and form support

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

vector-graphics.mddocs/

Vector Graphics

Comprehensive vector graphics with path construction, shapes, transformations, and painting operations using an HTML5 canvas-like API.

Capabilities

Graphics State Management

Methods for saving and restoring graphics state for isolated transformations and styling.

/**
 * Save current graphics state
 * @returns Document instance for chaining
 */
save(): PDFDocument;

/**
 * Restore previously saved graphics state
 * @returns Document instance for chaining
 */
restore(): PDFDocument;

Usage Examples:

// Use save/restore for isolated transformations
doc.save()
   .translate(100, 100)
   .rotate(45)
   .rect(0, 0, 50, 50)
   .fill('red')
   .restore();

// Continue with original coordinate system
doc.rect(200, 100, 50, 50)
   .fill('blue');

Path Construction

Low-level path construction methods for creating custom shapes.

/**
 * Move to point without drawing
 * @param x - X coordinate
 * @param y - Y coordinate
 * @returns Document instance for chaining
 */
moveTo(x: number, y: number): PDFDocument;

/**
 * Draw line to point
 * @param x - X coordinate
 * @param y - Y coordinate
 * @returns Document instance for chaining
 */
lineTo(x: number, y: number): PDFDocument;

/**
 * Draw cubic Bezier curve
 * @param cp1x - First control point X
 * @param cp1y - First control point Y
 * @param cp2x - Second control point X
 * @param cp2y - Second control point Y
 * @param x - End point X
 * @param y - End point Y
 * @returns Document instance for chaining
 */
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): PDFDocument;

/**
 * Draw quadratic curve
 * @param cpx - Control point X
 * @param cpy - Control point Y
 * @param x - End point X
 * @param y - End point Y
 * @returns Document instance for chaining
 */
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): PDFDocument;

/**
 * Close current path
 * @returns Document instance for chaining
 */
closePath(): PDFDocument;

Usage Examples:

// Draw custom shape with path construction
doc.moveTo(100, 100)
   .lineTo(200, 150)
   .quadraticCurveTo(250, 100, 300, 150)
   .lineTo(250, 200)
   .closePath()
   .fillAndStroke('lightblue', 'navy');

// Complex curve
doc.moveTo(50, 300)
   .bezierCurveTo(50, 250, 150, 250, 150, 300)
   .bezierCurveTo(150, 350, 50, 350, 50, 300)
   .stroke('purple');

Shape Primitives

High-level methods for creating common geometric shapes.

/**
 * Draw rectangle
 * @param x - X coordinate
 * @param y - Y coordinate
 * @param w - Width
 * @param h - Height
 * @returns Document instance for chaining
 */
rect(x: number, y: number, w: number, h: number): PDFDocument;

/**
 * Draw rounded rectangle
 * @param x - X coordinate
 * @param y - Y coordinate
 * @param w - Width
 * @param h - Height
 * @param r - Corner radius
 * @returns Document instance for chaining
 */
roundedRect(x: number, y: number, w: number, h: number, r: number): PDFDocument;

/**
 * Draw ellipse
 * @param x - Center X coordinate
 * @param y - Center Y coordinate
 * @param r1 - Horizontal radius
 * @param r2 - Vertical radius (optional, defaults to r1 for circle)
 * @returns Document instance for chaining
 */
ellipse(x: number, y: number, r1: number, r2?: number): PDFDocument;

/**
 * Draw circle
 * @param x - Center X coordinate
 * @param y - Center Y coordinate
 * @param radius - Circle radius
 * @returns Document instance for chaining
 */
circle(x: number, y: number, radius: number): PDFDocument;

/**
 * Draw arc
 * @param x - Center X coordinate
 * @param y - Center Y coordinate
 * @param radius - Arc radius
 * @param startAngle - Start angle in radians
 * @param endAngle - End angle in radians
 * @param anticlockwise - Draw counterclockwise
 * @returns Document instance for chaining
 */
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, anticlockwise?: boolean): PDFDocument;

/**
 * Draw polygon from points
 * @param points - Array of [x, y] coordinate pairs
 * @returns Document instance for chaining
 */
polygon(...points: [number, number][]): PDFDocument;

Usage Examples:

// Basic shapes
doc.rect(100, 100, 150, 100)
   .fill('lightgreen');

doc.circle(300, 150, 50)
   .stroke('red');

doc.roundedRect(100, 250, 150, 100, 10)
   .fillAndStroke('yellow', 'orange');

// Ellipse and arc
doc.ellipse(400, 150, 60, 40)
   .fill('pink');

doc.arc(200, 400, 50, 0, Math.PI, false)
   .stroke('blue');

// Polygon (triangle)
doc.polygon([100, 500], [150, 450], [200, 500])
   .fill('purple');

SVG Path Support

Support for rendering SVG path strings.

/**
 * Render SVG path string
 * @param path - SVG path data string
 * @returns Document instance for chaining
 */
path(path: string): PDFDocument;

Usage Examples:

// SVG path for complex shape
const heartPath = 'M12,21.35l-1.45-1.32C5.4,15.36,2,12.28,2,8.5 C2,5.42,4.42,3,7.5,3c1.74,0,3.41,0.81,4.5,2.09C13.09,3.81,14.76,3,16.5,3 C19.58,3,22,5.42,22,8.5c0,3.78-3.4,6.86-8.55,11.54L12,21.35z';

doc.save()
   .translate(200, 200)
   .scale(3)
   .path(heartPath)
   .fill('red')
   .restore();

Line Styling

Methods for configuring line appearance and stroke properties.

/**
 * Set line width
 * @param w - Line width in points
 * @returns Document instance for chaining
 */
lineWidth(w: number): PDFDocument;

/**
 * Set line cap style
 * @param style - Cap style
 * @returns Document instance for chaining
 */
lineCap(style: 'BUTT' | 'ROUND' | 'SQUARE' | 0 | 1 | 2): PDFDocument;

/**
 * Set line join style
 * @param style - Join style
 * @returns Document instance for chaining
 */
lineJoin(style: 'MITER' | 'ROUND' | 'BEVEL' | 0 | 1 | 2): PDFDocument;

/**
 * Set miter limit for sharp joins
 * @param limit - Miter limit
 * @returns Document instance for chaining
 */
miterLimit(limit: number): PDFDocument;

/**
 * Set dash pattern
 * @param length - Dash length or pattern array
 * @param options - Dash options
 * @returns Document instance for chaining
 */
dash(length: number | number[], options?: DashOptions): PDFDocument;

/**
 * Remove dash pattern (solid line)
 * @returns Document instance for chaining
 */
undash(): PDFDocument;

interface DashOptions {
  /** Phase offset for dash pattern */
  phase?: number;
  /** Space between dashes */
  space?: number;
}

Usage Examples:

// Different line styles
doc.lineWidth(5)
   .lineCap('round')
   .moveTo(100, 100)
   .lineTo(200, 100)
   .stroke('blue');

doc.lineWidth(3)
   .dash(5, { space: 3 })
   .rect(100, 150, 100, 50)
   .stroke('green');

doc.lineWidth(2)
   .dash([10, 5, 2, 5])  // Complex dash pattern
   .circle(300, 175, 40)
   .stroke('red');

// Remove dash for solid line
doc.undash()
   .lineWidth(1)
   .rect(100, 250, 100, 50)
   .stroke('black');

Painting Operations

Methods for filling and stroking paths with colors and effects.

/**
 * Fill current path
 * @param color - Fill color (optional)
 * @param rule - Fill rule for complex paths
 * @returns Document instance for chaining
 */
fill(color?: ColorValue, rule?: 'nonzero' | 'evenodd'): PDFDocument;

/**
 * Stroke current path
 * @param color - Stroke color (optional)
 * @returns Document instance for chaining
 */
stroke(color?: ColorValue): PDFDocument;

/**
 * Fill and stroke current path
 * @param fillColor - Fill color (optional)
 * @param strokeColor - Stroke color (optional)
 * @param rule - Fill rule
 * @returns Document instance for chaining
 */
fillAndStroke(fillColor?: ColorValue, strokeColor?: ColorValue, rule?: 'nonzero' | 'evenodd'): PDFDocument;

/**
 * Set clipping path
 * @param rule - Clipping rule
 * @returns Document instance for chaining
 */
clip(rule?: 'nonzero' | 'evenodd'): PDFDocument;

type ColorValue = string | [number, number, number] | [number, number, number, number] | Gradient | Pattern;

Usage Examples:

// Different painting operations
doc.rect(100, 100, 100, 50)
   .fill('lightblue');

doc.circle(300, 125, 40)
   .stroke('red');

doc.roundedRect(100, 200, 100, 50, 5)
   .fillAndStroke('yellow', 'orange');

// Using clipping
doc.save()
   .circle(200, 300, 50)
   .clip()
   .rect(150, 250, 100, 100)
   .fill('purple')
   .restore();

Coordinate Transformations

Methods for transforming the coordinate system.

/**
 * Apply transformation matrix
 * @param m11 - Horizontal scaling
 * @param m12 - Horizontal skewing
 * @param m21 - Vertical skewing
 * @param m22 - Vertical scaling
 * @param dx - Horizontal translation
 * @param dy - Vertical translation
 * @returns Document instance for chaining
 */
transform(m11: number, m12: number, m21: number, m22: number, dx: number, dy: number): PDFDocument;

/**
 * Translate coordinate system
 * @param x - X translation
 * @param y - Y translation
 * @returns Document instance for chaining
 */
translate(x: number, y: number): PDFDocument;

/**
 * Rotate coordinate system
 * @param angle - Rotation angle in degrees
 * @param options - Rotation options
 * @returns Document instance for chaining
 */
rotate(angle: number, options?: RotateOptions): PDFDocument;

/**
 * Scale coordinate system
 * @param xFactor - Horizontal scale factor
 * @param yFactor - Vertical scale factor (optional, defaults to xFactor)
 * @param options - Scale options
 * @returns Document instance for chaining
 */
scale(xFactor: number, yFactor?: number, options?: TransformOptions): PDFDocument;

interface RotateOptions {
  /** Origin point for rotation */
  origin?: [number, number];
}

interface TransformOptions {
  /** Origin point for transformation */
  origin?: [number, number];
}

Usage Examples:

// Translation
doc.save()
   .translate(200, 200)
   .rect(0, 0, 50, 50)  // Actually drawn at (200, 200)
   .fill('red')
   .restore();

// Rotation
doc.save()
   .translate(300, 300)
   .rotate(45)
   .rect(-25, -25, 50, 50)  // Rotated square
   .fill('blue')
   .restore();

// Scale
doc.save()
   .translate(400, 200)
   .scale(2, 0.5)  // 2x width, 0.5x height
   .rect(0, 0, 50, 50)
   .fill('green')
   .restore();

// Complex transformation
doc.save()
   .transform(1, 0.5, 0, 1, 100, 400)  // Shear transformation
   .rect(0, 0, 100, 50)
   .fill('purple')
   .restore();

Coordinate System

PDFKit uses a coordinate system where:

  • Origin (0,0) is at the bottom-left corner of the page
  • X-axis increases to the right
  • Y-axis increases upward
  • Units are in points (1/72 inch)
  • Page coordinates account for margins automatically

Path Winding Rules

For complex self-intersecting paths, PDFKit supports two fill rules:

  • nonzero: Default rule, fills based on path direction
  • evenodd: Alternates filled/unfilled for overlapping areas

Performance Tips

  • Use save()/restore() instead of manual state tracking
  • Combine multiple shapes in a single path when possible
  • Use appropriate line caps and joins for the desired appearance
  • Consider using clip() for masking complex graphics

Install with Tessl CLI

npx tessl i tessl/npm-pdfkit

docs

accessibility-features.md

attachments.md

color-management.md

document-management.md

font-management.md

image-handling.md

index.md

interactive-elements.md

outline.md

tables.md

text-rendering.md

vector-graphics.md

tile.json