Skip to content

Join the Seedly owners community →

TypeScript

Setting Up a TypeScript Project

Configuring tsconfig.json and setting up a TypeScript project from scratch

Written by 15 min read1 activity
Sprout, your presenter

Sprout presents

tsconfig.json has dozens of options, and we will examine only the essential ones. Restraint is difficult for me, but I will manage.tsconfig.json has dozens of options, and we will examine only the essential ones. Restraint is difficult for me, but I will manage.

Sprout hangs tools on a pegboard over a tidy wooden workbench with a toolbox and rolled plan
A project needs its workbench set up before you build

You've learned the TypeScript language. Cool. Now let's actually set up a project.

Think of it like setting up a workshop. You've got the skills (your TypeScript knowledge), but you still need a workbench (the project configuration) and the right tools on the wall (compiler options) before you can build a darn thing.

Starting from Scratch#

Setting up a TypeScript project only takes a few steps.

Step 1. Initialize Your Project#

Make a new folder and initialize it with npm.

mkdir my-typescript-project
cd my-typescript-project
npm init -y

That gives you a package.json file, which keeps track of your project's dependencies.

Step 2. Install TypeScript#

Add TypeScript as a development dependency.

npm install --save-dev typescript @types/node

That installs the TypeScript compiler (tsc) right inside your project, plus @types/node, which teaches TypeScript about Node.js stuff like console and process. (Newer TypeScript versions don't load those type packages automatically anymore, so we'll point at it in the config below.)

Step 3. Create tsconfig.json#

Generate a TypeScript configuration file.

npx tsc --init

That creates a starter tsconfig.json file. What's inside depends on your TypeScript version... older versions dump in every option with most of them commented out, and newer ones give you a shorter starter with a few lines you're meant to uncomment. Either way, don't panic. We're about to swap in our own version anyway.

Step 4. Create Your First File#

Make a src folder for your first TypeScript file.

mkdir src

Then create src/index.ts and put some TypeScript in it.

Step 5. Compile and Run#

Compile your TypeScript into JavaScript, then run it. (This step expects your compiled files to land in a dist folder, which the config in the next section sets up. A fresh starter config might drop them next to your source files instead.)

npx tsc
node dist/index.js

Understanding tsconfig.json#

The tsconfig.json file is the control panel for how TypeScript compiles your code. Here's a beginner-friendly setup.

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "nodenext",
    "lib": ["ES2022"],
    "types": ["node"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "declaration": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Let's break down what each of those does.

Essential Compiler Options#

Target and Module#

{
  "target": "ES2022",
  "module": "nodenext"
}
  • target - Which version of JavaScript to spit out. ES2022 is a safe modern pick for current Node.js. Older targets rewrite modern syntax so older runtimes can handle it.
  • module - Which module system to use. nodenext for modern Node.js projects, esnext or preserve when a bundler like Vite handles your code.

Types#

{
  "types": ["node"]
}
  • types - Which global type packages to load. TypeScript 6 and up loads none by default, so without "node" in here even console.log gets flagged as an error (fun way to start your first file, right?).

Directories#

{
  "outDir": "./dist",
  "rootDir": "./src"
}
  • outDir - Where the compiled JavaScript files go. Keeps your source and your output from getting mixed up.
  • rootDir - Where your TypeScript source files live.

Strict Mode#

{
  "strict": true
}

Strict mode flips on all the strict type-checking options in one shot. TypeScript 6 and up turns it on by default, but write it in anyway so nobody reading your config has to guess. If you only remember ONE option from this lesson, make it this one, because it catches the most bugs. Here's some of what it turns on.

  • noImplicitAny - Throws an error when TypeScript can't figure out a type (instead of quietly falling back to any)
  • strictNullChecks - Makes you deal with null and undefined
  • strictFunctionTypes - Tighter checking on function types
  • Plus a handful more safety checks
// Without strict mode:
function greet(name) {      // name is implicitly 'any' - no warning
  return name.toUpperCase();
}
greet(42); // Crashes at runtime!
 
// With strict mode:
function greet(name) {      // Error! Parameter 'name' implicitly has 'any' type
  return name.toUpperCase();
}
// Forces you to add a type annotation
function greet(name: string) {  // Now it's safe
  return name.toUpperCase();
}

Project Scripts#

Add a few handy scripts to your package.json.

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "tsc --watch",
    "lint": "tsc --noEmit"
  }
}
  • build - Compiles TypeScript into JavaScript
  • start - Runs the compiled code
  • dev - Watches for changes and recompiles automatically
  • lint - Checks for type errors without writing any files

TypeScript with Frameworks#

Most modern frameworks come with TypeScript support baked right in.

Next.js (React)#

npx create-next-app@latest my-app --typescript

Next.js sets up TypeScript for you with a sensible tsconfig.json. Your components use the .tsx extension.

Vite (React, Vue, etc.)#

npm create vite@latest my-app -- --template react-ts

Vite gives you fast TypeScript compilation and hot module reloading, so the page updates the moment you save.

Running TypeScript Directly in Node.js#

If you want to run TypeScript directly and skip the compile step, newer Node.js (22.18 and up) can do it with no extra packages.

node src/index.ts

Node just strips the types out and runs what's left. It does NOT check your types, so keep npx tsc --noEmit around to catch mistakes.

Common File Extensions#

Sprout sifts sand through a fine brass sieve that catches small pebbles, a coarse sieve set aside
Strict mode catches the bugs that would otherwise slip through
ExtensionUsed For
.tsRegular TypeScript files
.tsxTypeScript files with JSX (React components)
.d.tsType declaration files (types only, no runtime code)
.jsCompiled JavaScript output
.js.mapSource maps (for debugging)

Adding Type Declarations for Libraries#

Some JavaScript libraries don't come with TypeScript types. No biggie, you can install the type declarations separately.

# If a library doesn't have built-in types, check DefinitelyTyped
npm install --save-dev @types/lodash
npm install --save-dev @types/express
npm install --save-dev @types/node

The @types/ packages hand TypeScript the type info for popular JavaScript libraries.

A Complete Project Structure#

Here's what a typical TypeScript project looks like.

my-project/
  src/
    index.ts          # Entry point
    types.ts          # Shared type definitions
    utils/
      helpers.ts      # Utility functions
    services/
      api.ts          # API calls
  dist/               # Compiled output (gitignored)
  node_modules/       # Dependencies (gitignored)
  package.json        # Project config
  tsconfig.json       # TypeScript config
  .gitignore          # Git ignore rules

TL;DR#

  • Start a TypeScript project with npm init and npm install typescript
  • tsconfig.json controls how TypeScript compiles your code
  • ALWAYS turn on strict: true for the most type safety
  • Use outDir and rootDir to keep source and compiled output apart
  • Modern frameworks like Next.js and Vite have TypeScript support built in
  • Install @types/ packages for libraries that don't ship their own types
  • Use .ts for regular files and .tsx for React component files

What's Next?#

You've got a real project set up now, with a config that catches your mistakes. In the last lesson of this module we bring React into it... typing component props, state and events.

This lesson ends with a short activity.