Before you start
You need Node.js and npm, and a folder with some JavaScript in it (an empty folder works too). Nothing here changes how your code runs: the checker reads your files and reports problems, and your JavaScript ships exactly as you wrote it.
Path 1: write jsconfig.json yourself
The recommended path: four short steps, and you know what every line of the config does.
-
Install TypeScript
TypeScript is a development dependency: it checks your code and never runs in production. In a folder without a
package.json, create one first and mark the project as ES modules.Terminalnpm init -y npm pkg set type=module npm install --save-dev typescript -
Create jsconfig.json
Next to
package.json:jsconfig.json{ "compilerOptions": { "checkJs": true, "noEmit": true, "strict": true, "module": "nodenext", "target": "es2022" } }checkJsreports errors in.jsfiles,noEmitstopstscfrom writing output, andstrictturns on the strict family of checks, including the one behind TS7006.module: "nodenext"makes the checker resolve imports the way Node.js does, andtargetsays which JavaScript features your code may use. -
Add a lint script and run it
Terminalnpm pkg set scripts.lint="tsc -p jsconfig.json" npm run lintNo output means no errors. Run the same script in CI to keep it that way.
-
Annotate your first function
Add a JSDoc comment with the types. The checker holds every caller to them, and your editor shows them on hover.
index.js TypeScript 5.9.3 · checked 21 October 2026/** * @param {string} name * @returns {string} */ export function greet(name) { return `Hello, ${name}!`; } console.log(greet("world"));A first function, typed with JSDoc. jsconfig.json for this example
{ "compilerOptions": { "checkJs": true, "noEmit": true, "strict": true, "module": "nodenext", "target": "es2022" } }
Path 2: generate it with tsc --init
TypeScript can write the config file for you. Pass the options as flags, then rename the file it writes:
npm install --save-dev typescript
npx tsc --init --allowJs --checkJs --noEmit --strict --module nodenext --target es2024 --types node
mv tsconfig.json jsconfig.json
In TypeScript 5.9, tsc --init also writes defaults of its own. sourceMap, declaration and
declarationMap only matter when tsc writes files, which noEmit stops. noUncheckedIndexedAccess
and exactOptionalPropertyTypes make checking stricter than strict alone. verbatimModuleSyntax,
isolatedModules, noUncheckedSideEffectImports and moduleDetection tighten how imports and
modules are checked, skipLibCheck skips your dependencies' .d.ts files, and jsx does nothing in
files without JSX. Keep the ones you want, delete the rest, or let the jsconfig generator
print a tsc --init command that switches them off.
Install typescript before you run npx tsc. Without it, npx fetches an unrelated npm package named tsc
instead of TypeScript.
Renaming the file is optional, since tsc -p reads either name. Calling it jsconfig.json tells editors and
readers the project is JavaScript, and gives it JavaScript-friendly defaults such as allowJs. This example was checked
with the exact file tsc --init wrote, renamed (open the config under the code to see it):
import { readFile } from "node:fs/promises";
/**
* @param {string} path
* @returns {Promise<string[]>}
*/
export async function readLines(path) {
const text = await readFile(path, "utf8");
return text.split("\n");
}
const [first] = await readLines("notes.txt");
// With noUncheckedIndexedAccess, `first` is string | undefined.
console.log(first?.trim());jsconfig.json for this example
{
// Visit https://aka.ms/tsconfig to read more about this file
"compilerOptions": {
// File Layout
// "rootDir": "./src",
// "outDir": "./dist",
// Environment Settings
// See also https://aka.ms/tsconfig/module
"module": "nodenext",
"target": "es2024",
"types": ["node"],
// For nodejs:
// "lib": ["esnext"],
// "types": ["node"],
// and npm install -D @types/node
// Other Outputs
"sourceMap": true,
"declaration": true,
"declarationMap": true,
// Stricter Typechecking Options
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
// Style Options
// "noImplicitReturns": true,
// "noImplicitOverride": true,
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "noFallthroughCasesInSwitch": true,
// "noPropertyAccessFromIndexSignature": true,
// Recommended Options
"strict": true,
"jsx": "react-jsx",
"verbatimModuleSyntax": true,
"isolatedModules": true,
"noUncheckedSideEffectImports": true,
"moduleDetection": "force",
"skipLibCheck": true,
"allowJs": true,
"checkJs": true,
"noEmit": true,
}
} Path 3: scaffold it with jswt
jswt is a small command-line tool by AJ ONeal that sets up exactly this
kind of project in one step. It is published on npm under the Mozilla Public License 2.0.
npx -p jswt@2.x -- jswt init
It runs tsc --init with its own set of flags, renames the result to jsconfig.json, adds include
and paths entries, and creates a few placeholder files. Version 2 sets up ES modules; version 1 is for CommonJS projects.
Read its package page before you run it, as you would for any tool that writes files into your project.
The tool came out of the 2022 conference talk that first used this domain; the page on where the name comes from has the story.
Setups for your project shape
The config above suits a Node.js project. Each project shape has its own page with the matching config, types and scripts:
-
Project shape
Node.js with ES modules
Type-check a Node.js project written as ES modules: the jsconfig.json, @types/node, the npm scripts and the import rules that nodenext enforces.
-
Project shape
Node.js with CommonJS
Type-check a CommonJS Node.js project: require and module.exports with JSDoc, @types/node, and module nodenext reading "type": "commonjs".
-
Project shape
Browser, no bundler
Type-check JavaScript that the browser loads as module scripts: the DOM in lib, no Node.js types, and imports held to the exact paths a browser needs.
-
Project shape
Library (publishing types)
Publish a JavaScript package with types: JSDoc in the source, a second config that writes .d.ts files, and an exports map with a types condition.
-
Project shape
Cloudflare Workers
Type-check a Cloudflare Workers project written in JavaScript: the runtime types, an Env typedef for your bindings, @satisfies on the handler, no DOM in lib.
-
Project shape
Deno
Type-check JavaScript with Deno: deno check, checkJs and JSDoc, a jsconfig.json Deno reads next to package.json, and when Deno checks types.
-
Project shape
Bun
Type-check JavaScript that Bun runs: @types/bun, the module settings Bun recommends, and tsc -p jsconfig.json, since running a file does not check it.
-
Project shape
Monorepo
Type-check a JavaScript monorepo: one root jsconfig.json for all packages, a small one per package that extends it, and paths to the sources.
What to read next
@type: annotate a variable, cast an expression, type a whole function.- TS7006: the first error most projects see after turning on
strict. - VS Code: make the editor use the same TypeScript as
npm run lint. - jsconfig generator: a config for your project shape and strictness.
Last reviewed 20 October 2026.