lib lists TypeScript's own declaration files for built-in APIs: the ECMAScript standard library by year (es2022, es2024, esnext), the browser DOM (dom, dom.iterable), and a few more such as webworker. Without lib, TypeScript picks the files for your target and adds dom. With lib set, you get exactly the list.
The list is a statement about where your code runs. A browser project wants dom; a server or edge project wants it gone, so document is an error instead of a crash. One surprise: console is declared by the DOM library (and by @types/node), not by ECMAScript, so lib: ["es2022"] with no other types makes console.log an error too (TS2584).
At a glance
| Write | Leave it out for browser code. For code with no DOM (Node.js, Bun, Cloudflare), list the ES year alone: ["es2024"] |
|---|---|
| On the command line | --lib |
| Type | string[] |
| Default in TypeScript 5.9 | the target's libraries, plus dom |
| TypeScript's description | Specify a set of bundled library declaration files that describe the target runtime environment. |
| In the quick-start setups |
|
The description is quoted from TypeScript's own option list (Apache-2.0); see the notices. The setup values are the checked configs on the quick-start pages.
Examples
const button = document.querySelector("button");error TS2584: Cannot find name 'document'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'.
button?.addEventListener("click", () => {
console.log("clicked");error TS2584: Cannot find name 'console'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'.
});jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": [],
"lib": [
"es2022"
]
},
"include": [
"*.js"
]
} const button = document.querySelector("button");
button?.addEventListener("click", () => {
console.log("clicked");
});jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": [],
"lib": [
"es2022",
"dom"
]
},
"include": [
"*.js"
]
} Lists that fit the usual projects
Starting points that match the checked setups in the quick start:
- browser, no bundler:
["es2022", "dom", "dom.iterable"](dom.iterablelets you loop over aNodeListwithfor…of) - Node.js:
["es2024"], with"types": ["node"]forprocess,consoleand the built-in modules - Cloudflare:
["es2024"]with the platform types intypes(see the quick start) - Bun:
["esnext"]with"types": ["bun"], which is what Bun's documentation recommends
Gotchas
- Setting
libreplaces the default list; it does not add to it."lib": ["dom"]alone loses the ECMAScript library. - A type package can bring globals of its own regardless of
lib:@types/nodedeclaresconsole,setTimeoutand more.
Sources
- TSConfig Reference: lib · TypeScript
- TypeScript 2.0 release notes · TypeScript handbook
- TypeScript · Bun docs
Last reviewed 20 October 2026.