epubcheck-ts
    Preparing search index...

    epubcheck-ts

    epubcheck-ts

    Validate EPUB files in Node.js and the browser. A TypeScript implementation of EPUBCheck.

    CI npm License

    Status: Measured against EPUBCheck 5.4.0 across 763 spec fixtures — 95.9% agreement on whether a publication is valid, 87.5% agreement on which errors and warnings are reported. See PROJECT_STATUS.md for the full breakdown and methodology. For formal EPUB 3 conformance certification, use the official Java EPUBCheck.

    • CLI and API — Use as a CLI tool (npx @likecoin/epubcheck-ts book.epub) or import as a library
    • Browser support — Works in Node.js 18+ and modern browsers via pure JS + WASM
    • No native dependencies — No Java, no compilation — npm install and go
    • TypeScript — Full type definitions included
    • Tree-shakable — ESM with proper exports for minimal bundle impact

    Live demo at likecoin.github.io/epubcheck-ts — validate EPUB files in the browser without uploading to any server.

    npm install @likecoin/epubcheck-ts
    

    Quick validation:

    npx @likecoin/epubcheck-ts book.epub
    

    Or install globally:

    npm install -g @likecoin/epubcheck-ts
    epubcheck-ts book.epub

    CLI Options:

    epubcheck-ts <file.epub> [options]

    Options:
    -j, --json <file> Output JSON report to file (use '-' for stdout)
    -q, --quiet Suppress console output (errors only)
    -p, --profile <name> Validation profile (default|dict|edupub|idx|preview)
    -m, --mode <type> Validation mode: exp (expanded directory), opf, xhtml, svg, nav, mo
    -v, --epub-version <ver> EPUB version for single-file mode (2|2.0|3|3.0|3.1|3.2|3.3)
    -u, --usage Include usage messages (best practices)
    -f, --fatal Show only fatal errors
    -e, --error Show fatal errors and errors
    -w, --warn Show fatal errors, errors, and warnings
    -i, --info Show fatal, error, warning, and info messages
    -c, --customMessages <file> Override message severities (TSV: ID<tab>SEVERITY)
    --fail-on-warnings Exit with code 1 if warnings are found
    (also accepts --failonwarnings for Java compatibility)
    -l, --listChecks List all message IDs and severities
    -V, --version Show version information
    -h, --help Show this help message

    -w and --fail-on-warnings are different options: -w only widens which messages are displayed, while --fail-on-warnings changes the exit code. Use the latter in CI. Note also that -V shows the version — -v takes an EPUB version for single-file mode.

    Examples:

    # Basic validation
    epubcheck-ts book.epub

    # Generate JSON report
    epubcheck-ts book.epub --json report.json

    # Quiet mode for CI/CD
    epubcheck-ts book.epub --quiet --fail-on-warnings

    # Validate with specific profile
    epubcheck-ts dictionary.epub --profile dict

    # Show only errors (hide warnings/info)
    epubcheck-ts book.epub --error

    # Enable suppressed accessibility checks
    printf "ACC-004\tWARNING\nACC-005\tWARNING\n" > overrides.txt
    epubcheck-ts book.epub -c overrides.txt
    import { EpubCheck } from '@likecoin/epubcheck-ts';
    import { readFile } from 'node:fs/promises';

    // Load EPUB file
    const epubData = await readFile('book.epub');

    // Validate
    const result = await EpubCheck.validate(epubData);

    if (result.valid) {
    console.log('EPUB is valid!');
    } else {
    console.log(`Found ${result.errorCount} errors and ${result.warningCount} warnings`);

    for (const message of result.messages) {
    console.log(`${message.severity}: ${message.message}`);
    if (message.location) {
    console.log(` at ${message.location.path}:${message.location.line}`);
    }
    }
    }
    const fs = require('node:fs');

    async function validate() {
    const { EpubCheck } = require('@likecoin/epubcheck-ts');

    const epubData = fs.readFileSync('book.epub');
    const result = await EpubCheck.validate(epubData);

    console.log(result.valid ? 'Valid!' : 'Invalid');
    }

    validate();

    The XML engine (libxml2-wasm, ESM-only with top-level await) is lazy-loaded inside EpubCheck.validate(), so the package stays require()-able from CommonJS and importable without forcing top-level-await support on your bundler.

    import { EpubCheck } from '@likecoin/epubcheck-ts';

    // From file input
    const fileInput = document.querySelector('input[type="file"]');
    fileInput.addEventListener('change', async (event) => {
    const file = event.target.files[0];
    const data = new Uint8Array(await file.arrayBuffer());

    const result = await EpubCheck.validate(data);
    console.log(result);
    });

    Full API reference: online | markdown

    Static method to validate an EPUB file.

    Parameters:

    • data: Uint8Array - The EPUB file contents
    • options?: EpubCheckOptions - Optional validation options

    Returns: Promise<EpubCheckResult>

    Create a reusable validator instance.

    const checker = new EpubCheck({
    version: '3.3',
    profile: 'default',
    locale: 'en',
    });

    const result1 = await checker.check(epub1Data);
    const result2 = await checker.check(epub2Data);
    interface EpubCheckOptions {
    /** EPUB version to validate against (auto-detected if not specified) */
    version?: '2.0' | '3.0' | '3.1' | '3.2' | '3.3';

    /** Validation profile */
    profile?: 'default' | 'edupub' | 'idx' | 'dict' | 'preview';

    /** Include usage messages in results (default: false) */
    includeUsage?: boolean;

    /** Include info messages in results (default: true) */
    includeInfo?: boolean;

    /** Maximum errors before stopping, 0 = unlimited (default: 0) */
    maxErrors?: number;

    /** Locale for messages (default: 'en') */
    locale?: string;

    /** Custom message severity overrides (message ID → severity) */
    customMessages?: Map<string, MessageSeverity>;
    }
    interface EpubCheckResult {
    /** Whether the EPUB is valid (no errors or fatal errors) */
    valid: boolean;

    /** All validation messages */
    messages: ValidationMessage[];

    /** Counts by severity */
    fatalCount: number;
    errorCount: number;
    warningCount: number;
    infoCount: number;
    usageCount: number;

    /** Detected EPUB version */
    version?: string;

    /** Validation time in milliseconds */
    elapsedMs: number;
    }

    interface ValidationMessage {
    /** Unique message identifier (e.g., 'OPF-001') */
    id: string;

    /** Severity level */
    severity: 'fatal' | 'error' | 'warning' | 'info' | 'usage';

    /** Human-readable message */
    message: string;

    /** Location in the EPUB */
    location?: {
    path: string;
    line?: number;
    column?: number;
    context?: string;
    };

    /** Suggestion for fixing the issue */
    suggestion?: string;
    }

    Generate a JSON report compatible with the original EPUBCheck:

    import { EpubCheck, Report } from '@likecoin/epubcheck-ts';

    const result = await EpubCheck.validate(data);
    const jsonReport = Report.toJSON(result);
    console.log(jsonReport);
    Environment Version Notes
    Node.js 18+ Full support
    Chrome 89+ Full support
    Firefox 89+ Full support
    Safari 15+ Full support
    Edge 89+ Full support

    This library is a TypeScript port of the Java-based EPUBCheck tool maintained by the W3C. Key implementation details:

    • XML Processing: Uses libxml2-wasm for XML parsing and schema validation (RelaxNG, XSD) via WebAssembly
    • ZIP Handling: Uses fflate for fast, lightweight EPUB container processing
    • CSS Validation: Uses css-tree for CSS parsing and validation
    • Schematron rules: Hand-ported to TypeScript rather than evaluated from .sch files — there is no Schematron engine, so the three runtime dependencies above are the whole list
    Component Status Completeness Notes
    OCF Container 🟢 Complete ~92% ZIP structure, mimetype, container.xml, encryption.xml obfuscation
    Package Document (OPF) 🟢 Complete ~92% Metadata, manifest, spine, collections, Schematron-equivalent checks
    Content Documents 🟢 Complete ~93% XHTML structure, CSS url(), @import, SVG, entities, title, SSML, XML version
    Navigation Document 🟢 Complete ~95% Nav content model, landmarks, labels, reading order, hidden, nested-ol
    Schema Validation 🟡 Partial ~55% RelaxNG for OPF/container; XHTML/SVG disabled (libxml2 limitation)
    CSS 🟡 Partial ~85% @font-face, @import, url() extraction, position, forbidden properties, alt style tags
    Cross-reference Validation 🟢 Complete ~92% Reference tracking, fragments, fallbacks, remote resources, cross-document features
    Accessibility Checks 🟢 Complete ~71% 12/17 ACC checks: table, image alt, hyperlink, MathML, SVG, epub:type, OPF metadata
    Media Overlays 🟡 Partial ~70% SMIL structure, timing, audio, OPF metadata, duration validation
    Media Validation 🟡 Partial ~25% Magic number checks (MED-004/OPF-029/PKG-022); deep format parsing planned

    Legend: 🟢 Complete | 🟡 Partial | 🔴 Basic | ❌ Not Started

    The percentages above are per-component estimates. For what actually matters — whether this tool and Java EPUBCheck reach the same verdict on the same file — see the measured figures in PROJECT_STATUS.md: 97% valid/invalid agreement and 88% error/warning agreement across 758 fixtures, with the remaining differences enumerated.

    • Node.js 18+
    • npm 9+
    # Clone the repository
    git clone https://github.com/likecoin/epubcheck-ts.git
    cd epubcheck-ts

    # Install dependencies
    npm install

    # Run tests
    npm test

    # Build
    npm run build
    Script Description
    npm run build Build the library (ESM + CJS)
    npm run dev Build in watch mode
    npm test Run tests in watch mode
    npm run test:run Run tests once
    npm run test:coverage Run tests with coverage
    npm run lint Lint with ESLint
    npm run lint:fix Lint and auto-fix
    npm run format Format with Biome
    npm run typecheck TypeScript type checking
    npm run check Run all checks (format + typecheck)
    npm run docs Generate API docs (HTML + Markdown)
    npm run docs:html Generate HTML API docs to docs/html/
    npm run docs:md Generate Markdown API docs to docs/md/
    epubcheck-ts/
    ├── src/
    │ ├── index.ts # Public API exports
    │ ├── checker.ts # Main EpubCheck class
    │ ├── types.ts # TypeScript type definitions
    │ ├── core/ # Core validation logic
    │ ├── ocf/ # OCF container validation ✅
    │ ├── opf/ # Package document validation ✅
    │ ├── content/ # Content document validation ✅
    │ ├── nav/ # Navigation validation ✅
    │ ├── ncx/ # NCX validation (EPUB 2) ✅
    │ ├── references/ # Cross-reference validation ✅
    │ ├── schema/ # Schema validation ✅
    │ │ ├── relaxng.ts # RelaxNG validation
    │ │ ├── xsd.ts # XSD validation
    │ │ └── orchestrator.ts # Schema orchestration
    │ └── messages/ # Error messages
    ├── schemas/ # Schema files (RNG, RNC, XSD)
    ├── test/
    │ ├── fixtures/ # Test EPUB files
    │ └── integration/ # Integration tests
    ├── docs/
    │ └── md/ # Generated API docs (Markdown, checked in)
    ├── examples/
    │ └── web/ # Web demo ✅
    └── dist/ # Build output

    Legend: ✅ Implemented

    Aspect epubcheck-ts EPUBCheck (Java)
    Runtime Node.js / Browser JVM
    Verdict agreement 97% (measured, n=758) Baseline
    Bundle Size ~450KB JS + ~1.6MB WASM ~15MB
    Installation npm install Download JAR
    Integration Native JS/TS CLI or Java API
    Performance Comparable Baseline

    See PROJECT_STATUS.md for detailed feature comparison.

    Contributions are welcome! Please read CONTRIBUTING.md for guidelines.

    For AI agents contributing to this project, see AGENTS.md.

    BSD-3-Clause — the same license as the Java EPUBCheck. Releases up to and including 0.6.5 were published under GPL-3.0; 0.7.0 is the first BSD-3-Clause release.

    This is an independent TypeScript implementation of the Java EPUBCheck: the validation logic is written from scratch, not translated line by line. The RELAX NG schemas, the message identifiers and their wording, and the test fixtures do come from the original project — along with the Nu Html Checker (MIT) and W3C MathML/SVG schemas it bundles. THIRD_PARTY_NOTICES.md reproduces the notices those require, and ships with the package.

    This project is built and maintained by the 3ook.com team. 3ook is a Web3 eBook platform where authors can publish EPUB ebooks and readers can collect them as digital assets. If you're an author looking to publish your ebook, check out 3ook.com.