CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-qrcode

QR code generator for both server-side and client-side applications with multiple output formats including PNG, SVG, Canvas, and Terminal rendering.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

configuration.mddocs/

Configuration and Options

Comprehensive configuration system for QR code generation parameters and rendering customization. These options apply across all QRCode functions to control QR code structure, appearance, and output format.

QR Code Generation Options

Version Selection

Controls the size and data capacity of the QR code symbol.

interface VersionOptions {
  /** QR Code version (1-40), auto-selected if not specified */
  version?: number;
}

Details:

  • Version 1: 21×21 modules, up to 25 alphanumeric characters
  • Version 40: 177×177 modules, up to 4,296 alphanumeric characters
  • Auto-selection: Uses minimum version that fits the data (recommended)

Examples:

// Auto version (recommended)
QRCode.create('Auto-sized text');

// Specific version
QRCode.create('Fixed size', { version: 5 });

// Version too small (throws error)
try {
  QRCode.create('Very long text that exceeds capacity', { version: 1 });
} catch (err) {
  console.log(err.message); // "The chosen QR Code version cannot contain..."
}

Error Correction Level

Determines how much of the QR code can be damaged while remaining readable.

interface ErrorCorrectionOptions {
  /** Error correction level */
  errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H' | 'low' | 'medium' | 'quartile' | 'high';
}

// Error correction levels with damage tolerance
const ErrorCorrectionLevels = {
  L: '~7%',   // Low
  M: '~15%',  // Medium (default)
  Q: '~25%',  // Quartile  
  H: '~30%'   // High
};

Examples:

// Default (Medium ~15% error correction)
QRCode.create('Standard text');

// High error correction for critical data
QRCode.create('Important data', { errorCorrectionLevel: 'H' });

// Low error correction for size optimization
QRCode.create('Large data', { errorCorrectionLevel: 'L' });

// String formats accepted
QRCode.create('text', { errorCorrectionLevel: 'high' });    // 'high'
QRCode.create('text', { errorCorrectionLevel: 'quartile' }); // 'quartile'
QRCode.create('text', { errorCorrectionLevel: 'Q' });       // 'Q'

Mask Pattern Selection

Controls the pattern used to avoid problematic visual arrangements.

interface MaskOptions {
  /** Mask pattern (0-7), auto-selected if not specified */
  maskPattern?: number;
}

Examples:

// Auto mask selection (recommended)
QRCode.create('Auto mask');

// Specific mask pattern
QRCode.create('Fixed mask', { maskPattern: 3 });

// Invalid mask pattern (ignored, auto-selected)
QRCode.create('text', { maskPattern: 8 }); // Uses auto-selection

Kanji Mode Configuration

Enables optimal encoding of Japanese Kanji characters.

interface KanjiOptions {
  /** Function to convert UTF-8 characters to Shift JIS values */
  toSJISFunc?: (char: string) => number;
}

Examples:

// Node.js Kanji support
const toSJIS = require('qrcode/helper/to-sjis');

QRCode.create('漢字テスト', { 
  toSJISFunc: toSJIS 
});

// Browser Kanji support
// <script src="qrcode.js"></script>
// <script src="qrcode.tosjis.js"></script> 
QRCode.create('漢字', { 
  toSJISFunc: QRCode.toSJIS 
});

// Without Kanji support (uses Byte mode)
QRCode.create('漢字'); // Still works, but less optimal encoding

Rendering Options

Size and Scaling

Controls the physical dimensions of the QR code output.

interface SizeOptions {
  /** Force specific width in pixels (takes precedence over scale) */
  width?: number;
  
  /** Scale factor - 1 means 1px per module */
  scale?: number; // Default: 4
  
  /** Quiet zone margin size in modules */
  margin?: number; // Default: 4
}

Examples:

// Fixed width (overrides scale)
QRCode.toDataURL('Fixed width', { width: 300 });

// Scale factor
QRCode.toDataURL('Scaled', { scale: 8 }); // 8px per module

// No margin
QRCode.toDataURL('No margin', { margin: 0 });

// Large margin
QRCode.toDataURL('Large margin', { margin: 10 });

// Size calculation: final size = (modules + 2*margin) * scale
// Example: Version 1 (21 modules) + margin 4 + scale 4 = (21 + 8) * 4 = 116px

Color Customization

Controls the appearance of QR code modules and background.

interface ColorOptions {
  color?: {
    /** Dark module color in hex RGBA format */
    dark?: string;  // Default: '#000000ff'
    
    /** Light module color in hex RGBA format */  
    light?: string; // Default: '#ffffffff'
  };
}

Examples:

// Custom colors
QRCode.toDataURL('Colored QR', {
  color: {
    dark: '#0066CC',    // Blue modules
    light: '#FFFFFF'    // White background
  }
});

// Transparent background
QRCode.toDataURL('Transparent', {
  color: {
    dark: '#000000',
    light: '#00000000'  // Transparent background
  }
});

// High contrast
QRCode.toDataURL('High contrast', {
  color: {
    dark: '#000000FF',  // Pure black
    light: '#FFFFFFFF'  // Pure white
  }
});

// Brand colors
QRCode.toDataURL('Brand QR', {
  color: {
    dark: '#FF6B35FF',  // Brand orange
    light: '#F7F7F7FF'  // Light gray
  }
});

Terminal-Specific Options

Options for terminal and console output.

interface TerminalOptions {
  /** Compact terminal output using smaller characters */
  small?: boolean; // Default: false
  
  /** Invert foreground and background colors */
  inverse?: boolean; // Default: false
}

Examples:

// Standard terminal output
QRCode.toString('Terminal', { type: 'terminal' });

// Compact output for small terminals
QRCode.toString('Compact', { 
  type: 'terminal', 
  small: true 
});

// Inverted colors
QRCode.toString('Inverted', {
  type: 'terminal',
  inverse: true
});

// Combined terminal options
QRCode.toString('Custom terminal', {
  type: 'terminal',
  small: true,
  inverse: true
});

Format-Specific Options

PNG Options

PNG-specific rendering configuration (Node.js only).

interface PNGOptions {
  type?: 'png';
  
  /** PNG-specific renderer options */
  rendererOpts?: {
    /** Deflate compression level (0-9) */
    deflateLevel?: number;     // Default: 9
    
    /** Deflate compression strategy (0-3) */
    deflateStrategy?: number;  // Default: 3
  };
}

Examples:

// Maximum compression (default)
QRCode.toFile('compressed.png', 'text', {
  type: 'png',
  rendererOpts: {
    deflateLevel: 9,      // Best compression
    deflateStrategy: 3    // Default strategy
  }
});

// Fast compression
QRCode.toFile('fast.png', 'text', {
  type: 'png',
  rendererOpts: {
    deflateLevel: 1,      // Fastest compression
    deflateStrategy: 0    // Speed-optimized
  }
});

// No compression  
QRCode.toFile('uncompressed.png', 'text', {
  type: 'png',
  rendererOpts: {
    deflateLevel: 0       // No compression
  }
});

Data URL Options

Options for browser data URL generation.

interface DataURLOptions {
  /** Image MIME type for data URLs */
  type?: 'image/png' | 'image/jpeg' | 'image/webp'; // Default: 'image/png'
  
  /** Format-specific options */
  rendererOpts?: {
    /** Image quality for JPEG/WebP (0.0 to 1.0) */
    quality?: number; // Default: 0.92
  };
}

Examples:

// PNG data URL (default)
const pngURL = await QRCode.toDataURL('PNG QR');

// JPEG with quality
const jpegURL = await QRCode.toDataURL('JPEG QR', {
  type: 'image/jpeg',
  rendererOpts: { quality: 0.8 }
});

// WebP with high quality
const webpURL = await QRCode.toDataURL('WebP QR', {
  type: 'image/webp', 
  rendererOpts: { quality: 0.95 }
});

// Low quality for smaller size
const lowQualityURL = await QRCode.toDataURL('Small QR', {
  type: 'image/jpeg',
  rendererOpts: { quality: 0.3 }
});

Complete Configuration Examples

High-Quality Print QR Code

const printQR = await QRCode.toFile('print-qr.png', 'https://example.com', {
  version: 3,                    // Fixed size for consistent layout
  errorCorrectionLevel: 'H',     // High error correction for durability
  width: 500,                    // Large size for print clarity
  margin: 6,                     // Extra margin for printing
  color: {
    dark: '#000000FF',           // Pure black for maximum contrast
    light: '#FFFFFFFF'           // Pure white background
  },
  type: 'png',
  rendererOpts: {
    deflateLevel: 9              // Maximum compression for file size
  }
});

Web-Optimized QR Code

const webQR = await QRCode.toDataURL('https://example.com', {
  errorCorrectionLevel: 'M',     // Balanced error correction
  width: 200,                    // Web-appropriate size
  margin: 2,                     // Minimal margin for space efficiency
  color: {
    dark: '#2C3E50',             // Dark blue-gray
    light: '#ECF0F1'             // Light gray
  },
  type: 'image/png'              // PNG for transparency support
});

Mobile-Friendly QR Code

const mobileQR = await QRCode.toCanvas(canvas, 'mobile://action', {
  errorCorrectionLevel: 'Q',     // Higher error correction for camera scanning
  width: 300,                    // Large enough for mobile cameras
  margin: 4,                     // Standard margin
  color: {
    dark: '#1ABC9C',             // Vibrant teal
    light: '#FFFFFF'             // White background
  }
});

Terminal Display QR Code

const terminalQR = await QRCode.toString('Terminal QR', {
  type: 'terminal',
  errorCorrectionLevel: 'L',     // Lower error correction for size
  small: process.stdout.columns < 80,  // Adapt to terminal width
  inverse: false                 // Standard colors
});
console.log(terminalQR);

SVG for Scalable Graphics

const svgQR = await QRCode.toString('https://example.com', {
  type: 'svg',
  width: 400,                    // SVG width attribute
  margin: 3,                     // Moderate margin
  color: {
    dark: '#8E44AD',             // Purple modules
    light: '#F8F9FA'             // Light background
  }
});

Option Validation and Defaults

Default Values

const DefaultOptions = {
  // QR Code options  
  version: undefined,              // Auto-select
  errorCorrectionLevel: 'M',       // Medium (~15% error correction)
  maskPattern: undefined,          // Auto-select
  toSJISFunc: undefined,           // No Kanji support
  
  // Rendering options
  margin: 4,                       // 4 modules quiet zone
  scale: 4,                        // 4px per module
  width: undefined,                // Use scale instead
  color: {
    dark: '#000000ff',             // Black modules
    light: '#ffffffff'             // White background
  },
  
  // Terminal options
  small: false,                    // Full-size terminal output
  inverse: false,                  // Normal colors
  
  // Format options
  type: 'png',                     // Default output type
  rendererOpts: {
    deflateLevel: 9,               // Maximum PNG compression
    deflateStrategy: 3,            // Default PNG strategy
    quality: 0.92                  // JPEG/WebP quality
  }
};

Option Precedence

  1. Explicit options - Options passed to function calls
  2. Format defaults - Default values for specific output formats
  3. Global defaults - Library-wide default values

Validation Rules

// Version validation (1-40)
if (options.version < 1 || options.version > 40) {
  // Uses auto-selection
}

// Error correction level validation
const validECLevels = ['L', 'M', 'Q', 'H', 'low', 'medium', 'quartile', 'high'];
if (!validECLevels.includes(options.errorCorrectionLevel)) {
  // Uses default 'M'
}

// Mask pattern validation (0-7)
if (options.maskPattern < 0 || options.maskPattern > 7) {
  // Uses auto-selection
}

// Color format validation (hex RGBA)
if (!/^#[0-9A-Fa-f]{6,8}$/.test(options.color.dark)) {
  // Uses default color
}

// Width/scale validation
if (options.width && options.width < minRequiredSize) {
  // Ignores width, uses scale
}

Install with Tessl CLI

npx tessl i tessl/npm-qrcode

docs

browser-rendering.md

configuration.md

core-generation.md

index.md

server-operations.md

string-rendering.md

tile.json