Node.js Promisify Polyfill
util-promisify is a JavaScript package that provides the `util.promisify` function from Node.js core as a standalone module. It was originally created to enable the use of `async/await` patterns with callback-based Node.js APIs in environments prior to Node.js 8, where `util.promisify` was initially introduced. While the current stable version is 3.0.0, the package's core functionality is now standard and natively available in all actively supported Node.js versions (v8.0.0 and later). Consequently, this package primarily serves as a polyfill for legacy Node.js environments. Its release cadence is infrequent, typically limited to minor maintenance updates or compatibility adjustments, rather than active feature development. The key differentiator at its inception was providing early access to this crucial utility for modernizing asynchronous code, though its necessity has significantly diminished due to its universal inclusion in recent Node.js runtimes. Developers targeting Node.js versions older than 8.0.0 would find this module essential, otherwise, the native `util.promisify` should be preferred for better performance and reduced dependency count.
Common errors
-
TypeError: promisify is not a function
cause Attempting to import `promisify` incorrectly, or `require`ing it in a way that doesn't yield the function directly (e.g., trying `require('util-promisify').promisify` when it's a default export). This can also happen if attempting to use `util.promisify` on Node.js versions older than 8.0.0 without the `util-promisify` polyfill.fixEnsure you are importing/requiring the module correctly: `const promisify = require('util-promisify');` for CommonJS or `import promisify from 'util-promisify';` for ESM. If targeting Node.js < 8, ensure this package is installed and imported. If targeting Node.js >= 8, use `const { promisify } = require('util');` instead. -
ERR_INVALID_ARG_TYPE: The "original" argument must be of type function. Received an instance of Object
cause The `promisify` function was called with an argument that is not a function. This often occurs when passing a method directly from an object without binding its context, or passing an undefined/null value.fixEnsure that the argument passed to `promisify` is always a valid function. For object methods, you might need to bind the context: `promisify(myObject.method.bind(myObject))` or use a wrapper function `promisify((...args) => myObject.method(...args))`. Always check that the function you intend to promisify is actually defined and accessible.
Warnings
- gotcha The `util.promisify` function has been natively available in Node.js core since version 8.0.0. For modern Node.js applications (v8 and newer), directly importing `util` and using `util.promisify` is generally preferred over this standalone module, as it avoids an unnecessary dependency.
- breaking Version 3.0.0 did not introduce functional breaking changes, but focused on license updates and Travis CI configurations, including updating to Node 10 in CI. The API remained consistent with previous versions and Node.js core's `util.promisify`.
Install
-
npm install util-promisify -
yarn add util-promisify -
pnpm add util-promisify
Imports
- promisify
import promisify from 'util-promisify';
const promisify = require('util-promisify'); - promisify
import { promisify } from 'util-promisify';import promisify from 'util-promisify';
- promisify.custom
import { custom } from 'util-promisify';const promisify = require('util-promisify'); const customSymbol = promisify.custom;
Quickstart
import promisify from 'util-promisify'; // Use const promisify = require('util-promisify'); for CommonJS
import * as fs from 'fs';
import { join } from 'path';
const statAsync = promisify(fs.stat);
const readFileAsync = promisify(fs.readFile);
const writeFileAsync = promisify(fs.writeFile);
async function demonstratePromisify() {
const tempFilePath = join(process.cwd(), `temp_file_${Date.now()}.txt`);
const fileContent = `Hello, util-promisify! This is a test content written at ${new Date().toISOString()}`;
try {
console.log(`Attempting to write to: ${tempFilePath}`);
await writeFileAsync(tempFilePath, fileContent, 'utf8');
console.log(`Successfully wrote ${fileContent.length} bytes to ${tempFilePath}`);
const stats = await statAsync(tempFilePath);
console.log(`File stats: size=${stats.size} bytes, isFile=${stats.isFile()}`);
const content = await readFileAsync(tempFilePath, 'utf8');
console.log(`File content read: "${content}"`);
// Example of error handling: trying to stat a non-existent file
console.log('\nAttempting to stat a non-existent file for error demonstration...');
await statAsync('/path/to/definitely/nonexistent/file.xyz');
} catch (error: any) {
if (error.code === 'ENOENT') {
console.error(`Expected error: File or directory not found. Message: ${error.message}`);
} else {
console.error(`An unexpected error occurred: ${error.message}`);
}
} finally {
if (fs.existsSync(tempFilePath)) {
await promisify(fs.unlink)(tempFilePath);
console.log(`Cleaned up temporary file: ${tempFilePath}`);
} else {
console.log(`No temporary file to clean up at ${tempFilePath}`);
}
}
}
demonstratePromisify().catch(err => {
console.error("A fatal error occurred during the demonstration:", err);
});