print-check-cli
v1.0.1
Published
CLI tool to validate print-ready PDF files
Readme
print-check-cli
A Node.js + TypeScript CLI tool that validates print-ready PDF files. Runs eight checks and reports pass/warn/fail results in the terminal.
Demo

Checks
| Check | What it validates | | ---------------------- | ------------------------------------------------------------------------------- | | Bleed & Trim | TrimBox/BleedBox presence and minimum bleed dimensions | | Fonts | Font embedding status (embedded, subset, or missing) | | Color Space | CMYK compliance, RGB detection, spot color reporting | | Resolution | Raster image DPI against a configurable minimum | | PDF/X Compliance | PDF/X standard detection (OutputIntents, version, output condition) — info only | | Total Ink Coverage | Maximum ink density (C+M+Y+K %) against configurable limit | | Transparency | Detects unflattened transparency (groups, soft masks, blend modes) | | Page Size | Verifies consistent page dimensions and optional expected size match |
Usage
print-check <file.pdf ...> [options]
Options:
--min-dpi <number> Minimum acceptable DPI (default: 300)
--color-space <mode> Expected color space: cmyk | any (default: cmyk)
--bleed <mm> Required bleed in mm (default: 3)
--max-tac <percent> Maximum total ink coverage % (default: 300)
--page-size <WxH> Expected page size in mm (e.g. 210x297)
--checks <list> Comma-separated checks to run (default: all)
--severity <overrides> Per-check severity: check:level,... (fail|warn|off)
--profile <name> Print profile: standard | magazine | newspaper | large-format
--verbose Show detailed per-page results
--format <type> Output format: text | json (default: text)
-V, --version Output version
-h, --help Show helpExamples
# Run all checks with defaults
print-check flyer.pdf
# Verbose output with custom DPI threshold
print-check flyer.pdf --verbose --min-dpi 150
# Run only font and bleed checks
print-check flyer.pdf --checks fonts,bleed
# Skip color space enforcement
print-check flyer.pdf --color-space any
# JSON output for CI pipelines
print-check flyer.pdf --format json
# Use a built-in profile
print-check flyer.pdf --profile magazine
# Profile with explicit override
print-check flyer.pdf --profile newspaper --min-dpi 300
# Check multiple files at once
print-check flyer.pdf poster.pdf brochure.pdf
# Use shell globbing to check all PDFs in a directory
print-check *.pdf
# Multiple files with JSON output (outputs an array of reports)
print-check *.pdf --format jsonProfiles
Built-in profiles provide preset thresholds for common print scenarios. Explicit CLI flags override profile defaults.
| Profile | minDpi | colorSpace | bleedMm | maxTac | Use case |
| -------------- | ------ | ---------- | ------- | ------ | ---------------------------------- |
| standard | 300 | cmyk | 3 | 300 | General commercial print (default) |
| magazine | 300 | cmyk | 5 | 300 | Magazine / perfect-bound |
| newspaper | 150 | any | 0 | 240 | Newsprint / low-fidelity |
| large-format | 150 | cmyk | 5 | 300 | Banners, posters, signage |
Exit codes
0— all checks passed (or warned)1— one or more checks failed
Severity Overrides
Override the default severity for any check using --severity:
# Downgrade font failures to warnings (exit 0)
print-check flyer.pdf --severity fonts:warn
# Skip transparency check entirely
print-check flyer.pdf --severity transparency:off
# Multiple overrides
print-check flyer.pdf --severity fonts:warn,transparency:off| Level | Behavior |
| ------ | ---------------------------------------------- |
| fail | Default — no change to check result |
| warn | Downgrade any fail result to warn (exit 0) |
| off | Skip the check entirely |
Available check names: bleed, fonts, colorspace, resolution, pdfx, tac, transparency, pagesize.
Configuration
Create a config file to set default options for your project:
.printcheckrc / .printcheckrc.json
{
"minDpi": 300,
"colorSpace": "cmyk",
"bleed": 5,
"maxTac": 300,
"checks": "bleed,fonts,colorspace",
"profile": "magazine",
"severity": {
"fonts": "warn",
"transparency": "off"
}
}printcheck.config.js
export default {
minDpi: 150,
colorSpace: "any",
bleed: 0,
profile: "newspaper",
};Config files are auto-discovered from the current directory upward. CLI flags always override config file values.
Tech Stack
| Package | Purpose | | ------------------------------------------------------- | ----------------------------------------------------------- | | mupdf (mupdf.js) | PDF engine — WASM-powered, deep PDF object traversal | | pdf-lib | Supplemental — reading page boxes (TrimBox, BleedBox, etc.) | | commander | CLI framework | | picocolors | Terminal colors | | zod | CLI option validation | | tsup | TypeScript build | | vitest | Testing |
Project Structure
src/
├── index.ts # CLI entry point (Commander setup)
├── types.ts # Shared interfaces (CheckResult, CheckOptions, etc.)
├── checks/
│ ├── index.ts # Re-exports all checks
│ ├── bleed-trim.ts # Page box validation (pdf-lib)
│ ├── fonts.ts # Font embedding check (mupdf)
│ ├── colorspace.ts # Color space detection (mupdf)
│ ├── resolution.ts # Image DPI check (mupdf)
│ ├── pdfx-compliance.ts # PDF/X standard detection (mupdf)
│ ├── tac.ts # Total ink coverage check (mupdf)
│ ├── transparency.ts # Transparency detection check (mupdf)
│ └── page-size.ts # Page size consistency check (pdf-lib)
├── engine/
│ ├── pdf-engine.ts # Unified PDF document loader (mupdf + pdf-lib)
│ └── pdf-utils.ts # Safe wrappers for mupdf PDFObject API
└── reporter/
├── console.ts # Terminal output formatter
└── json.ts # JSON output formatter (--format json)Development
npm install # Install dependencies (also sets up pre-commit hooks)
npm run dev -- <file> # Run via tsx (no build needed)
npm run build # Build to dist/
npm test # Run vitest
npm run test:coverage # Run with coverage report
npm run lint # ESLint
npm run format:check # Prettier checkSee CONTRIBUTING.md for full development guidelines.
Known Limitations (MVP)
- mupdf PDFObject nulls — mupdf.js returns PDFObject wrappers with
.isNull() === truerather than JavaScriptnull. All mupdf access goes throughsrc/engine/pdf-utils.tssafe wrappers to handle this.
