Plain TypeScript vs TypeScript with SWC in Vite: Key Differences and Setup Guide

Vite provides built-in TypeScript support via esbuild by default, but you can opt into SWC for faster transpilation and broader syntax support by installing specific plugins like @rollup/plugin-swc or @vitejs/plugin-react-swc.

When scaffolding a new project with create-vite, you face a choice between standard TypeScript templates and those prefixed with -swc. According to the vitejs/vite repository, this decision impacts your build pipeline, development server performance, and which experimental JavaScript features you can use. Both approaches skip type checking during the build process, requiring a separate tsc --noEmit step for full type safety.

How Vite Handles Plain TypeScript by Default

Vite’s default TypeScript implementation relies on esbuild, a Go-based bundler that handles transpilation. As documented in docs/guide/typescript.md, Vite uses esbuild to convert .ts and .tsx files to JavaScript instantly during development and production builds.

Key characteristics of plain TypeScript in Vite:

  • No type checking: The transformation process strips TypeScript types but does not validate them. You must run tsc --noEmit separately or use IDE integration for type safety.
  • Configuration: Only requires a standard tsconfig.json. No additional Vite plugins are necessary.
  • Limitations: Esbuild tracks TC39 proposals conservatively. Experimental syntax like the latest decorators proposal may not be supported, causing build errors if used in your source code.

Understanding TypeScript with SWC in Vite

SWC is a Rust-based compiler that serves as an alternative transpiler to esbuild. In the vitejs/vite ecosystem, SWC integration is achieved through Rollup-compatible plugins rather than core Vite functionality, as noted in docs/guide/migration.md.

When to consider SWC:

  • Your codebase contains experimental JavaScript syntax unsupported by esbuild
  • You require the fastest possible cold start and HMR performance for large projects
  • Your organization standardizes on SWC across multiple tools (e.g., Next.js, Jest transforms)

Key Differences: Plain TypeScript vs TypeScript with SWC

The choice between esbuild and SWC impacts several technical dimensions of your Vite project.

Performance Characteristics

Plain TypeScript (esbuild): Provides sub-second transpilation for most projects, typically 10× faster than the TypeScript compiler alone. However, for monorepos with thousands of modules, you may notice slower cold starts compared to SWC.

TypeScript with SWC: Delivers approximately 10–20% faster cold start times and HMR updates in large codebases. The Rust implementation parses entire files in a single pass, reducing overhead during the transformation pipeline.

Syntax and Feature Support

Plain TypeScript limitations: As implemented in packages/vite/src/node/plugins/resolve.ts, Vite’s esbuild integration handles JSX, imports/exports, and modern ES2022 syntax. However, it lacks support for certain TC39 proposals, notably the decorators metadata specification and some advanced TypeScript declaration emit features.

SWC advantages: SWC supports a broader range of experimental syntax, including:

  • Class properties and decorators (legacy and newer proposals)
  • Optional chaining and nullish coalescing (optimized transforms)
  • Custom SWC plugins via @swc/plugin-import for macro transformations

Configuration Complexity

Plain TypeScript setup:

  • Requires only tsconfig.json in project root
  • Zero Vite configuration needed
  • No additional dependencies beyond vite and typescript

TypeScript with SWC setup:

  • Requires installing @rollup/plugin-swc and @swc/core
  • Needs vite.config.ts modification to register the plugin
  • Optional .swcrc file for granular compiler options
  • Must ensure SWC options align with tsconfig.json settings to avoid transform mismatches

Source Map Accuracy

Plain TypeScript: Esbuild generates source maps quickly, but in complex transformation chains (especially when combined with CSS preprocessing), line and column offsets may occasionally drift.

TypeScript with SWC: Produces high-fidelity source maps because the Rust parser maintains precise AST positioning throughout the single-pass transformation, making debugging more reliable in browser DevTools.

Setting Up TypeScript with SWC in Vite

Depending on your framework choice, you have two primary paths to enable SWC.

General TypeScript Projects

For non-React projects or custom setups, use @rollup/plugin-swc:

npm install -D @rollup/plugin-swc @swc/core
// vite.config.ts
import { defineConfig } from 'vite'
import swc from '@rollup/plugin-swc'

export default defineConfig({
  plugins: [
    swc({
      jsc: {
        parser: {
          syntax: 'typescript',
          tsx: true,
          decorators: true
        },
        target: 'es2022',
        transform: {
          react: {
            runtime: 'automatic',
            development: true,
            refresh: true
          }
        }
      },
      sourceMaps: true
    })
  ]
})

Optionally, extract configuration to .swcrc:

{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": true,
      "decorators": true
    },
    "target": "es2022"
  },
  "sourceMaps": true
}

React Projects with SWC

For React applications, the official @vitejs/plugin-react-swc provides optimized JSX transforms and Fast Refresh:

npm install -D @vitejs/plugin-react-swc
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'

export default defineConfig({
  plugins: [react()]
})

As documented in the template-react-swc-ts README, this configuration replaces Babel with SWC for React files while allowing esbuild to handle non-React TypeScript, creating a hybrid pipeline optimized for React development.

Summary

  • Plain TypeScript in Vite uses esbuild for zero-config transpilation, offering excellent performance for most projects but limited support for experimental syntax like certain decorator proposals.
  • TypeScript with SWC requires installing @rollup/plugin-swc or framework-specific plugins like @vitejs/plugin-react-swc, trading minimal configuration for 10–20% faster build times and broader TC39 proposal support.
  • Both approaches skip type checking during the build process, necessitating a separate tsc --noEmit command or CI step to ensure type safety.
  • SWC produces more accurate source maps and handles complex transformations in a single Rust-based pass, making it ideal for large monorepos or projects requiring experimental JavaScript features.

Frequently Asked Questions

Does Vite type-check TypeScript during the build process?

No. Whether you use plain TypeScript with esbuild or TypeScript with SWC, Vite only transpiles your code by stripping type annotations and converting syntax. It does not perform type checking. You must run tsc --noEmit separately, either in your IDE, as a pre-commit hook, or in CI/CD pipelines, to validate type safety.

Can I use SWC only for specific files while keeping esbuild for others?

Yes. When using @rollup/plugin-swc, you can configure the include or exclude options to target specific file patterns. For React projects, @vitejs/plugin-react-swc automatically applies SWC only to JSX/TSX files containing React components, while Vite's default esbuild handler processes standard TypeScript files, creating an efficient hybrid pipeline.

What experimental syntax requires SWC instead of the default esbuild?

If your codebase uses the legacy TypeScript decorators (experimentalDecorators) or certain TC39 proposals like class static blocks in specific configurations, esbuild may fail with syntax errors. SWC supports a broader range of experimental features, including various decorator implementations and advanced JSX transforms, making it necessary when esbuild's conservative syntax support is insufficient for your project requirements.

Is there a performance difference between @rollup/plugin-swc and @vitejs/plugin-react-swc?

Both plugins leverage the same SWC core written in Rust, so the underlying transformation speed is identical. However, @vitejs/plugin-react-swc is optimized specifically for React's Fast Refresh and JSX runtime, potentially offering smoother Hot Module Replacement (HMR) in React applications. For non-React projects, @rollup/plugin-swc provides more granular control over general TypeScript and JavaScript transformation settings.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →