npm: specifier format for npm packages
To import an npm package in Deno, use the npm: prefix with the format: npm:<package-name>[@<version-requirement>][/<sub-path>]. For example, npm:chalk@^5 or npm:cowsay@1.5.0/cowthink for a specific binary. Deno downloads the package on first run and stores it in a global cache.
node: prefix for Node built-in modules
Node.js built-in APIs are available in Deno through a compatibility layer using the node: prefix, such as node:os, node:http, or node:process. Since Deno 2.9, bare imports that match a Node built-in (like import * as os from 'os') also work without the prefix, but explicit node: form is preferred for clarity and compatibility with Node.js.
Node globals availability in Deno
Node globals map to Deno as follows: process is available everywhere; Buffer is not global and must be imported from node:buffer; __filename and __dirname are not defined and must be replaced with import.meta.filename and import.meta.dirname; require() is available in CommonJS files; setTimeout and setInterval are available with Node semantics since Deno 2.8.
process.version and process.versions in Deno
Deno reports a Node-compatible version: process.version is v26.3.0 and process.versions.napi is 10 (Node-API version 10), allowing packages that gate on Node or Node-API versions to recognize Deno as a modern runtime.
Buffer import and TypeScript types
Buffer must be explicitly imported from node:buffer in Deno. For TypeScript users needing Node.js-specific types like BufferEncoding, use the NodeJS namespace when referencing npm:@types/node. Prefer using Uint8Array or other TypedArray subclasses instead of Buffer.
setTimeout and setInterval return values in Deno 2.8+
Starting in Deno 2.8, setTimeout and setInterval return a Node.js Timeout object instead of a number, matching Node.js semantics. The returned object exposes methods like .ref(), .unref(), .refresh(), and .hasRef(). It still coerces to a number via Symbol.toPrimitive, so existing code storing the timer ID as a number or passing it to clearTimeout/clearInterval continues to work.
Running npm CLI tools with Deno
Run npm CLI tools directly using deno run with the format: deno run -R -E npm:<package-name>[@<version-requirement>][/<binary-name>]. For example, deno run -R -E npm:cowsay@1.5.0 'Hello' or deno run -R -E npm:cowsay@1.5.0/cowthink for a specific binary. This works similarly to npx.
Creating require() function in ES modules
To use require() in an ES module, create an instance using: import { createRequire } from 'node:module'; const require = createRequire(import.meta.url); const express = require('express');. Dependencies must be installed manually and appropriate permission flags (-R, -E) must be given.
Requiring ES modules from CommonJS in Deno
Deno's require() implementation supports requiring ES modules, matching Node.js behavior. You can only require() ES modules that don't have top-level await in their module graph (synchronous modules). ES modules can also be imported in CommonJS files.
Package export conditions in Deno ESM
The conditions satisfied by an import from a Deno ESM module are: ["deno", "node", "import", "module-sync", "default"]. For require() resolution, including createRequire(), the conditions are: ["require", "node", "module-sync", "default"]. Expand the import conditions list using --conditions flag: deno run --conditions development,react-server main.ts.
Using @ts-types for npm package types
For npm packages without shipped types, use the @ts-types directive to specify types: // @ts-types="npm:@types/express@^4.17" import express from "npm:express@^4.17";. This allows using TypeScript definitions from @types packages.
Most Node.js code runs in Deno without modification
Standard Node.js code, such as Node HTTP servers using node:http, can be executed with deno instead of node. Deno provides Node's built-in APIs through a compatibility layer and supports npm packages via npm: specifiers.
Deno Node compatibility test coverage
As of Deno 2.8, over 75% of Node's own test suite passes in Deno, covering nearly every node: module. Most pure-JavaScript npm packages work without changes. Current state can be tracked at node-test-viewer.deno.deno.net.
no-process-global lint rule for preferring explicit imports
Enable the no-process-global lint rule (off by default since Deno 2.8) to prefer explicit import process from 'node:process' over using the global process. Run deno lint to flag uses of the global and receive hints for fixing.