npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cloud-convert-private-malcolm

v3.0.0

Published

Local file conversion with chainable TypeScript classes. Conversion uses installed command-line tools; `new Convert()` does not install or run anything.

Readme

Cloud Convert

Local file conversion with chainable TypeScript classes. Conversion uses installed command-line tools; new Convert() does not install or run anything.

import Convert, { ImageFormat } from './index.js';

const result = await new Convert()
    .Image('photo.png', ImageFormat.PNG, { width: 1200 })
    .To('photo.webp', 'webp', { quality: 85 });

// Infer both types from filename extensions.
await new Convert().Image('photo.png', { width: 800 }).To('photo.jpg');
await new Convert().From('photo.png').To('photo.webp', { quality: 80 });

// Explicit types also work for paths without a matching extension.
await new Convert().Image('upload', 'png').To('download', 'webp');

// Reusable source settings; From returns a new independent chain.
const image = new Convert().Image('first.png', { width: 400 });
await image.To('first.webp');
await image.From('second.png', { width: 600 }).To('second.jpg');

.Image, .Audio, .Video, .Archive, .Document, .Font, .Model, and .Pdf accept (inputPath, optionalType, options) or (inputPath, options). .From selects a category from the source extension or explicit type. .To accepts the same argument shapes for the destination and executes the conversion, returning Promise<ConversionResult> with buffer, filename, and mime. The destination path is required and the result is also written there. Destination options override source options with the same key. An existing destination is replaced after the backend succeeds; an input cannot also be its destination.

Type strings and the exported format enums are accepted. Compound extensions such as tar.gz are recognized. Explicit types override extensions. For ambiguous formats, automatic selection treats PDF as the PDF chain, and SVG/GIF as images. Use .Document, .Image, .Font, or .Video explicitly to choose another backend. Types must belong to the selected category; actual format support also depends on the installed backend and its codecs or delegates. .Pdf takes a PDF source and covers OCR, page rendering, text extraction, optimization, and structural edits; .Image('scan.pdf') still routes a PDF through ImageMagick where supported.

const convert = new Convert();
await convert.Audio('recording.wav', { rate: 44100 }).To('recording.flac');
await convert.Video('clip.mp4', { width: 1280 }).To('clip.mkv');
await convert.Document('notes.md').To('notes.html');
await convert.Document('report.docx').To('report.pdf');       // LibreOffice
await convert.Document('sheet.xlsx').To('sheet.csv');          // LibreOffice
await convert.Document('book.epub').To('book.mobi');           // Calibre
await convert.Archive('bundle.zip').To('bundle.7z');
await convert.Font('font.ttf').To('font.woff');
await convert.Model('mesh.obj').To('mesh.stl');
await convert.Pdf('scan.pdf', { language: 'eng', deskew: true }).To('searchable.pdf');
await convert.Pdf('scan.pdf').To('page.png', { dpi: 300, page: 1 });   // Poppler
await convert.Pdf('scan.pdf').To('scan.txt');                          // Poppler
await convert.Pdf('scan.pdf').To('small.pdf', { compress: 'screen' }); // Ghostscript
await convert.Pdf('scan.pdf').To('web.pdf', { linearize: true });      // QPDF
await convert.Font('brand.ttf').To('brand.woff2');                     // WOFF2

await convert.Merge.Images(['one.png', 'two.png'], { direction: 'vertical' }).To('combined.png');
await convert.Merge.Videos(['one.mp4', 'two.mp4']).To('combined.mp4');
await convert.Merge.Pdfs(['one.pdf', 'two.pdf']).To('combined.pdf');

const status = await convert.Tools.Check();
// Explicitly install missing tools via Homebrew when needed:
// await convert.Tools.InstallMissing();

The API returns a single output file. Split archives and PDF merge page numbering are rejected. Backends that produce multiple files or sidecar assets require a separate workflow. The audio converter selects FFmpeg when options such as audio_codec, sample_rate, or strip_metadata require it; select engine: 'sox' or engine: 'ffmpeg' explicitly when needed. Image compress selects lossless/lossy WebP output. Video uses container-aware defaults for MP4, MOV, MKV, WebM, and OGV. Other formats use FFmpeg defaults. Hard subtitles require an FFmpeg build with the subtitles filter (libass).

Layout

index.ts          public entry point
convert/          the Convert factory and one chain class per category
engines/          backend classes that run the external tools
abstract/         shared conversion, staging, cleanup, and merge bases
capabilities/     registry of the routes the engines implement
constants/        formats.ts, mime.ts, matrices.ts, aliases.ts, routing.ts, tools.ts
interfaces/       conversion results, options, and contracts
installer.ts      tool availability checks and Homebrew installation
bin/              install-tools CLI
scripts/          documentation coverage check
tests/            integration checks against the real tools

constants/matrices.ts holds the format lists each backend reads and writes; constants/routing.ts turns those into the backend a route uses. Both the engines and capabilities/ read from them, so the registry cannot claim a route the engines will not run.

This class API replaces the original default object of convert_image, convert_audio, and other functions. Import ConversionResult for the old buffer/filename/MIME result shape; Convert now names the factory class.

Development

npm install
npm run typecheck
npm run docs:check
npm test
npm run check-tools

npm test builds the package and exercises real conversions with ImageMagick, SoX, FFmpeg, Pandoc, LibreOffice, 7-Zip, Assimp, FontForge, WOFF2, OCRmyPDF, Poppler, QPDF, and Ghostscript. Tests whose backend is absent skip rather than fail. Install these tools before running the integration tests. npm run install-tools explicitly installs missing tools via Homebrew. For plain Node.js use the compiled entry point dist/index.js after npm run build; TypeScript consumers can use the source entry point.

Local capabilities

Every conversion runs a command on this machine. The package contains no API client, no API-key configuration, no uploads, and no remote fallback.

Capabilities reports what the engines actually implement, computed from the same backend matrices and routing policy the engines use — 2,395 routes across 135 formats and 14 local backends. Route(input, output) returns the backend a conversion will use; List(filter) and Options(input, output) describe the registry.

const convert = new Convert();
convert.Capabilities.Supports('docx', 'pdf');            // true
convert.Capabilities.Route('docx', 'pdf').backend;       // 'libreoffice'
convert.Capabilities.Route('pdf', 'png').backend;        // 'poppler'
convert.Capabilities.List({ backend: 'calibre' });       // ebook routes

await convert.Image('photo.png').To('photo.jpg', { fit: 'crop', width: 800, height: 800 });

Backends by category:

| Category | Backends | Notes | | --- | --- | --- | | Image | ImageMagick | Also rasterizes PDF, EPS, and PS sources. | | Audio | SoX, FFmpeg | SoX handles its own formats; options such as codecs or metadata stripping select FFmpeg. | | Video | FFmpeg | Container-aware defaults; hard subtitles need a libass build. | | Archive | 7-Zip | Writable formats are listed in ARCHIVE_WRITABLE_FORMATS. | | Document | Pandoc, LibreOffice, Calibre | Markup uses Pandoc; office and spreadsheet formats use LibreOffice; MOBI and AZW3 use Calibre. | | Font | FontForge, WOFF2 | WOFF2 packing and unpacking use woff2_compress and woff2_decompress, bridged by FontForge. | | Model | Assimp | Mesh conversion. | | PDF | OCRmyPDF, Poppler, Ghostscript, QPDF | OCR, page rendering and text extraction, optimization, and structural edits. |

PDF output selects its backend from the options supplied: compress uses Ghostscript, page selection, rotation, encryption, and linearization use QPDF, and OCR settings use OCRmyPDF. Name one explicitly with backend. Document routes pick their backend from the format pair, overridable the same way. Calibre is optional; routes needing it report the missing executable rather than failing silently.