"tscis just a JavaScript program. It reads.ts, it writes.js. Everything else is configuration."
What tsc actually is
tsc is the TypeScript compiler — a Node.js program shipped as part of the typescript npm package. You run it, it reads your .ts files, type-checks them, and writes .js files. That's the whole job description. Everything else — bundlers, dev servers, IDE integration — wraps this same compiler API.
You don't need a bundler to use TypeScript. You don't need Vite, Next.js, or Webpack. They make life nicer, but tsc on its own can compile any TypeScript project. In this lesson we install tsc, point it at a single file, and watch it work.
The three install options
1. Project-local: npm install --save-dev typescript in a project folder. Pinned in package.json, runs via npx tsc. This is what almost every real project does. Every collaborator gets the same compiler version.
2. Global: npm install -g typescript. Available everywhere as plain tsc. Fine for tinkering or one-off scripts. Don't rely on it inside a team project — version drift between machines is a pain.
3. Run-once: npx -p typescript@latest tsc hello.ts. No install. Slower per-invocation but useful for a quick experiment.
tsconfig.json — the only config file you need
Without a tsconfig.json, tsc falls back to defaults that are wrong for most projects (loose mode, ES5 target, CommonJS modules). With one, tsc picks up the entire project layout automatically. Run npx tsc --init and it writes a starter tsconfig.json that's heavily commented and explains every option.
The four fields that matter for your first compile: target (which JavaScript version to emit — almost always 'ES2022' or newer in 2026), module (how to emit imports/exports — usually 'NodeNext' or 'ESNext'), strict (we'll cover this next lesson — leave it true), and outDir (where compiled JS goes — usually 'dist').
tsc is a build step that turns one tree of .ts files into a parallel tree of .js files in outDir. The .ts files are your source. The .js files are the artifact. Edit the source, run the build, ship the artifact.The compile happens in two phases
Phase 1: type-checking. tsc reads every file, builds a global type graph, and flags any inconsistencies — wrong argument types, missing return statements, calls to non-existent methods. If errors are found, tsc reports them (and by default, does NOT emit JS files).
Phase 2: emit. tsc walks each file, strips the type annotations, down-levels any newer JavaScript syntax to the configured target, and writes the .js file to outDir. This phase is mechanical — no opinions, no transformations beyond what's needed.
You can run just phase 1 with tsc --noEmit. This is what CI uses, and what your IDE uses silently as you type.
Pippa's confession
tsc -b (the build mode for project references) plus Vite for the actual dev/build pipeline. But when I want to understand a TypeScript issue — really understand it — I run plain tsc against a single file. No Vite, no bundler, no plugin. Just compiler in, compiler out. It's the cleanest way to isolate "is this a TS problem or a tooling problem?"