Bits Kingdom logo with a hexagon lattice, uppercase text in white, and a minimalistic design.

Strictly Typed: Taking TypeScript to Production—Performance and Best Practices

TypeScript From Zero to Production-Ready Code - Chapter 8

Home / Development / Strictly Typed: Taking TypeScript to Production—Performance and Best Practices

Writing clean TypeScript in development is one thing, but running it smoothly in production is another. Over the years, I’ve learned that production-ready TypeScript requires careful configuration, bundling strategies, and strict attention to type safety in CI/CD pipelines. In this chapter, we’ll go through the essential best practices for compiling, bundling, optimizing, and maintaining TypeScript projects in real-world production environments.

3D TypeScript logo for a series of posts.

1. Compiling TypeScript for Production

When preparing for production, focus on:

  • Fast build times
  • Small, optimized output
  • Guaranteed type safety

Use tsc for type-only builds:

npx tsc --noEmit

Use bundlers for final output:

  • Frontend: Vite, Webpack, esbuild, Parcel
  • Backend: tsup, swc, rollup, esbuild

Example with tsup:

npx tsup src/index.ts --format esm,cjs --dts

2. Stripping Types in Production Builds

Ensure .ts files are never deployed. Output should include .js, .map, and .d.ts files only.

{
  "compilerOptions": {
    "outDir": "dist",
    "declaration": true,
    "emitDeclarationOnly": false
  }
}

3. Catching Errors Before Shipping

Run type checks as part of your CI pipeline:

"scripts": {
  "type-check": "tsc --noEmit"
}

This blocks unsafe deployments if types don’t pass.

4. Minimizing Bundle Size in TypeScript Apps

  • Stick to ESModules for better tree-shaking.
  • Avoid require or dynamic imports when unnecessary.
  • Use sideEffects: false in package.json when safe.
  • Analyze bundles with Bundlephobia or Webpack Bundle Analyzer.
  • Use dynamic import() for lazy loading in React/Next.js.

5. Generating .d.ts Files for TypeScript Libraries

If you’re publishing a library, always ship type definitions:

{
  "declaration": true,
  "emitDeclarationOnly": true
}

Tools like rollup-plugin-dts or tsup –dts help automate this.

6. Type-Checking External APIs and Environments

Type definitions shouldn’t stop at your code—extend them to APIs, environment variables, and config files.

interface ApiResponse<T> {
  data: T;
  status: number;
  error?: string;
}

Environment variables:

// env.d.ts
declare namespace NodeJS {
  interface ProcessEnv {
    API_URL: string;
    NODE_ENV: "development" | "production";
  }
}

7. Error Handling with Strong Types

Model state and error handling with discriminated unions:

type Result<T> =
  | { status: "ok"; data: T }
  | { status: "error"; message: string };

8. Recommended tsconfig.json for Production

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "outDir": "./dist",
    "declaration": true,
    "removeComments": true,
    "strict": true,
    "noUnusedLocals": true,
    "noImplicitAny": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src"]
}

9. Securing TypeScript Builds

  • Never ship raw .ts files.
  • Lock down environment variables with .env.production.
  • Use type-safe wrappers for configuration.

10. Monitoring and Maintaining Type Safety

  • Run type-checks in CI/CD.
  • Use ts-prune for dead code detection.
  • Use tsc-alias if relying on path aliases.

Quick Recap

  • Compile and bundle separately for efficiency.
  • Strip types from production builds—deploy only .js and .d.ts.
  • Automate type-checks in your pipeline.
  • Model errors with discriminated unions for safer runtime handling.
  • Publish .d.ts files alongside libraries.
  • Follow production best practices to secure and optimize builds for long-term maintainability.

Coming up next: Common TypeScript Pitfalls & FAQ—debug tricky type errors, clear up common myths, and answer frequently asked questions that every developer eventually runs into.

About the author

<a href="https://bitskingdom.com/blog/author/heberlyn/" target="_self">Heberlyn Mendoza</a>
Heberlyn Mendoza
I have been building my experience as a Full Stack Developer for around 5 years. I'm passionate about challenges, finding issues and blockers to explore my creativity and ingenuity, and then getting the satisfaction of getting things done. I always like to do different things, move on, and learn something different every day.

Explore more topics:

Strictly Typed: TypeScript with React & Next.js. Real-World Usage

From Zero to Production-Ready Code – Chapter 6