@types/node review
Your editor can accept a Node API that your deployed process doesn't have. @types/node contains TypeScript definitions for Node: it tells the compiler what Node APIs look like, but doesn't install Node, execute TypeScript, or add those APIs to a runtime. This guide covers declaration release 26.6.6. The useful decision is which declaration line describes the Node environment you actually ship, not which package removes the most editor errors. A checked type is still a claim about your program; runtime checks remain your responsibility.
Use @types/node for compile-time knowledge of the Node APIs you intend to deploy, and review declaration updates with your build. Keep runtime availability and input validation as separate checks, even when the editor is happy.
Answers from our run
@types/node or typescript: which should you use?
typescript: Choose this when you need the tsc compiler executable. It is a companion to Node declarations, not a replacement for them in a Node TypeScript project. Use @types/node for compile-time knowledge of the Node APIs you intend to deploy, and review declaration updates with your build.
When should you not use @types/node?
You expect installing this package to upgrade Node or make a missing API available. It supplies declarations; update the runtime or change the code instead.
Use it if
- You write TypeScript that calls Node APIs and need declarations for the compiler and editor. Install the declaration line that corresponds to the Node APIs you target.
- A server or command-line tool accepts values whose types aren't known yet. Node's typed runtime predicates can narrow an unknown value after checking it, as the examples below show.
- Your build needs an explicit, reviewable declaration dependency. An exact package pin and a committed lockfile make a type update a deliberate change.
- You expect installing this package to upgrade Node or make a missing API available. It supplies declarations; update the runtime or change the code instead.
- You need a compiler or a TypeScript execution tool. This package supplies neither. The typescript package provides the tsc executable; the separate [ts-node guide](https://mrkeyoor.com/libs/ts-node/) covers execution hooks.
- Your application runs only in a browser and the error concerns a Node-only API. Adding Node declarations can hide a mistaken assumption about where the code runs.
- You require type upgrades to be free of breaking changes within a patch line. Definitely Typed explicitly permits breaking declaration changes in patch revisions, so even a small update needs a build check.
Setup reality
Start by checking the Node version in your deployment, not just the one on your laptop. The installation example below pins @types/node 26.6.6 for a project deliberately targeting the Node 26 declaration line. For another Node major, choose its corresponding declaration line rather than copying that pin. Definitely Typed explains that declaration patch numbers are independent of runtime patch numbers. Do not read 26.6.6 as a request to install Node 26.6.6.
Install it as a development dependency when your build uses the declarations and deployment runs already-built JavaScript. Keep the compiler as a separate dependency. The 26.6.6 manifest points to index.d.ts, depends on undici-types ~8.9.0, records TypeScript 5.6, and has typesVersions routes for compilers through 5.6 and through 5.7. Those routes are a reason to inspect compiler resolution when an upgrade breaks your build, not a compatibility test of your project. Definitely Typed's published policy tests packages with TypeScript versions less than two years old. An old compiler may need a different declaration release.
The compiler normally includes installed types automatically. For a script that needs an explicit reference, Definitely Typed documents the triple-slash reference shown below. Keep that compiler directive separate from JavaScript imports: import the runtime module such as node:util/types, never @types/node as an executable module. If the editor and CI disagree, check which compiler and declaration version each is resolving before changing application code.
The examples are documentation-based illustrations checked against the declarations shipped in 26.6.6. We did not install the package, run a compiler, execute these snippets, or perform a security audit for this guide. They use one small surface, node:util/types, to show how runtime checks and static narrowing work together. A predicate can identify a Date or a Promise without proving that a date is valid or that a promise will fulfill with the value you expect.
Ratings use an editorial documentation rubric: 1 means a material documented obstacle, 3 means usable with stated caveats, and 5 requires clear coverage plus independent verification of that dimension. Intermediate scores sit between those anchors. These scores do not measure runtime speed, adoption, security, or compatibility with your application.
Patterns
Install an explicit declaration version pin-node-declarations
npm install --save-dev --save-exact @types/node@26.6.6For a project targeting the Node 26 declaration line. This installs declarations and their dependency, not the Node runtime or a compiler. The exact pin makes later type updates explicit.
Make a script reference Node declarations reference-script-types
/// <reference types="node" />Put the triple-slash directive at the top of the TypeScript file. Definitely Typed documents it for cases needing an explicit reference; it does not execute an import or add runtime APIs.
Check a value before treating it as a Date narrow-date
import { isDate } from 'node:util/types';
export function asDate(value: unknown): Date | undefined {
return isDate(value) ? value : undefined;
}The declaration narrows unknown to Date after the runtime predicate succeeds. It identifies a Date object, not whether that object holds a valid timestamp.
Require an ArrayBuffer rather than a shared buffer narrow-array-buffer
import { isArrayBuffer } from 'node:util/types';
export function asArrayBuffer(value: unknown): ArrayBuffer | undefined {
return isArrayBuffer(value) ? value : undefined;
}The shipped documentation explicitly excludes SharedArrayBuffer. A true result identifies the buffer type; it does not validate the content or length your application needs.
Accept a buffer view narrow-buffer-view
import { isArrayBufferView } from 'node:util/types';
export function hasView(value: unknown): boolean {
if (!isArrayBufferView(value)) return false;
const view: NodeJS.ArrayBufferView = value;
return view.byteLength > 0;
}The predicate includes typed arrays and DataView and excludes a bare ArrayBuffer. This function adds its own nonempty check; it does not identify a particular element format.
Keep a DataView after checking its type narrow-data-view
import { isDataView } from 'node:util/types';
export function asDataView(value: unknown): DataView | undefined {
return isDataView(value) ? value : undefined;
}The predicate distinguishes DataView from typed arrays. Returning a DataView does not establish that any particular offset is in bounds for later reads.
Accept a Uint8Array narrow-byte-array
import { isUint8Array } from 'node:util/types';
export function asBytes(value: unknown): Uint8Array | undefined {
return isUint8Array(value) ? value : undefined;
}The declaration narrows the result to Uint8Array. A wider typed-array check would also accept other element types; this check still does not validate an encoding or payload format.
Keep a checked regular expression narrow-regexp
import { isRegExp } from 'node:util/types';
export function asPattern(value: unknown): RegExp | undefined {
return isRegExp(value) ? value : undefined;
}The predicate identifies a RegExp object. A source string containing a pattern is still a string and needs a separate, deliberate parsing step.
Keep a Promise without guessing its result type narrow-promise
import { isPromise } from 'node:util/types';
export function asPromise(value: unknown): Promise<unknown> | undefined {
return isPromise(value) ? value : undefined;
}The declaration returns Promise<unknown>, so inspect the eventual fulfillment value separately. Identifying a Promise does not guarantee that it will fulfill or that an arbitrary thenable will pass this check.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| typescript | npm | Choose this when you need the tsc compiler executable. It is a companion to Node declarations, not a replacement for them in a Node TypeScript project. |
| @types/bun | npm | Choose this when you need TypeScript definitions for Bun. It is an environment-specific choice, not a way to add Bun APIs to Node or a guarantee of conflict-free coexistence with other declarations. |
More ai / ml guides
openai · @modelcontextprotocol/sdk · mcp · huggingface-hub · @anthropic-ai/sdk · openai · the whole shelf →
How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.