PNG Decoder for Node.js and Browser
png-js is a JavaScript-based PNG decoder designed for both Node.js and browser environments. The package's latest version, 2.0.0, was released over a decade ago (tagged in 2013, with the last npm publish for version 1.0.0 being over six years ago), indicating it is an abandoned project with no active maintenance or release cadence. While it provides basic functionality for decoding PNG files into raw pixel data, its age means it does not support modern JavaScript module systems like ESM, lacks official TypeScript definitions, and likely misses performance optimizations or features found in contemporary image processing libraries. Developers requiring a robust, actively maintained, or high-performance PNG solution should consider modern alternatives such as 'pngjs' (note the lowercase 'js'), 'sharp', or 'jimp'. Its key differentiator was being a pure JavaScript decoder for both environments at a time when fewer options existed.
Common errors
-
TypeError: (0 , png_js_1.default) is not a function
cause Attempting to import `png-js` using ESM default import syntax in a TypeScript or ESM Node.js project.fixUse CommonJS `require()` syntax for Node.js: `const PNG = require('png-js');`. If in an ESM file, you may need `import { createRequire } from 'module'; const require = createRequire(import.meta.url); const PNG = require('png-js');`. -
ReferenceError: PNG is not defined
cause Trying to use `PNG.load()` or `new PNG()` in a browser environment without including the `png.js` script tag, or in a Node.js ESM context without proper CommonJS interop.fixFor browsers, ensure `<script src="png.js"></script>` and `<script src="zlib.js"></script>` are present before your script. For Node.js, ensure `const PNG = require('png-js');` is at the top of your file. -
Error: Invalid PNG
cause The PNG file is corrupted, malformed, or uses features (e.g., specific interlace methods, bit depths) that this older library might not fully support or correctly parse.fixVerify the integrity of the PNG file. If the file is valid and still causes issues, this library might not support that specific PNG variant. Consider using a more robust and actively maintained PNG decoding library like `pngjs` (lowercase) or `sharp`.
Warnings
- breaking The `png-js` package is effectively abandoned, with its last significant update (version 2.0.0 tag) dating back to 2013, and the latest npm publish (version 1.0.0) over six years ago. This means it is unlikely to receive security patches, bug fixes, or feature updates.
- gotcha This library uses CommonJS `require()` syntax exclusively for Node.js. It does not support ES Modules (`import/export`) natively. Using it in a pure ESM project will require a CommonJS interoperability layer or a bundler.
- gotcha The package does not provide TypeScript type definitions, making it harder to use in TypeScript projects without manually declaring types or relying on `@ts-ignore`.
- gotcha Performance may be significantly lower compared to native C++ based image processing libraries (like `sharp`) or more modern, optimized pure JavaScript decoders. Being an older pure JavaScript implementation, it might not leverage recent V8 engine optimizations or WebAssembly.
Install
-
npm install png-js -
yarn add png-js -
pnpm add png-js
Imports
- PNG
import PNG from 'png-js'; import { PNG } from 'png-js';const PNG = require('png-js'); - decode
import { decode } from 'png-js'; PNG.decodeAsync(...);const PNG = require('png-js'); PNG.decode('some.png', callback); - PNG instance
new pngjs.PNG(buffer);
const PNG = require('png-js'); const pngInstance = new PNG(buffer);
Quickstart
import { readFileSync } from 'fs';
import { join } from 'path';
// Simulate loading png-js in a CommonJS-like environment
// In a real Node.js CJS project, this would be: const PNG = require('png-js');
// For this example, we'll manually 'import' it as if it were a default export from a CJS wrapper.
// In a modern ESM project, you would need a CJS interop or a bundler.
// To make this runnable, we'll assume a simplified shim for `require('png-js')`
// In a real project, ensure `png-js` is properly required.
// For demonstration purposes, we'll mock the module structure based on README:
const createPngJsMock = () => {
return {
decode: (filePath, callback) => {
console.log(`Decoding ${filePath} using png-js...`);
try {
// In a real scenario, this would read the file and parse PNG data
// For this mock, we'll just return dummy pixel data
// The actual `png-js` would read the file system.
const dummyPixels = Buffer.from([255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255]); // R,G,B,A for 3 pixels
process.nextTick(() => callback(dummyPixels));
} catch (error) {
console.error('Error in PNG.decode mock:', error);
process.nextTick(() => callback(null, error));
}
},
load: (filePath, canvas) => {
console.log(`Loading ${filePath} into canvas (browser-only feature, mocked here)...`);
// Browser-side PNG.load implementation would handle canvas rendering.
},
// Add a constructor for buffer-based decoding as described in the README
PNG: class PngBufferDecoder {
constructor(buffer) {
console.log('New PNG instance created from buffer.');
this.buffer = buffer;
}
decode(callback) {
console.log('Decoding PNG buffer...');
// Simulate decoding buffer data
const dummyPixels = Buffer.from([128, 128, 0, 255, 0, 128, 128, 255]); // 2 pixels
process.nextTick(() => callback(dummyPixels));
}
}
};
};
const PNG = createPngJsMock(); // Simulate require('png-js');
// Example 1: Decode a file (mocked path)
const imagePath = join(process.cwd(), 'test.png'); // Placeholder, file won't actually exist
PNG.decode(imagePath, function(pixels) {
if (!pixels) {
console.error('Failed to decode image.');
return;
}
console.log(`Decoded pixels (from file): ${pixels.length} bytes.`);
// pixels is a 1d array (in rgba order) of decoded pixel data
// console.log(pixels);
});
// Example 2: Decode from an existing buffer
const dummyPngBuffer = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYGD4DwABSgCB3yA4JgAAAABJRU5ErkJggg==', 'base64');
const pngInstance = new PNG.PNG(dummyPngBuffer);
pngInstance.decode(function(pixels) {
if (!pixels) {
console.error('Failed to decode buffer.');
return;
}
console.log(`Decoded pixels (from buffer): ${pixels.length} bytes.`);
// console.log(pixels);
});