Skip to Content
Node.js10. Utility Modules 🧰

Core Utility Modules - url, path, process, environment variables.

🔗 Understanding the URL Module

The node:url module provides tools for parsing and resolving URLs. It’s essential for handling web addresses in your applications.

It contains two distinct APIs for this purpose:

  • The WHATWG URL API: A modern API that matches the URL standard used in web browsers. This is the recommended API to use.
  • The Legacy URL API: A Node.js-specific API that is now considered legacy. You should use the WHATWG API instead for new applications.

✨ The Modern WHATWG URL API

This is the current standard for working with URLs in Node.js. Its main components are the URL and URLSearchParams classes.

The URL Class

This class is used to parse and represent a URL. It’s available globally, so you don’t always need to import it explicitly.

myURL.js
const myURL = new URL( "https://user:pass@sub.example.com:8080/p/a/t/h?query=string#hash" );

Once a URL string is parsed into a URL object, you can easily access its different parts through simple properties. These properties can also be set to modify the URL.

┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ href │ ├──────────┬──┬─────────────────────┬────────────────────────┬───────────────────────────┬───────┤ │ protocol │ │ auth │ host │ path │ hash │ │ │ │ ├─────────────────┬──────┼──────────┬────────────────┤ │ │ │ │ │ hostname │ port │ pathname │ search │ │ " https: // user : pass @ sub.example.com : 8080 /p/a/t/h ? query=string #hash " ├──────────┴──┼──────────┴──────────┼────────────────────────┤ │ │ │ │ origin │ │ origin │ pathname │ search │ hash │ ├─────────────┴─────────────────────┴────────────────────────┴──────────┴────────────────┴───────┤ │ href │ └────────────────────────────────────────────────────────────────────────────────────────────────┘
  • href: The full, serialized URL string.
  • origin: The read-only origin, which includes the protocol and host.
  • protocol: The URL’s protocol scheme.
  • username: The username portion of the URL.
  • password: The password portion of the URL.
  • host: The full host, including the hostname and port.
  • hostname: The host name, without the port.
  • port: The port number.
  • pathname: The path portion of the URL.
  • search: The serialized query string, including the leading ?.
  • hash: The fragment identifier, including the leading #.

The URLSearchParams Class

This class provides a simple way to read and write the query string of a URL. You can access it directly from a URL object via the searchParams property and use its methods to get, set, append, or delete query parameters.

myURL.js
const myURL = new URL("https://example.org/?user=abc&query=xyz"); // Get a query parameter console.log(myURL.searchParams.get("user")); // Prints 'abc' // Add a new parameter myURL.searchParams.append("id", "123"); console.log(myURL.href); // Prints 'https://example.org/?user=abc&query=xyz&id=123' // Set (or update) a parameter myURL.searchParams.set("user", "def"); console.log(myURL.href); // Prints 'https://example.org/?user=def&query=xyz&id=123'

⚙️ Useful Utility Functions

The url module also provides helper functions for converting between file paths and file: URLs. This is crucial when working with ES modules, which often use file: URLs for imports.

  • url.fileURLToPath(url): Converts a file: URL to a platform-specific file system path (e.g., /path/to/file on POSIX or C:\path\to\file on Windows).
  • url.pathToFileURL(path): Does the reverse, converting a file system path to a file: URL object.
url.js
import { fileURLToPath, pathToFileURL } from "node:url"; // On POSIX (Linux/macOS) const myPath = "/path/to/你好.txt"; const myURL = pathToFileURL(myPath); console.log(myURL.href); // Prints 'file:///path/to/%E4%BD%A0%E5%A5%BD.txt' console.log(fileURLToPath(myURL)); // Prints '/path/to/你好.txt'

⚠️ Legacy URL API

The older, Node.js-specific API (using methods like url.parse() and url.format()) is now considered Legacy. It is not recommended for use because it uses a non-standard parsing algorithm that can lead to security vulnerabilities. You should always use the WHATWG URL class instead.


🗺️ What is the path Module?

The node:path module provides tools for working with file and directory paths. It’s essential for handling file system paths in a way that works across different operating systems like Windows and macOS/Linux. To use it, you import it into your file.

💻 Windows vs. POSIX (The Cross-Platform Issue)

Node.js path methods behave differently depending on the operating system they are run on.

  • POSIX: Refers to Unix-based systems like macOS and Linux, which use forward slashes (/) as path separators.
  • Windows: Uses backward slashes (\) but can also understand forward slashes.

This can lead to unexpected results. To write code that works everywhere, you can explicitly use the POSIX or Windows version of the path methods:

  • path.posix: Guarantees POSIX-compliant path handling on any OS.
  • path.win32: Guarantees Windows-compliant path handling on any OS.

📌 Important Properties

The path module provides two very useful properties for creating cross-platform compatible paths.

  • path.sep: Provides the platform-specific path segment separator. It’s \ on Windows and / on POSIX systems.
  • path.delimiter: Provides the platform-specific path delimiter, used to separate paths in environment variables like $PATH. It’s ; on Windows and : on POSIX systems.

🛠️ Important Methods

Here’s a breakdown of the most essential methods for path manipulation.

path.join([...paths])

This method joins all given path segments together using the platform-specific separator (/ or \) and then normalizes the resulting path (e.g., handles ..). It’s the safest way to build a path.

path.resolve([...paths])

This method resolves a sequence of paths into an absolute path. It works from right to left, stopping when it constructs an absolute path. If one is never created, it prepends the current working directory.

path.basename(path[, suffix])

Returns the last portion of a path, which is typically the filename. You can optionally provide a suffix (like the extension) to have it removed from the result.

path.dirname(path)

Returns the directory name of a path, similar to the dirname command in Unix.

path.extname(path)

Returns the extension of the path, from the last . to the end of the string. If there’s no dot, it returns an empty string.

path.parse(path) & path.format(pathObject)

These two methods are opposites.

  • path.parse(path) takes a path string and returns an object with its components (root, dir, base, ext, name).
  • path.format(pathObject) takes an object with path components and returns a path string.
path.js
const path = require("path"); path.posix.basename("/tmp/myfile.html"); // Returns: 'myfile.html' (works on both Windows and Linux) path.win32.basename("C:\\temp\\myfile.html"); // Returns: 'myfile.html' (works on both Windows and Linux) "foo/bar/baz".split(path.posix.sep); // ['foo', 'bar', 'baz'] "foo\\bar\\baz".split(path.win32.sep); // ['foo', 'bar', 'baz'] // On POSIX: '/usr/bin:/bin:/usr/sbin' // On Windows: 'C:\\Windows\\system32;C:\\Windows' console.log(process.env.PATH.split(path.delimiter)); // path.join([...paths]) const myPath = path.join("/users", "john", "files", "..", "document.txt"); // Returns: '/users/john/document.txt' // path.resolve([...paths]) path.resolve("/foo/bar", "./baz"); // Returns: '/foo/bar/baz' path.resolve("/foo/bar", "/tmp/file/"); // Returns: '/tmp/file' (The second argument is absolute, so the first is ignored) // path.basename(path[, suffix]) path.basename("/foo/bar/baz/asdf/quux.html"); // Returns: 'quux.html' path.basename("/foo/bar/baz/asdf/quux.html", ".html"); // Returns: 'quux' // path.dirname(path) path.dirname("/foo/bar/baz/asdf/quux.html"); // Returns: '/foo/bar/baz/asdf' // path.extname(path) path.extname("index.html"); // Returns: '.html' path.extname("archive.tar.gz"); // Returns: '.gz' (Note: only the last extension) path.extname("app"); // Returns: '' (No extension) // path.parse(path) & path.format(pathObject) const pathObj = path.parse("/home/user/dir/file.txt"); // Returns: // { // root: '/', // dir: '/home/user/dir', // base: 'file.txt', // ext: '.txt', // name: 'file' // } const pathString = path.format({ dir: "/home/user/dir", base: "file.txt", }); // Returns: '/home/user/dir/file.txt'

⚙️ What is the process Object?

The process object is a global that provides information about, and control over, the current Node.js process. Since it’s a global object, you can access it from anywhere in your code without needing to use require() or import.

📋 Important Properties and Methods

These are some of the most commonly used properties and methods for interacting with the Node.js process.

process.env

This property returns an object containing all the user environment variables. It’s a crucial tool for configuring applications, as you can pass settings like database URLs, API keys, or the NODE_ENV (e.g., ‘development’ or ‘production’).

env.js
// Accessing the NODE_ENV environment variable const environment = process.env.NODE_ENV || "development"; console.log(`Running in ${environment} mode.`); // To run this and set the variable: // NODE_ENV=production node your_script.js

process.argv

This property is an array that contains the command-line arguments passed when the Node.js process was launched.

  • The first element (process.argv[0]) is the path to the node executable.
  • The second element (process.argv[1]) is the path to the JavaScript file being executed.
  • The remaining elements are any additional command-line arguments.
arguments.js
// To run: node your_script.js arg1 arg2 console.log(process.argv); // Output might look like: // [ // '/path/to/node', // '/path/to/your_script.js', // 'arg1', // 'arg2' // ] // To get only the user-provided arguments: const userArgs = process.argv.slice(2); console.log("User arguments:", userArgs); // ['arg1', 'arg2']

process.cwd()

This method returns the current working directory of the Node.js process. This is the directory from which you ran the node command.

cwd.js
console.log(`Current working directory: ${process.cwd()}`);

process.platform

This property returns a string identifying the operating system platform, such as 'darwin' (macOS), 'win32' (Windows), or 'linux'.

platform.js
if (process.platform === "win32") { console.log("This is a Windows system."); } else if (process.platform === "darwin") { console.log("This is a macOS system."); } else { console.log("This is a Linux system."); }

process.exit([code])

This method instructs Node.js to terminate the process synchronously with an exit code. By convention:

  • An exit code of 0 means the process completed successfully.
  • An exit code of 1 or any other non-zero number indicates an error.
exit.js
const user = "admin"; if (user !== "admin") { console.error("Error: Invalid user."); process.exit(1); // Exit with a failure code } console.log("Welcome, admin!"); process.exit(0); // Exit successfully

📢 Process Events

The process object is an instance of EventEmitter, allowing you to listen for specific process-level events.

The 'exit' Event

This event is emitted when the Node.js process is about to exit, either because it completed its work or because process.exit() was called. The listener callback receives the exit code as its only argument.

Important: You can only perform synchronous operations in the 'exit' event handler. The event loop is no longer running, so asynchronous calls (like database queries or network requests) will not be executed.

The 'uncaughtException' Event

This event is emitted when a JavaScript exception bubbles all the way back to the event loop without being caught by a try...catch block.

Warning: Using this event is a crude mechanism for exception handling and is not a replacement for try...catch. The official documentation strongly advises against using it as a way to resume normal operation, because the application is in an unknown and potentially unstable state. The recommended use is to perform synchronous cleanup of allocated resources and then exit the process.

events.js
// Exit Event process.on("exit", (code) => { // This will run console.log(`Process exiting with code: ${code}`); // This will NOT run setTimeout(() => { console.log("This will never be logged."); }, 1000); }); // Uncaught Exception Event process.on("uncaughtException", (err, origin) => { console.error(`Caught exception: ${err}`); console.error(`Exception origin: ${origin}`); // Perform synchronous cleanup here process.exit(1); // Exit because the application is in an unstable state }); // This will trigger the 'uncaughtException' event nonExistentFunction(); console.log("This line will not be reached.");

↔️ Standard I/O

The process object provides streams for standard input, output, and error, which are used for interacting with the terminal.

  • process.stdin: A readable stream for getting input from the user.
  • process.stdout: A writable stream for sending output to the user. console.log() uses this internally.
  • process.stderr: A writable stream for sending error messages.
stdIO.js
// Using stdout is like console.log() process.stdout.write("Hello from stdout!\n"); // Using stderr is like console.error() process.stderr.write("This is an error message.\n");

🌳 What are Environment Variables?

Environment variables are variables that exist within the shell where your Node.js application is running. They are a fundamental way to configure your application from outside your code. This is especially useful for storing sensitive information like API keys or changing behavior based on the environment (e.g., development vs. production) without changing the code.

In Node.js, you can access these variables through the global process.env object.

📥 Accessing Environment Variables

You can read any environment variable by accessing it as a property on process.env. The process object is available globally, so you don’t need to import anything.

It’s a good practice to provide a default value in case the environment variable isn’t set.

env.js
// Access the USER variable (common on Linux/macOS) const user = process.env.USER || "Guest"; console.log(`Hello, ${user}!`); // Access a custom API_KEY const apiKey = process.env.API_KEY; if (!apiKey) { console.error("API_KEY is not set!"); process.exit(1); } console.log(`Using API Key: ${apiKey}`);

📤 Setting Environment Variables

You can set environment variables either in your shell before running the app or directly within your Node.js code.

In the Shell

This is the most common and recommended way. The syntax differs slightly between operating systems, but generally, you declare the variable before running the node command.

env.sh
# POSIX (Linux, macOS, etc.): API_KEY=your-secret-key NODE_ENV=development node app.js # Windows(CMD): set "API_KEY=your-secret-key" & set "NODE_ENV=development" & node app.js # Windows (PowerShell): $env:API_KEY="your-secret-key"; $env:NODE_ENV="development"; node app.js

In Node.js

You can also set properties on process.env within your script.

Important: Modifying process.env in your code will only affect the current Node.js process and any child processes it spawns. It does not modify the environment variables in your parent shell.

env.js
// Set a variable for the current process process.env.CUSTOM_GREETING = "Hello from Node!"; console.log(process.env.CUSTOM_GREETING); // Prints 'Hello from Node!'

📜 Important Environment Variables

While you can use any custom variables, Node.js and its ecosystem reserve a few for specific purposes.

NODE_ENV

This is the most common and important environment variable in the Node.js ecosystem. Many libraries and frameworks (like Express.js) change their behavior based on its value to optimize for either development or production.

Common values are:

  • 'production': For live applications. Typically enables caching, reduces logging, and improves performance.
  • 'development' For when you are coding. Typically enables more verbose error messages and disables caches.
  • 'test': For when you are running automated tests.
env.js
if (process.env.NODE_ENV === "production") { console.log("Running in production mode! Caching enabled."); } else { console.log("Running in development mode. Verbose logging is on."); }

NODE_OPTIONS

This variable allows you to specify command-line options that the Node.js executable should use. This is useful for modifying the runtime environment without changing your start script, such as increasing the default memory limit.

options.sh
# Run a script with an increased memory limit of 4GB NODE_OPTIONS='--max-old-space-size=4096' node app.js
Last updated on