Skip to content

Fix: TypeScript error TS2304: Cannot find name 'x'

FixDevs · (Updated: )

Part of:  JavaScript & TypeScript Errors

Quick Answer

How to fix TypeScript Cannot find name error caused by missing type declarations, missing imports, wrong tsconfig settings, global types, and DOM API usage.

The Error

You compile TypeScript and get:

error TS2304: Cannot find name 'document'.

Or variations:

error TS2304: Cannot find name 'console'.
error TS2304: Cannot find name 'process'.
error TS2304: Cannot find name 'describe'.
error TS2304: Cannot find name 'React'.
error TS2304: Cannot find name 'Buffer'.

TypeScript does not recognize the identifier you used. It is not imported, not declared in any type definition file, or not included in your tsconfig.json configuration.

Why This Happens

TypeScript needs type declarations for every name you use. Built-in browser APIs (document, window, fetch) come from the dom library. Node.js APIs (process, Buffer, __dirname) come from @types/node. Testing APIs (describe, it, expect) come from @types/jest or @types/mocha.

There are three places TypeScript looks for a name. First, the lib entries in compilerOptions.lib — these are the JavaScript-level built-ins (Array, Promise, Map) plus optional libraries like DOM, ES2022, WebWorker. Second, the ambient declarations picked up from @types/* packages (auto-included when compilerOptions.types is unset). Third, explicit imports from files in the project. A Cannot find name error means the name is missing from all three sources at once.

The most confusing variation is when a name works in one file and fails in another inside the same project. That usually means you have multiple tsconfig.json files — tsconfig.app.json, tsconfig.node.json, tsconfig.spec.json — and they specify different lib or types arrays. A file picked up by the “app” config has DOM types; the same file picked up by the “node” config does not. Run npx tsc --showConfig to dump the effective config a given file is being compiled against.

If the required type declarations are not included, TypeScript reports Cannot find name.

Common causes:

  • Missing lib in tsconfig.json. The dom or es2020 libraries are not included.
  • Missing @types packages. @types/node, @types/react, @types/jest, etc. are not installed.
  • Wrong tsconfig.json scope. The file is not included in the TypeScript project.
  • Missing import statement. A type or value from a module is used without importing it.
  • Node.js types missing. Using Node.js APIs without @types/node.

Platform and Environment Differences

The set of types TypeScript needs depends entirely on where the code runs. Mixing them up is the single most common cause of Cannot find name.

Node types vs DOM types per project. A Node-only project (CLI tool, server) needs @types/node and should set "lib": ["ES2022"] (no DOM). A browser-only project needs "lib": ["ES2022", "DOM", "DOM.Iterable"] and should not install @types/node at runtime — doing so makes process.env look available in browser code and ships build-time secrets to the client. A full-stack monorepo needs separate tsconfig files for client and server with different lib/types arrays. The Vite and Next.js templates already split these; if you wrote your own tooling, replicate that split.

Deno vs Bun vs Node typing differences. Deno has its own type system bundled into the deno binary (deno types > deno.d.ts reveals it). Bun ships bun-types, which is published as a normal npm package and aliased to bun in compilerOptions.types. Node uses the community-maintained @types/node. A Bun-specific API like Bun.serve is Cannot find name 'Bun' in Node and Deno projects until you install bun-types and add "types": ["bun"]. Similarly, Deno’s Deno.cwd is unknown to Node/Bun unless you reference the Deno types.

Jest vs Vitest global type setup. Jest historically used @types/jest for describe/it/expect. Vitest provides its own vitest/globals type reference and needs "types": ["vitest/globals"] in tsconfig.json or explicit imports (import { describe, it } from "vitest"). Migrating a project from Jest to Vitest without updating compilerOptions.types leaves every test file showing Cannot find name 'describe'. The IDE underline survives a successful vitest run, which makes it look like only TypeScript is broken — that is a symptom, not the cause.

IDE TypeScript version mismatch. VS Code ships its own TypeScript service for IntelliSense. If the workspace pins TypeScript 5.5 in devDependencies but VS Code uses its bundled 5.2, you get Cannot find name errors in the editor that disappear on the command line (or vice versa). Fix: open the Command Palette, run “TypeScript: Select TypeScript Version”, choose “Use Workspace Version”. Or pin in .vscode/settings.json with "typescript.tsdk": "node_modules/typescript/lib".

Browser-only globals vs Node-only globals. fetch is global in modern Node 18+, but the type comes from lib.dom.d.ts (Node 18+ Fetch types) or from undici-types for Node 20 onward. If your lib excludes DOM, fetch becomes Cannot find name 'fetch' even on Node where it works at runtime. Add "lib": ["ES2022", "DOM"] or explicitly reference "types": ["node"] for Node 20+.

Worker contexts. A file targeting a Web Worker needs "lib": ["WebWorker", "ES2022"] and not "DOM" — Workers do not have document or window. A Service Worker needs "lib": ["WebWorker", "ES2022"] plus a triple-slash reference to lib.webworker.iterable.d.ts. Mixing these libraries in one project requires per-folder tsconfig overrides.

Fix 1: Add DOM Types for Browser APIs

If document, window, fetch, console, alert, localStorage, or HTMLElement are not found:

Check your tsconfig.json:

{
  "compilerOptions": {
    "lib": ["ES2020", "DOM", "DOM.Iterable"]
  }
}

The DOM library provides types for all browser APIs. Without it, TypeScript does not know about document, window, fetch, etc.

If no lib is specified: TypeScript uses a default set based on the target. If target is ES2020, it includes ES2020 and DOM by default. But if you explicitly set lib to just ["ES2020"], DOM is excluded.

Pro Tip: When you specify lib, you must include everything you need. Setting "lib": ["ES2020"] removes the default DOM types. Always include "DOM" and "DOM.Iterable" for browser projects.

Fix 2: Install @types/node for Node.js APIs

If process, Buffer, __dirname, __filename, require, or module are not found:

npm install --save-dev @types/node

Then ensure TypeScript includes them. In tsconfig.json:

{
  "compilerOptions": {
    "types": ["node"]
  }
}

Or if you do not have a types field, TypeScript automatically includes all @types packages in node_modules/@types.

Warning: If you set "types": ["node"], TypeScript only includes @types/node and ignores other @types packages. To include everything, remove the types field entirely or list all required types:

{
  "compilerOptions": {
    "types": ["node", "jest", "react"]
  }
}

Fix 3: Install Test Framework Types

If describe, it, expect, test, beforeEach, afterAll, or jest are not found:

For Jest:

npm install --save-dev @types/jest

For Mocha + Chai:

npm install --save-dev @types/mocha @types/chai

For Vitest:

Vitest includes its own types. Add to tsconfig.json:

{
  "compilerOptions": {
    "types": ["vitest/globals"]
  }
}

Or import in each test file:

import { describe, it, expect } from "vitest";

Fix 4: Fix React/JSX Types

If React is not found in JSX files:

npm install --save-dev @types/react @types/react-dom

For React 17+ with the new JSX transform:

In tsconfig.json:

{
  "compilerOptions": {
    "jsx": "react-jsx"
  }
}

With react-jsx, you do not need import React from 'react' in every file. The JSX factory is included automatically.

For older React (< 17):

{
  "compilerOptions": {
    "jsx": "react"
  }
}

And add the import in every JSX file:

import React from "react";

Fix 5: Check File Inclusion in tsconfig.json

TypeScript only processes files that are included in the project. If your file is outside the include paths, types are not resolved:

{
  "compilerOptions": { ... },
  "include": ["src/**/*.ts", "src/**/*.tsx"],
  "exclude": ["node_modules", "dist"]
}

If your file is in tests/ but only src/ is included:

{
  "include": ["src/**/*.ts", "tests/**/*.ts"]
}

Check which files TypeScript sees:

npx tsc --listFiles

If your file is not in the list, it is not part of the project.

Fix 6: Declare Global Types

If you use global variables (e.g., injected by the environment), declare them:

Create a .d.ts file (e.g., src/global.d.ts):

declare const __DEV__: boolean;
declare const API_URL: string;

interface Window {
  gtag: (...args: any[]) => void;
  dataLayer: any[];
}

TypeScript picks up .d.ts files automatically if they are in the include path.

For environment variables with Vite:

/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_API_URL: string;
  readonly VITE_APP_TITLE: string;
}

For environment variables with Next.js:

Create env.d.ts:

declare namespace NodeJS {
  interface ProcessEnv {
    DATABASE_URL: string;
    NEXT_PUBLIC_API_URL: string;
  }
}

For environment variable issues in general, see Fix: environment variable is undefined.

If a name from a module is not found:

Missing import:

// Error: Cannot find name 'useState'
function App() {
  const [count, setCount] = useState(0);
}

// Fix: Import it
import { useState } from "react";

Default vs named import confusion:

// Module exports: export default function parse() {}
import { parse } from "./parser";  // Wrong — named import
// Error: Module has no exported member 'parse'

import parse from "./parser";  // Correct — default import

For module resolution errors, see Fix: TypeScript cannot find module.

Common Mistake: Using require() in TypeScript without @types/node. TypeScript does not know about require unless Node.js types are installed. Use import instead of require in TypeScript:

// Instead of:
const fs = require("fs");

// Use:
import fs from "fs";
import * as fs from "fs";

Fix 8: Fix Enum and Const Issues

If a name from an enum or const is not found:

// In types.ts
export enum Status {
  Active = "active",
  Inactive = "inactive",
}

// In app.ts — missing import:
const status: Status = Status.Active;
// Error: Cannot find name 'Status'

// Fix:
import { Status } from "./types";

Const enums across modules:

// const enums are inlined at compile time
export const enum Color {
  Red = 0,
  Green = 1,
  Blue = 2,
}

If you use isolatedModules: true (required by Vite, esbuild, SWC), const enums from other files do not work. Use regular enums or as const objects instead:

export const Color = {
  Red: 0,
  Green: 1,
  Blue: 2,
} as const;

type Color = (typeof Color)[keyof typeof Color];

For broader isolatedModules constraints, see Fix: TypeScript isolatedModules error.

Still Not Working?

If the error persists:

Check for TypeScript version compatibility. Some types require a minimum TypeScript version. Update TypeScript:

npm install --save-dev typescript@latest

Check for conflicting tsconfig files. If you have multiple tsconfig.json files (e.g., tsconfig.app.json, tsconfig.node.json), make sure the right one is used for your file.

Check for skipLibCheck. Setting "skipLibCheck": true skips type checking of .d.ts files. This can mask issues but also prevent valid errors in your own .d.ts files.

Check for triple-slash references. Some older type definitions require explicit references:

/// <reference types="node" />
/// <reference lib="dom" />

Run tsc directly to see all errors:

npx tsc --noEmit

This shows all TypeScript errors without generating output files.

Check IDE vs CLI TypeScript version drift. If npx tsc --noEmit is clean but VS Code keeps showing Cannot find name, the editor is running a different TypeScript version. Switch to the workspace version via the Command Palette (“TypeScript: Select TypeScript Version”), then restart the TS server (“TypeScript: Restart TS Server”).

Check that @types/* packages match runtime versions. @types/node@20 describes Node 20 APIs. Pinning @types/node@16 in a project that runs on Node 22 leaves modern APIs (fetch, WebSocket, --watch mode hooks) undeclared. Run npm outdated @types/node and bump to match your actual Node.

Check for stale build incremental cache. TypeScript’s --incremental mode writes .tsbuildinfo files. If lib or types changes, the cache can refuse to rebuild affected declarations. Delete *.tsbuildinfo and node_modules/.cache then rerun the build.

For TypeScript type assignment errors, see Fix: TypeScript type is not assignable. The closely related “object is possibly undefined” warning comes from strictNullChecks and is solved with the same import and declaration patterns described above — narrow the type with a guard, give the declaration a non-nullable default, or assert at the boundary where the value enters the program.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles