Node.js API compatibility - Utils

The util module in Node.js provides a set of utility functions that assist with various tasks, enhancing the functionality of JavaScript and Node.js applications. It’s particularly useful for developers looking to simplify common programming tasks and improve code readability. This module is available in the Azion Runtime through Node.js compatibility, where helpers such as promisify and inspect are handy for adapting callback-based code and for logging structured data inside a function.


Example: Promisify and inspect

The example below shows how to use the util module in a function:

/**
* An example of using Node.js Util API in an Azion Function.
* Support:
* - Partially supported (Extended by library `util`)
* @module runtime-apis/nodejs/util/main
* @example
* // Execute with Azion Bundler:
* npx edge-functions build
* npx edge-functions dev
*/
import util from "node:util";
const myTest = (callback) => {
try {
callback(null, "Success!");
} catch (err) {
callback(err);
}
};
/**
* An example of using the Node.js Util API in an Azion Function.
* @param {*} event
* @returns {Promise<Response>}
*/
const main = async (event) => {
const promisifyTest = util.promisify(myTest);
const result = await promisifyTest();
console.log(util.inspect(result, { showHidden: false, depth: null }));
return new Response("Done!", { status: 200 });
};
export default main;

Example: Converting callbacks to promises

Use promisify to convert callback-style functions to async/await:

import util from "node:util";
import { setTimeout } from "node:timers";
// Simulate a callback-based API
const fetchData = (id, callback) => {
setTimeout(() => {
if (id > 0) {
callback(null, { id, data: `Item ${id}`, timestamp: Date.now() });
} else {
callback(new Error("Invalid ID"));
}
}, 100);
};
// Convert to promise-based
const fetchDataAsync = util.promisify(fetchData);
const main = async (event) => {
try {
// Now can use with async/await
const result1 = await fetchDataAsync(1);
const result2 = await fetchDataAsync(2);
console.log("Result 1:", result1);
console.log("Result 2:", result2);
return new Response(JSON.stringify({ results: [result1, result2] }), {
headers: { "Content-Type": "application/json" }
});
} catch (error) {
console.error("Error:", error.message);
return new Response(JSON.stringify({ error: error.message }), {
status: 400,
headers: { "Content-Type": "application/json" }
});
}
};
export default main;

Example: Deep object inspection

Use inspect for detailed object logging and debugging:

import util from "node:util";
const main = async (event) => {
// Complex object to inspect
const requestInfo = {
url: event.request.url,
method: event.request.method,
headers: Object.fromEntries(event.request.headers),
timestamp: new Date().toISOString()
};
// Nested object
const complexData = {
level1: {
level2: {
level3: {
value: "deep",
array: [1, 2, { nested: true }]
}
}
}
};
// Inspect with options
const inspected = util.inspect(requestInfo, {
depth: null, // Unlimited depth
colors: false, // Explicitly disabled since output goes into JSON response
compact: false, // Multi-line output
showHidden: false, // Don't show non-enumerable
maxArrayLength: 10 // Limit array display
});
console.log("Request info:", inspected);
// Format string with placeholders
const formatted = util.format(
"Request %s to %s at %s",
requestInfo.method,
requestInfo.url,
requestInfo.timestamp
);
console.log(formatted);
return new Response(JSON.stringify({
requestInfo,
formatted,
inspectedDepth: util.inspect(complexData, { depth: 2 })
}), {
headers: { "Content-Type": "application/json" }
});
};
export default main;

Example: Type checking utilities

Use util.types for runtime type checking:

import util from "node:util";
const main = async (event) => {
const values = {
string: "hello",
number: 42,
boolean: true,
object: { key: "value" },
array: [1, 2, 3],
null: null,
undefined: undefined,
date: new Date(),
regex: /test/,
promise: Promise.resolve("test"),
buffer: new ArrayBuffer(8)
};
// Type checking results
const typeChecks = {
isDate: util.types.isDate(values.date),
isRegExp: util.types.isRegExp(values.regex),
isPromise: util.types.isPromise(values.promise),
isArrayBuffer: util.types.isArrayBuffer(values.buffer),
isNativeError: util.types.isNativeError(new Error("test")),
isTypedArray: util.types.isTypedArray(new Uint8Array(4)),
isMap: util.types.isMap(new Map()),
isSet: util.types.isSet(new Set())
};
// Note: isConstructor is not part of util.types API
// Use typeof for function/constructor checking
class MyClass {}
const isFunction = typeof MyClass === "function";
console.log("Type checks:", typeChecks);
return new Response(JSON.stringify({
values: Object.keys(values).map(k => ({
key: k,
type: typeof values[k],
isDate: util.types.isDate(values[k]),
isRegExp: util.types.isRegExp(values[k])
})),
typeChecks,
isFunction
}), {
headers: { "Content-Type": "application/json" }
});
};
export default main;

Example: String formatting and deprecation

Use format strings and mark deprecated functions:

import util from "node:util";
// Mark a function as deprecated
const oldFunction = util.deprecate(
() => "This is the old function",
"oldFunction is deprecated. Use newFunction instead."
);
const newFunction = () => "This is the new function";
const main = async (event) => {
const results = [];
// String formatting with %s, %d, %j, %%
results.push(util.format("Hello %s!", "World"));
results.push(util.format("Number: %d, String: %s", 42, "test"));
results.push(util.format("JSON: %j", { key: "value" }));
results.push(util.format("Percent: %%"));
// Style strings (for console output)
// Note: ANSI codes are only meaningful in terminal output
// They will appear as escape sequences in HTTP responses
const styled = util.format(
"%s %s %s",
"\x1b[31mRed\x1b[0m",
"\x1b[32mGreen\x1b[0m",
"\x1b[34mBlue\x1b[0m"
);
console.log(styled); // Useful in logs only
// Call deprecated function (will show warning in console)
const oldResult = oldFunction();
const newResult = newFunction();
// Get object's own property names
const obj = { a: 1, b: 2, c: 3 };
const keys = Object.keys(obj);
return new Response(JSON.stringify({
formattedStrings: results,
oldFunctionResult: oldResult,
newFunctionResult: newResult,
objectKeys: keys
// Note: styled string not included - ANSI codes not useful in JSON
}), {
headers: { "Content-Type": "application/json" }
});
};
export default main;

Example: Inheritance and class utilities

Use inherits for prototypal inheritance patterns:

import util from "node:util";
import { EventEmitter } from "node:events";
// ⚠️ Note: util.inherits() is deprecated since Node.js v5.0.0
// Prefer ES6 class syntax instead:
// class CustomEmitter extends EventEmitter {
// constructor() {
// super();
// this.events = [];
// }
// }
// Legacy pattern shown for compatibility with older codebases
// Create a custom class that inherits from EventEmitter
function CustomEmitter() {
EventEmitter.call(this);
this.events = [];
}
// Inherit from EventEmitter (deprecated pattern)
util.inherits(CustomEmitter, EventEmitter);
// Add custom methods
CustomEmitter.prototype.recordEvent = function(name, data) {
this.events.push({ name, data, timestamp: Date.now() });
this.emit(name, data);
};
const main = async (event) => {
const emitter = new CustomEmitter();
const recordedEvents = [];
// Listen to events
emitter.on("data", (data) => {
console.log("Received data:", data);
recordedEvents.push({ type: "data", value: data });
});
emitter.on("complete", () => {
console.log("Process complete");
recordedEvents.push({ type: "complete" });
});
// Emit events
emitter.recordEvent("data", { id: 1, message: "First" });
emitter.recordEvent("data", { id: 2, message: "Second" });
emitter.recordEvent("complete", null);
// Check inheritance
const isEmitter = emitter instanceof EventEmitter;
return new Response(JSON.stringify({
recordedEvents,
emitterEvents: emitter.events,
isEventEmitter: isEmitter
}), {
headers: { "Content-Type": "application/json" }
});
};
export default main;

Supported APIs

APIStatus
util.promisify()🟢 Supported
util.inspect()🟢 Supported
util.format()🟢 Supported
util.deprecate()🟢 Supported
util.isDeepStrictEqual()🟢 Supported
util.inherits()🟡 Deprecated (use ES6 classes)
util.callbackify()🟡 Partially supported
util.formatWithOptions()🟡 Partially supported
util.getSystemErrorMap()🟡 Partially supported
util.getSystemErrorName()🟡 Partially supported
util.log()🟡 Partially supported
util.stripVTControlCharacters()🟡 Partially supported
util.styleText()🟡 Partially supported
util.types.isDate()🟢 Supported
util.types.isRegExp()🟢 Supported
util.types.isPromise()🟢 Supported
util.types.isArrayBuffer()🟢 Supported
util.types.isNativeError()🟢 Supported
util.types.isTypedArray()🟢 Supported
util.types.isMap()🟢 Supported
util.types.isSet()🟢 Supported
util.types.isCryptoKey()🟢 Supported
util.types.isKeyObject()🟢 Supported

Note: APIs marked as 🟡 Partially supported have limited functionality compared to the full Node.js implementation. Note that util.inherits() is deprecated since Node.js v5.0.0 — prefer ES6 class syntax with extends for inheritance. For type checking, util.types provides runtime-safe alternatives to instanceof checks.