Node.js Usage
webcvt works in Node.js ≥ 20. The same packages used in the browser run server-side without modification — backends register themselves against the same defaultRegistry.
Installation
bash
npm i @catlabtech/webcvt-core @catlabtech/webcvt-image-canvas
# Or with pnpm:
pnpm add @catlabtech/webcvt-core @catlabtech/webcvt-image-canvasBasic conversion
ts
import { readFile, writeFile } from 'node:fs/promises';
import { convert, defaultRegistry } from '@catlabtech/webcvt-core';
import { CanvasBackend } from '@catlabtech/webcvt-image-canvas';
// Register backend once
defaultRegistry.register(new CanvasBackend());
// Read input file as a Blob
const buffer = await readFile('photo.jpg');
const input = new Blob([buffer], { type: 'image/jpeg' });
// Convert
const result = await convert(input, { format: 'webp', quality: 0.85 });
// Write output
const outBuffer = Buffer.from(await result.blob.arrayBuffer());
await writeFile('photo.webp', outBuffer);
console.log(`Done in ${result.durationMs}ms via ${result.backend}`);Full convert() flow with multiple backends
Register multiple backends in priority order. The registry picks the first one that reports canHandle() as true:
ts
import { convert, defaultRegistry } from '@catlabtech/webcvt-core';
import { CanvasBackend } from '@catlabtech/webcvt-image-canvas';
import { WasmBackend } from '@catlabtech/webcvt-backend-wasm';
// Canvas backend handles common image formats with no WASM overhead
defaultRegistry.register(new CanvasBackend());
// WASM backend handles everything else (video, audio, rare image formats)
defaultRegistry.register(new WasmBackend());
const result = await convert(input, { format: 'mp4' });Subtitle conversion
ts
import { SubtitleBackend } from '@catlabtech/webcvt-subtitle';
import { convert, defaultRegistry } from '@catlabtech/webcvt-core';
import { readFile, writeFile } from 'node:fs/promises';
defaultRegistry.register(new SubtitleBackend());
const buffer = await readFile('subtitles.srt');
const input = new Blob([buffer], { type: 'application/x-subrip' });
const result = await convert(input, { format: 'vtt' });
await writeFile('subtitles.vtt', Buffer.from(await result.blob.arrayBuffer()));Direct parser / serializer usage
For subtitle and data-text packages, you can bypass the registry and call parsers directly:
ts
import { parseSrt, serializeVtt } from '@catlabtech/webcvt-subtitle';
import { readFileSync } from 'node:fs';
const srtText = readFileSync('subtitles.srt', 'utf-8');
const track = parseSrt(srtText);
const vttText = serializeVtt(track);When to use the CLI instead
For simple one-off conversions in shell scripts, the CLI is more ergonomic than writing a Node.js script:
bash
npx @catlabtech/webcvt-cli photo.jpg photo.webp
npx @catlabtech/webcvt-cli subtitles.srt subtitles.vttSee CLI usage for details.
Error handling
All webcvt errors extend WebcvtError and carry a .code property for programmatic handling:
ts
import { convert, defaultRegistry, UnsupportedFormatError, NoBackendError } from '@catlabtech/webcvt-core';
try {
const result = await convert(input, { format: 'xyz' });
} catch (err) {
if (err instanceof UnsupportedFormatError) {
console.error(`Format not supported: ${err.code}`);
} else if (err instanceof NoBackendError) {
console.error('No backend registered for this conversion');
} else {
throw err;
}
}See the Error Codes reference for a full list.