TypeScript Compiler Explained

The TypeScript compiler (tsc) turns .ts files into .js files while checking types. Learn what it does, how to use it, and how it fits your workflow.

5 min read

The TypeScript compiler, called tsc, is the official tool that turns your .ts files into plain .js files. While it produces JavaScript, its real value is what happens before that: it checks every type in your project and reports problems before any code runs.

When you run tsc, it does two things: first it type-checks your entire project against the rules in your configuration, then it emits .js files that browsers and Node.js can run. The types are stripped away during emit and never reach the runtime.

How tsc fits into your workflow

Here is the full path from TypeScript source to running code:

TypeScript compile workflow

The compiler catches type errors at the type-check stage. If the check passes, it emits .js output. If it fails, you fix the error and try again. The browser never sees the types.

TypeScript can also run in strict mode, which enables every type-safety check the compiler offers. See strict mode in TypeScript for details on what that enables and why you should use it.

Running tsc with no arguments

The most common way to use tsc is with no arguments, from a directory that contains a tsconfig.json file:

bashbash
tsc

This reads the configuration, finds all included .ts files, type-checks them, and writes .js output. If there are errors, it prints them and, by default, still emits the JavaScript so you can keep working.

You can change this behavior with the noEmitOnError option in your tsconfig. Setting it to true blocks file output when errors exist, which is useful in CI pipelines where a failing build should stop completely.

Compiling a single file

You can compile one file without any configuration. This is handy for quick experiments:

bashbash
tsc index.ts

This command uses the compiler defaults: ES5 target, CommonJS modules, and no strict checks. The output is index.js in the same directory. For real projects you always want a tsconfig to control these settings.

Type-checking without emitting files

A common pattern in modern projects is to use a bundler like Vite or esbuild to compile TypeScript fast, and run tsc separately only for type checking:

bashbash
tsc --noEmit

The --noEmit flag tells the compiler to check every type and report errors, but skip writing any .js files. This keeps your CI pipeline fast: the bundler handles compilation, and the noEmit check catches type errors before they reach production.

This pattern is especially common in frontend projects using frameworks like Next.js or Vite, where the framework's own build tool already handles TypeScript compilation at lightning speed. You get the best of both worlds: fast builds and thorough type-checking.

Watch mode for development

During development, you want the compiler to re-check your code every time you save a file. Watch mode keeps tsc alive in the background and recompiles on every change:

bashbash
tsc --watch

This keeps tsc running in the background. When you change a .ts file, it recompiles only what is affected. You get near-instant feedback on type errors as you work, without manually re-running the compiler each time.

To see what the compiler actually produces, let's look at a complete example from source to output.

Compiler output: a quick look

Here is a small TypeScript file and what tsc produces from it:

typescripttypescript
function add(a: number, b: number): number {
  return a + b;
}
 
console.log(add(5, 3));

Run tsc on this file and you get clean JavaScript. Every type annotation is stripped away, leaving only the runtime code:

javascriptjavascript
function add(a, b) {
  return a + b;
}
console.log(add(5, 3));

The number annotations after each parameter and the return type both disappeared. The JavaScript is identical to code you would write by hand, and nothing about the runtime behavior changed.

Common tsc commands

CommandWhat it does
tscCompile the project using the nearest tsconfig.json
tsc --noEmitType-check only, produce no .js files
tsc --watchRecompile automatically on file changes
tsc --initCreate a new tsconfig.json with recommended defaults
tsc --project tsconfig.prod.jsonUse a specific config file
tsc --versionPrint the TypeScript version

Target and version compatibility

The TypeScript compiler can target many versions of JavaScript. The target option in tsconfig controls how modern syntax is downleveled. For example, with target set to ES5, an arrow function becomes a regular function expression. With target set to ES2022, it stays as-is.

The special value ESNext means "the highest version this TypeScript release supports." It is convenient but can change behavior between TypeScript upgrades, so pinning a specific target like ES2022 is safer for production projects.

When to use tsc vs other tools

tsc is the official compiler and the only tool that does full type-checking. Other tools can strip types faster because they skip type-checking entirely:

ToolType-checks?SpeedBest for
tscYesSlowerCI type-checking, .d.ts generation
esbuildNoVery fastDev server, production builds
SWCNoVery fastDev server, production builds
BabelNoFastLegacy project support

Use tsc when you need reliable type-checking in CI, when you are generating declaration files, or when you want the simplest setup with no extra dependencies. Pair tsc with a bundler when you need fast dev reloads plus type safety.

For details on setting up your project configuration, read about important tsconfig options. To understand how to generate your config from scratch, see the guide on creating a tsconfig file.

Rune AI

Rune AI

Key Insights

  • tsc compiles .ts files to .js and checks types, but does not run your code.
  • Use tsc with no arguments to compile a project that has a tsconfig.json.
  • Use tsc --noEmit to type-check without producing output files.
  • Use tsc --watch to recompile automatically on file changes.
  • Modern projects often use a bundler for compilation and tsc only for type checking.
RunePowered by Rune AI

Frequently Asked Questions

Does the TypeScript compiler run my code?

No. tsc compiles TypeScript to JavaScript and checks types, but it does not execute your code. You run the output .js files with Node.js, a bundler, or a browser like any JavaScript code.

Can I use TypeScript without running tsc?

Yes. Many build tools like Vite, esbuild, and SWC can compile TypeScript without tsc. They strip types for speed but do not type-check. You still run tsc separately for type checking, often with --noEmit.

What is the difference between tsc and a bundler?

tsc compiles individual .ts files to .js files. A bundler like Vite or Webpack combines many files into optimized bundles for the browser. Modern projects often use a bundler for compilation and tsc only for type checking.

Conclusion

The TypeScript compiler is the bridge between the .ts files you write and the .js files that actually run. It type-checks your code and produces clean JavaScript output. You can use it as your full build tool, pair it with a bundler, or run it only for type checking while another tool handles compilation.