Jimp (JavaScript Image Manipulation Program)
Jimp is a comprehensive image processing library for Node.js, written entirely in JavaScript with zero native dependencies. It enables various image manipulation tasks such as resizing, cropping, color adjustments, and format conversions without external binaries. The current stable version is 1.6.1, reflecting an active development and release cadence with multiple patch and minor versions in recent months. Key differentiators include its pure JavaScript implementation, which ensures high portability across diverse environments, and a modular plugin architecture for customized builds. Jimp supports a wide range of formats, including JPEG, PNG, BMP, TIFF, and GIF, making it a versatile choice for server-side image processing workflows.
Common errors
-
Error [ERR_REQUIRE_ESM]: require() of ES Module ... Not supported
cause Attempting to use `require()` in an ES Module context (e.g., in a `type: "module"` project) for a package that is primarily ESM or has a main ESM export.fixChange `const { Jimp } = require('jimp');` to `import { Jimp } from 'jimp';`. -
TypeError: Jimp.read is not a function
cause Incorrect import of the Jimp class, often caused by using a default import (`import Jimp from 'jimp'`) when `Jimp` is a named export, or trying to access a static method on an incorrectly imported object.fixEnsure you are using the named import: `import { Jimp } from 'jimp';`. -
TypeError: Cannot read properties of undefined (reading 'write')
cause Attempting to call `.write()` or other manipulation methods on an image object that has not been `await`ed, or if `Jimp.read` failed to return an image.fixAlways `await` asynchronous Jimp operations, especially `Jimp.read()`: `const image = await Jimp.read('path/to/image.png');`
Warnings
- breaking Starting from `v1.2.0`, most plugins (e.g., blur, color, print) are no longer included by default with the main `jimp` package. To use these functionalities, you must explicitly import and add them to a custom Jimp instance.
- breaking The `brightness` function behavior changed in `v1.1.2` to align with standard CSS brightness implementations. Previously, it used an inverted multiplication. A value of `1` now means no change, with values above `1` increasing brightness.
- gotcha Older versions of Jimp (before `v1.1.4`) often required importing from `jimp/browser` specifically for browser environments to ensure correct bundler integration. While improved, some older configurations might still encounter issues.
- gotcha When working with `jimp` in ESM projects (e.g., Node.js with `"type": "module"` or bundlers), ensure you use `import` statements. Attempting to use `require()` might lead to errors about `require is not defined`.
Install
-
npm install jimp -
yarn add jimp -
pnpm add jimp
Imports
- Jimp
const Jimp = require('jimp');import { Jimp } from 'jimp'; - Jimp (default)
import Jimp from 'jimp';
import Jimp from 'jimp/browser';
- Jimp.read
import Jimp from 'jimp'; const image = await Jimp.read('path/to/image.png');import { Jimp } from 'jimp'; const image = await Jimp.read('path/to/image.png'); - JimpType
import type { JimpType } from '@jimp/types';
Quickstart
import { Jimp } from 'jimp';
import path from 'path';
import fs from 'fs/promises';
async function processImage() {
const inputPath = path.resolve('./input.png');
const outputPath = path.resolve('./output-processed.jpg');
const fontPath = path.resolve(__dirname, '../../node_modules/@jimp/plugin-print/fonts/open-sans/open-sans-16-black/open-sans-16-black.fnt'); // Example font path
try {
// Ensure input.png exists for demonstration
// For a real app, you'd fetch or use an existing file
// await fs.writeFile(inputPath, Buffer.from('...', 'base64')); // Example: write a placeholder image
const image = await Jimp.read(inputPath); // Read the image
// Resize, grayscale, and add text
const font = await Jimp.loadFont(fontPath);
image
.resize(300, Jimp.AUTO) // resize to 300px width, auto height
.quality(80) // set JPEG quality
.greyscale() // set greyscale
.print(font, 10, 10, 'Hello Jimp!') // add text
.write(outputPath); // save
console.log(`Image processed and saved to ${outputPath}`);
} catch (error) {
console.error('Error processing image:', error);
}
}
// Create a dummy input.png for the quickstart if it doesn't exist
async function createDummyImage() {
const dummyImagePath = path.resolve('./input.png');
if (!await fs.stat(dummyImagePath).catch(() => false)) {
const dummyImage = await new Jimp(100, 100, 0xFF0000FF); // 100x100 red image
await dummyImage.write(dummyImagePath);
console.log(`Created dummy image at ${dummyImagePath} for quickstart.`);
}
}
createDummyImage().then(() => processImage());