How Deno Executes TypeScript Without Extra Tooling
Deno runs .ts files directly by using its internal Rust‑based SWC compiler to transpile and type‑check on demand, eliminating the need for separate tsc, Babel, or webpack steps.
04 Sept 2026, 18:57 UTC

Useful answer: run TypeScript instantly
If you want to execute a TypeScript file without installing a separate compiler, Deno does it for you. The runtime ships a Rust‑based swc compiler that transpiles your .ts or .tsx source to JavaScript, feeds the result to V8, and optionally runs type‑checking. No tsc, babel, or webpack configuration is required to get started.
How it works: a worked example
Create a file named hello.ts with the following content:
// hello.ts
console.log('Hello from Deno at', new Date().toISOString());
Run it from a terminal where Deno is installed:
# Run the file (no type‑checking by default)
$ deno run hello.ts
Hello from Deno at 2026-10-18T17:25:46.291Z
What happens under the hood:
- Deno reads
hello.ts. - The internal SWC compiler parses the TypeScript syntax, transforms it to plain JavaScript (ES2022 target by default), and produces an in‑memory module.
- V8 executes that JavaScript.
- Because we invoked
deno runwithout--check, no type‑checking pass is performed, so the start‑up is fast.
Now introduce a type error to see the optional checking step:
// hello.ts with error
const x: number = 'oops'; // Type 'string' is not assignable to type 'number'.
console.log(x);
Running the file still succeeds because type‑checking is skipped:
$ deno run hello.ts
# prints: oops (runtime coercion happens, but the program runs)
To catch the error before execution, ask Deno to type‑check:
$ deno check hello.ts
error: TS2322: Type '"oops"' is not assignable to type 'number'.
const x: number = 'oops';
~~~~~~
The check uses the same SWC type‑checker that the runtime would use if you passed --check to deno run. No JavaScript is emitted; only diagnostics are reported.
Configuration: when you need it
Deno works out of the box, but you can adjust compiler behaviour with a deno.json or deno.jsonc file placed in the project root. A minimal example that sets the target to ES2020 and enables strict mode:
{
"compilerOptions": {
"target": "ES2020",
"strict": true,
"lib": ["DOM"]
}
}
If the file is absent, Deno assumes ES2022 target, includes the DOM library, and enables strict mode. Import maps for aliasing remote modules go in the same file under the importMap key.
Limits and common mistakes
Limits
- Large codebases: Deno’s type‑checker runs the whole module graph each time you invoke
deno checkordeno run --check. For very large projects this can be slower than incrementaltsc --watch. - Unsupported TS features: Features that rely on custom Babel/plugins or TypeScript emit helpers—such as
emitDecoratorMetadataor custom transformers—are not available because Deno does not plug into the TypeScript emitter pipeline. - Declaration file generation:
deno emit --declarationproduces.d.tsfiles, but the output may differ fromtsc --declarationfor advanced conditional types or module augmentation. Library authors should still verify the generated declarations.
Common mistakes
- Assuming
deno runtype‑checks. It does not; add--checkor rundeno checkseparately. - Committing the cache directory (
$DENO_DIRor~/.cache/deno) to version control. The cache is safe to ignore; setDENO_DIRto a local folder in CI to keep your home directory clean. - Expecting a
tsconfig.jsonto be read automatically. Deno ignores it unless you explicitly pass-c / --config(deprecated) or migrate its options intodeno.json. - Mixing Node‑style resolution (
require,node_modules) with Deno URLs in the same project without an import map. This leads to “module not found” errors; use an import map to redirect bare specifiers to CDN URLs if needed.
Practical verification steps
- Confirm you have a recent Deno version (≥ 1.40 for stable SWC‑based TS):
deno --version. - Create a
test.tsfile with a deliberate type error, rundeno run test.ts(should execute), then rundeno check test.ts(should fail with a diagnostic). - Inspect the module cache:
deno infoshows the location;deno cache --reloadforces a fresh fetch of remote modules. - For library authors, compare declaration output:
deno emit --declaration lib.tsvstsc --declaration lib.tsand check the generated.d.tsfiles for differences.
Following these steps lets you take advantage of Deno’s zero‑setup TypeScript execution while being aware of where the behaviour diverges from the traditional tsc workflow.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.