At a glance
Last verified 21 October 2026 with TypeScript 5.9.3 (the sample file); runtime behavior per the Node.js, Deno and Bun documentation, none of them run here.
| Compared | Node.js | Deno | Bun |
|---|---|---|---|
Runs .js with JSDoc | Yes, as written | Yes, as written | Yes, as written |
| Checks types while running | No | No, by default since 1.23; deno run --check opts in | No; bun run --check opts in (1.4.3) |
| Built-in checker | None: install typescript and run tsc | deno check, with TypeScript's checker built in | bun check (1.4.3), which its release notes describe as a port of TypeScript 7's checker |
Checks .js files when | tsc: checkJs, or // @ts-check per file | checkJs, // @ts-check, or deno check --check-js | checkJs is on |
| Config it reads | None; tsc reads the jsconfig.json you name | deno.json, or a jsconfig.json or tsconfig.json beside a package.json (2.1 and later) | tsconfig.json; its documentation does not mention jsconfig.json |
| Types for the runtime's own APIs | @types/node | Built in (the Deno namespace) | @types/bun |
Runs .ts files | Yes, by erasing types (on by default from 22.18 and 23.6) | Yes | Yes |
The same file in three runtimes
The file below uses only web APIs (Request, Response, URL), which all three runtimes provide, so the same code runs on each. Its types are JSDoc, so it runs as written everywhere; the question is only which checker reads the comments. This site checks it with tsc 5.9, and the second version shows the mistake every checker reports:
/** @typedef {{ path: string, method: string }} Echo */
/**
* Answers every request with its path and method, as JSON.
* @param {Request} request
* @returns {Response}
*/
export function handle(request) {
const url = new URL(request.url);
/** @type {Echo} */
const body = { path: url.pathname, method: request.method };
return Response.json(body);
}jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["**/*.js"]
} /** @typedef {{ path: string, method: string }} Echo */
/**
* Answers every request with its path and method, as JSON.
* @param {Request} request
* @returns {Response}
*/
export function handle(request) {
const url = new URL(request.url);
/** @type {Echo} */
const body = { path: url.pathnme, method: request.method };error TS2551: Property 'pathnme' does not exist on type 'URL'. Did you mean 'pathname'?
return Response.json(body);
}jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["**/*.js"]
} None of the three runtimes reports that typo when it runs the file: per their documentation, Node.js does not check types at all, and Deno and Bun check only when asked. The program starts, and fails on the first request.
Node.js
Node.js runs JavaScript and, since 22.18 and 23.6, .ts files with their types erased (JSDoc vs Node’s type stripping). It checks neither. The check is tsc, installed as a development dependency and run with your config:
npm install --save-dev typescript @types/node
npx tsc -p jsconfig.jsonThe Node.js setup has the config, including types: ["node"] for @types/node.
Deno
Deno ships TypeScript’s checker. Per its documentation, deno run stopped checking by default in 1.23 (deno run --check turns it back on), and deno check checks without running. JavaScript files are checked only when you ask: checkJs in the config, // @ts-check in the file, or deno check --check-js:
deno check --check-js main.jsSince 2.1, Deno reads a jsconfig.json or tsconfig.json when the project has a package.json, so the same config can serve tsc and Deno; a deno.json with compilerOptions takes precedence when both exist. The Deno setup covers both. Deno’s own APIs (Deno.serve) are typed by deno check only: tsc does not know them.
Bun
Per Bun’s documentation, Bun runs JavaScript and TypeScript without checking types. Since Bun 1.4.3 (10 October 2026), bun check checks a project from its tsconfig.json and writes nothing, and bun run --check checks before running; the release post describes the checker as a port of TypeScript 7’s. It reports errors in JavaScript files when checkJs is on, and its documentation does not mention jsconfig.json:
bun checktsc works on Bun projects too, with @types/bun for Bun’s APIs; the Bun setup checks its example that way. We have not run bun check.
One checker or three
Every runtime here leaves type errors to a separate step, so the practical question is which checker your CI runs. Running tsc everywhere gives one TypeScript version, pinned in package.json, for the editor, CI and every developer. The runtimes’ own checkers save an install, at the cost of following their own release schedule for TypeScript: Deno’s built-in version, and Bun’s port of TypeScript 7, can differ from the typescript your editor runs.
Which to choose
Choose tsc, whatever the runtime when…
- You want one checker and one config for code that runs in more than one place, or in CI on any machine.
- You want the TypeScript version pinned in
package.json, so the editor, CI and every developer get the same results.
Choose the runtime's own checker when…
- The project runs only on Deno, where
deno checkneeds no install and knows theDenoAPIs. - The project runs only on Bun and you are happy with
bun checkfollowing TypeScript 7, with atsconfig.json.
Questions
Does any runtime refuse to run code with type errors?
Not by default. Per their documentation, Node.js never checks types, and Deno and Bun run without checking unless you pass --check. A type error stops nothing until a checker runs, which is why the check belongs in CI.
Can one jsconfig.json serve all three?
For tsc and Deno, yes: Deno reads a jsconfig.json when the project has a package.json. For bun check, name the file tsconfig.json, or keep running tsc on Bun projects, which works with @types/bun.
Which TypeScript does deno check use?
The one built into that Deno release. deno --version prints it. It may differ from the typescript in your package.json, so tsc and deno check can disagree after a TypeScript release.
Sources
- Modules: TypeScript (type stripping) · Node.js documentation
- deno check · Deno docs
- TypeScript support (Deno) · Deno docs
- Type checking (bun check) · Bun docs
- Bun v1.4.3 · Bun blog
Last reviewed 21 October 2026.