dyslibria-converter

dyslibria-converter

Install `dyslibria-converter`, run it from Node.js or the CLI, and understand the runtime expectations before you wire it into your own tools.

5 sectionsDevelopers integrating Dyslibria into scripts, apps, workers, or CI.

What you'll cover

  • Published as `dyslibria-converter`
  • CLI binary: `dyslibria-convert`
  • Targets Node.js 20 or newer
  • The same package powers the self-hosted library

Chapter 1 · 5 min read

Package quick start

Install

The package ships a Node.js API together with a small CLI. Install it into any Node 20+ project that needs EPUB inspection or Dyslibria conversion without the rest of the application stack.

Install from npm

terminal · bash

npm install dyslibria-converter

Your first conversion

If you do not provide a preset or custom profile, the converter falls back to Dyslibria Default. By default it also returns an in-memory `outputBuffer` as well as the inspection and stats object. If you only want a file written to disk, pass `returnBuffer: false` to skip holding the output in memory.

Minimal Node example

convert-book.ts · ts

import { convertBook } from 'dyslibria-converter';

const result = await convertBook('./books/input.epub', {
  outputPath: './books/input.dyslibria.epub',
  presetId: 'intense-scaffolding',
});

console.log(result.outputPath);
console.log(result.stats.processedFiles);
console.log(result.inspection.title);

What `convertBook` returns

  • `inspection`: title, author, warnings, HTML entry list, and cover metadata
  • `stats`: processed file count, skipped file count, duration, input bytes, and output bytes
  • `outputPath`: present when you provide `outputPath`
  • `outputBuffer`: present by default unless `returnBuffer` is set to `false`

Chapter 2 · 8 min read

Node.js API reference

Use file paths, buffers, streams, or custom converter instances depending on the shape of your own application.

  • Supports path, buffer, and stream inputs
  • `createConverter()` for reusable instances
  • Deterministic output is enabled by default
  • Safety limits protect archive extraction

Accepted input types

The converter API accepts more than a plain file path. You can pass a string path, a `Buffer`, a `Uint8Array`, a readable stream, or an object wrapper containing a path, buffer, or stream with an optional filename.

That flexibility makes it easy to use in web workers, message consumers, or custom upload flows where the EPUB is already in memory.

Buffer and stream inputs

inputs.ts · ts

import fs from 'node:fs';
import { convertBook } from 'dyslibria-converter';

const bufferResult = await convertBook({
  buffer: await fs.promises.readFile('./books/source.epub'),
  filename: 'source.epub',
});

const streamResult = await convertBook({
  stream: fs.createReadStream('./books/source.epub'),
  filename: 'source.epub',
}, {
  outputPath: './books/source.dyslibria.epub',
  returnBuffer: false,
});

Important options

  • `outputPath`: copy the finished EPUB to a stable path you choose
  • `returnBuffer`: keep or skip the in-memory output buffer
  • `presetId`: select a built-in preset such as `intense-scaffolding` (Dyslibria Default) or `dyslibria-balanced`
  • `profile` or `profilePath`: pass a full custom profile JSON or a reader-configuration export from the typography lab
  • `deterministic`: keep reproducible output packaging enabled
  • `dictionary` or `dictionaryPath`: override the word list used by the transform
  • `tempRootDir`: choose where temporary workspaces are created
  • `maxArchiveEntries` and `maxExtractBytes`: adjust archive-safety limits

Reusable converter instances

If you prefer to hide the static functions behind a reusable object, `createConverter()` exposes the same conversion capability through an instance-style interface. That can be convenient in dependency-injected services or background worker classes.

Using createConverter

converter-service.ts · ts

import { createConverter } from 'dyslibria-converter';

const converter = createConverter();

export async function convertFromQueue(inputPath: string, outputPath: string) {
  return converter.convertBook(inputPath, {
    outputPath,
    returnBuffer: false,
  });
}

Chapter 3 · 7 min read

Inspection, logging, and error handling

Inspect EPUBs before conversion, stream structured log events into your own observability tooling, and respond to package-specific error classes.

  • `inspectBook()` reads metadata without converting
  • Structured logger callback with step and level
  • Typed error classes for invalid EPUBs and safety failures
  • Cover entry information is surfaced during inspection

Use `inspectBook()` when you want metadata first

Inspection is useful when you want to show a title, author, warnings list, or cover entry before deciding whether to run a full conversion. It is also a good fit for validation endpoints and content triage tools.

Inspect an EPUB

inspect-book.ts · ts

import { inspectBook } from 'dyslibria-converter';

const inspection = await inspectBook('./books/source.epub');

console.log(inspection.title);
console.log(inspection.author);
console.log(inspection.coverEntryName);
console.log(inspection.warnings);

Structured logging

Pass a `logger` callback to receive structured events for each stage of the pipeline. Each event includes a log level, a step name, a message, and optional details.

This is the easiest way to wire the converter into your own app logs without parsing arbitrary console output.

Conversion logger

logger.ts · ts

import { convertBook } from 'dyslibria-converter';

await convertBook('./books/source.epub', {
  outputPath: './books/source.dyslibria.epub',
  logger(event) {
    if (event.level === 'debug') return;

    console.log(`[${event.level}] [${event.step}] ${event.message}`, event.details ?? {});
  },
});

Error classes worth catching

  • `InvalidEpubError` for archives that are not valid EPUBs
  • `ArchiveSafetyError` for extraction hazards such as zip-slip style paths or over-large archives
  • `NoContentFilesError` when no HTML or XHTML content was found to process
  • `ConversionStepError` when a specific pipeline stage fails and you want step context

A practical catch block

Typed error handling

error-handling.ts · ts

import {
  ArchiveSafetyError,
  ConversionStepError,
  InvalidEpubError,
  convertBook,
} from 'dyslibria-converter';

try {
  await convertBook('./books/source.epub');
} catch (error) {
  if (error instanceof InvalidEpubError) {
    console.error('The upload is not a valid EPUB.');
  } else if (error instanceof ArchiveSafetyError) {
    console.error('The EPUB failed safety checks.');
  } else if (error instanceof ConversionStepError) {
    console.error('Conversion failed during step:', error.context?.step);
  } else {
    console.error('Unexpected converter error:', error);
  }
}

Chapter 4 · 4 min read

CLI usage

Use the CLI for quick local conversions, inspection runs, and simple shell-driven workflows without writing any Node code.

  • Binary name: `dyslibria-convert`
  • `convert` and `inspect` subcommands
  • Optional `--output`, `--preset`, and `--profile` flags
  • Default output naming appends `.dyslibria.epub`

CLI commands

Usage

terminal · bash

dyslibria-convert convert <input.epub> [--output <output.epub>] [--preset <preset-id>] [--profile <profile.json>]
dyslibria-convert inspect <input.epub>

Convert a book from the command line

If you do not pass `--output`, the CLI writes the result beside the input file using the pattern `name.dyslibria.epub`. If you do not pass `--preset` or `--profile`, the CLI uses Dyslibria Default.

Convert

terminal · bash

npx dyslibria-convert convert ./books/input.epub
npx dyslibria-convert convert ./books/input.epub --preset intense-scaffolding
npx dyslibria-convert convert ./books/input.epub --profile ./profiles/custom-profile.json --output ./books/output.epub

Inspect without converting

The inspect command prints a formatted JSON object with title, author, warnings, and other metadata fields, which makes it handy inside shell scripts and CI checks.

Inspect

terminal · bash

npx dyslibria-convert inspect ./books/input.epub

Chapter 5 · 6 min read

Release and regression workflow

Use the package like a real maintainer would: build it, run tests, dry-run the published tarball, and validate it against a trusted private EPUB corpus.

  • `npm run release:check` before publishing
  • `npm pack --dry-run` included
  • Real-world regression script supported
  • Private manifests can target hand-picked regression books

Release check

Before publishing a new version, run the built-in release check. It covers unit and parity tests, the package build, and a dry-run pack step so you can confirm the published tarball shape before npm sees it.

Release check

terminal · bash

npm test
npm run build
npm run release:check

Real-world regression runs

Synthetic fixtures are essential, but real EPUB corpora catch the awkward edge cases that only appear in the wild. The package includes a regression runner so you can point the current build at a trusted local corpus before a release.

Batch regression run

terminal · bash

npm run build
npm run qa:real-world -- \
  --input-dir /path/to/raw-epubs \
  --output-dir ./reports/real-world-output \
  --report ./reports/real-world-regression.json

Target a smaller release-candidate subset

If you keep a hand-picked private manifest for especially valuable books, the real-world regression runner can process just that shortlist. This is a good habit when you have a known set of titles that historically reveal regressions.

Manifest-driven run

terminal · bash

npm run qa:real-world -- \
  --input-dir /path/to/raw-epubs \
  --manifest ./fixtures/local/release-candidate.json \
  --output-dir ./reports/regression-output \
  --report ./reports/regression-report.json

Cookies

Dyslibria currently uses essential browser storage only. It remembers your theme, reader-demo preferences, and that you dismissed this notice. We do not currently use optional analytics or advertising cookies.

Read the cookie policy for the full details.