Skip to content

Repository files navigation

calibre-node

NPM Version NPM Downloads

calibre-node is a lightweight Node.js module that provides ebook conversion capabilities by wrapping the Calibre CLI tools. It offers built-in queuing and threading to efficiently handle multiple conversions with ease. Please note that this module does not handle the actual conversion algorithms; it interfaces with Calibre's CLI utilities to perform conversions.

Installation

First, ensure that you have Calibre installed on your system, as this module relies on its conversion tools. You can download Calibre from the official website. Make sure that the ebook-convert command is available in your system's PATH.

To test if Calibre is installed correctly, run the following command in your terminal:

ebook-convert --version

To install calibre-node, use npm:

npm install calibre-node

Installing Calibre

The package includes a CLI tool to help install Calibre:

npx calibre-node install calibre

When installing Calibre using the CLI tool, you can specify additional options:

  • --install_dir=*path/to/install*: The directory where Calibre will be installed. The default is ./calibre-bin (root of the project).

Example usage:

npx calibre-node install calibre --install_dir=/custom/path/to/calibre

Usage

After installing both Calibre and calibre-node, you can start converting ebooks in your Node.js application.

const calibre = require('calibre-node');

// Convert an ebook
calibre.convert({
    input: './input/book.pdf',
    output: './output/book.epub',
    delete: false,
    silent: true, // this package's console output
    verbose: 'low' // calibre conversion output verbosity
}).then(response => {
    console.log('Conversion successful:', response);
}).catch(error => {
    console.error('Conversion failed:', error);
});

In this example, a PDF file at ./input/book.pdf is converted to an EPUB file at ./output/book.epub. Set the delete option to true if you want to remove the input file after conversion, and silent to false if you want verbose logging.

Conversion Options

The convert function accepts an object with the following properties:

  • input (string, required): The path to the input file.
  • output (string, required): The path where the output file will be saved, including the desired extension.
  • delete (boolean, optional): Whether to delete the input file after conversion. Default is false.
  • silent (boolean, optional): If set to true, suppresses calibre-node package's console output. Default is true.
  • verbose ("low" | "med" | "high", optional): Sets the verbosity level of calibre conversion output. Default is "low". Any other value is rejected with a clear error rather than being passed through to Calibre.
  • timeoutMs (number, optional): Maximum time the underlying ebook-convert process may run before it is killed with SIGKILL. Default is 120000 (2 minutes). ebook-convert can hang indefinitely on malformed input, so this guarantees a conversion always terminates and never permanently occupies a pool slot.

Additional conversion options supported by Calibre can also be included. Refer to the Calibre conversion documentation for a full list of parameters.

Conversion Result

The conversion promise resolves with a result object containing:

  • success (boolean): Indicates whether the conversion was successful
  • filePath (string): The full path where the converted file was saved
  • filename (string): The name of the converted file without extension
  • extension (string): The file extension of the converted file
  • error (string, optional): Error message if the conversion failed
interface ConversionResult {
    success: boolean;
    filePath: string;
    filename: string;
    extension: string;
    error?: string;
}

Conversion Errors

On failure the promise rejects with a ConversionError. It is a real Error (so it carries a stack trace) and additionally exposes the success, outputPath and error properties that earlier versions rejected with, so existing .catch() handlers keep working unchanged:

class ConversionError extends Error {
    success: false;
    outputPath: string;
    error: string;          // same string as `message`
    stderr?: string;        // ebook-convert's stderr - why Calibre rejected the file
    stdout?: string;
    code?: number | string | null;
    signal?: string | null; // e.g. 'SIGKILL'
    killed?: boolean;
    timedOut?: boolean;     // true when the conversion hung and was killed
    queueFull?: boolean;    // true when the request was refused as backpressure
}

timedOut lets you distinguish "the conversion hung and we killed it" from "Calibre rejected this file", and a partially-written output file is removed automatically on any failure.

calibre.convert({ /* ... */ }).catch(err => {
    if (err.timedOut) console.error('Conversion hung and was killed');
    else if (err.queueFull) console.error('Server busy, retry later');
    else console.error('Calibre said:', err.stderr);
});

Managing the Thread Pool

You can control the number of concurrent conversions by setting the thread pool size:

calibre.setPoolSize(2); // Allows two conversions to run simultaneously. Default is 2.

Worker threads are created only when a pool slot is free, so setPoolSize is a hard bound on concurrent threads and memory, not just on concurrent executions.

Conversions exceeding the pool size are queued and processed as threads become available. The queue is bounded: once maxQueueSize requests are already waiting, further convert() calls reject immediately with queueFull: true instead of the queue growing without limit.

calibre.setMaxQueueSize(100); // Default is 100. Pass Infinity for an unbounded queue.

// Introspection, useful for health checks and metrics:
calibre.getPoolSize();
calibre.getMaxQueueSize();
calibre.getActiveCount();  // conversions currently running
calibre.getPendingCount(); // conversions waiting for a slot

Set Calibre Path

If the ebook-convert command is not in your system's PATH, you can specify the full path to the Calibre CLI tools:

calibre.setCalibrePath('/path/to/calibre');

Contributing

This module is open-source under the MIT license. Contributions, issues, and feature requests are welcome! Feel free to fork and submit pull requests.

Credits

calibre-node is an improvement over the node-ebook-converter package.

About

A lightweight, high-performance Node.js ebook conversion library powered by Calibre, featuring built-in queue management and parallel processing capabilities.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages