# ts2esm

> Transforms TypeScript imports and exports into ESM-compatible declarations.

Latest version **3.0.0** (published 2026-10-01) · MIT license · 0 weekly downloads

## Install

```sh
npm install ts2esm
pnpm add ts2esm
yarn add ts2esm
bun add ts2esm
```

Provides the command `ts2esm`.

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 3.0.0 |
| Published | 2026-10-01 |
| First published | 2023-10-25 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=23.5.0 \|\| ^22.13.0 \|\| ^20.17.0 |
| Dependencies | 9 |
| Unpacked size | 64.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 82 |
| Maintainers | bennycode |
| Keywords | codemod, ecmascript, esm, tsc, typescript |

## Links

- npm: https://www.npmjs.com/package/ts2esm
- Repository: https://github.com/bennycode/ts2esm
- Homepage: https://www.npmjs.com/package/ts2esm
- Issues: https://github.com/bennycode/ts2esm/issues
- npm.io page: https://npm.io/package/ts2esm

## Dependencies (9)

- [jju](https://npm.io/package/jju.md) ^1.4.0
- [ts-morph](https://npm.io/package/ts-morph.md) ^28.0.0
- [json-diff](https://npm.io/package/json-diff.md) ^1.0.6
- [jsonpatch](https://npm.io/package/jsonpatch.md) ^3.1.0
- [@types/jju](https://npm.io/package/@types/jju.md) ^1.4.5
- [typescript](https://npm.io/package/typescript.md) 6.0.3
- [@inquirer/core](https://npm.io/package/@inquirer/core.md) ^12.0.3
- [@types/json-diff](https://npm.io/package/@types/json-diff.md) ^1.0.3
- [@inquirer/prompts](https://npm.io/package/@inquirer/prompts.md) ^8.7.2

## Alternatives

- [@openai/codex-sdk](https://npm.io/package/@openai/codex-sdk.md) — 731.4K weekly downloads
- [babel-plugin-transform-react-jsx](https://npm.io/package/babel-plugin-transform-react-jsx.md) — 565.0K weekly downloads
- [babel-helper-remove-or-void](https://npm.io/package/babel-helper-remove-or-void.md) — 508.5K weekly downloads
- [@pnpm/store-controller-types](https://npm.io/package/@pnpm/store-controller-types.md) — 186.9K weekly downloads
- [react-native-signature-canvas](https://npm.io/package/react-native-signature-canvas.md) — 155.6K weekly downloads

## Recent versions

- 3.0.0 (latest) — 2026-10-01
- 2.2.7 — 2024-11-27
- 2.2.6 — 2024-11-22
- 2.2.5 — 2024-11-18
- 2.2.4 — 2024-11-17
- 2.2.3 — 2024-11-17
- 2.2.2 — 2024-11-17
- 2.2.1 — 2024-11-16
- 2.2.0 — 2024-10-25
- 2.1.0 — 2024-07-22
- 2.0.2 — 2024-06-07
- 2.0.1 — 2024-06-07
- 2.0.0 — 2024-04-27
- 1.4.0 — 2024-01-23
- 1.3.0 — 2024-01-14
- … 12 more at https://npm.io/package/ts2esm/versions

## README

# ts2esm

You want to transform your TypeScript project into an ECMAScript module (ESM)? Look no further! This tool (`ts2esm`) converts your import and export declarations into ESM-compatible ones. It's the ideal tool for converting a CommonJS project to ESM. It also [works with plain JavaScript](https://github.com/bennycode/ts2esm/issues/20#issuecomment-1894702085) projects! 🪄

## Installation

Simply run this command to install `ts2esm` globally on your machine:

```bash
npm i -g ts2esm
```

You can also run it locally (without being globally installed):

```bash
npx ts2esm
```

## Usage

Convert your CommonJS projects (TypeScript or JavaScript) into ECMAScript modules with a single command. Just launch the program inside the directory of your project (it will ask you for your `tsconfig.json` path):

```bash
ts2esm
```

You can also provide a list of tsconfigs (no prompt):

```bash
ts2esm packages/foo/tsconfig.json packages/bar/tsconfig.json
```

Note: The path can be specified absolutely (i.e. `/home/user/cornerstone3D/tsconfig.json`) or relative (i.e. `../../cornerstone3D/tsconfig.json`).

There is also a debug mode with verbose logging:

```bash
ts2esm --debug
```

> [!WARNING]  
> Make sure you have a backup (in Git or similar) of your code as "ts2esm" will modify your source code.

> [!IMPORTANT]  
> Use TypeScript 5.2 or later as there have been [breaking changes to the Node.js settings](https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#breaking-changes-and-correctness-fixes), which you don't want to miss.

> [!IMPORTANT]  
> Since TypeScript 5.3 import assertions are [replaced with import attributes](https://devblogs.microsoft.com/typescript/announcing-typescript-5-3-beta/#import-attributes).

## Step-by-Step Guide

This workflow migrates a CommonJS project and checks its types:

```bash
# Build your project
npx tsc

# Check your types
npx @arethetypeswrong/cli --pack .

# Convert to ESM
npx ts2esm tsconfig.json

# Rebuild your project
npx tsc

# Check your types again
npx @arethetypeswrong/cli --pack . --ignore-rules cjs-resolves-to-esm
```

## Video Tutorial

Watch this 5-minute video and learn how to migrate from CommonJS to ESM:

[<img src="https://i.ytimg.com/vi_webp/bgGQgSQSpI8/mqdefault.webp">](https://youtu.be/bgGQgSQSpI8)

## Examples

Here you can see the transformations that `ts2esm` applies.

### Require Statements

Before:

```ts
const fs = require('node:fs');
const path = require('path');
```

After:

```ts
import fs from 'node:fs';
import path from 'path';
```

### Module Exports

Before:

```ts
const Benny = 1;
const Code = 2;

module.exports = Benny;
module.exports.Code = Code;
```

After:

```ts
const Benny = 1;
const Code = 2;

export default Benny;
export {Code};
```

### Import Declarations

Before:

```ts
import {AccountAPI} from '../account';
import {RESTClient} from './client/RESTClient';
import {removeSuffix} from '@helpers/removeSuffix';
```

After:

```ts
import {AccountAPI} from '../account/index.js';
import {RESTClient} from './client/RESTClient.js';
import {removeSuffix} from '@helpers/removeSuffix.js';
```

### Export Declarations

Before:

```ts
export * from './account';
export * from './UserAPI';
```

After:

```ts
export * from './account/index.js';
export * from './UserAPI.js';
```

### JSON Import Attributes

Before:

```ts
import listAccounts from '../test/fixtures/listAccounts.json';
```

After:

```ts
import listAccounts from '../test/fixtures/listAccounts.json' with {type: 'json'};
```

### CSS Import Attributes

Before:

```ts
import styles from './MyComponent.module.css';
```

After:

```ts
import styles from './MyComponent.module.css' with {type: 'css'};
```

## How it works

The `ts2esm` program adjusts your relative imports, adding extensions like `index.js` or `.js` to make them ESM-compatible. Say goodbye to import errors such as **TS2305**, **TS2307**, **TS2834**, and [**TS2835**](https://typescript.tv/errors/#ts2835)!

Errors that get automatically fixed (🛠️):

> TypeError [ERR_IMPORT_ASSERTION_TYPE_MISSING]: Module needs an import assertion of type "json"

> error TS2834: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Consider adding an extension to the import path.

> error TS2835: Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'.

## Noteworthy

With ESM, you can no longer use Node.js objects like `__filename` or `__dirname`. Here is a simple snippet to replicate their behavior using the [import.meta property](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta):

```ts
import path from 'node:path';
import url from 'node:url';

const __filename = url.fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
```

## Credits

This program was born from an [inspiring conversation](https://twitter.com/bennycode/status/1693362836695585084) I had with [Basarat Ali Syed](https://twitter.com/basarat). I recommend checking out [Basarat's coding tutorials](https://www.youtube.com/@basarat). 👍

## Attributions

- ts2esm got highlighted in Deno's article on [How to convert CommonJS to ESM](https://deno.com/blog/convert-cjs-to-esm#tools-for-migrating)
- ts2esm helped migrating [cornerstonejs/cornerstone3D](https://github.com/cornerstonejs/cornerstone3D) from CommonJS to ESM

## Used By

[<img src="https://ohif.org/static/c99ccbad57599dbf9f3490519c9b444f/63739/ohif-logo-dark.png" width="256"/>](https://ohif.org/)

## Vision

Ideally, the extension change would be available as a [codefix in TypeScript](https://github.com/microsoft/TypeScript/tree/v5.3.3/src/services/codefixes) itself. Then all conversions could be applied using [ts-fix](https://github.com/microsoft/ts-fix).

## References

- [TypeScript's Module Resolution](https://www.typescriptlang.org/docs/handbook/modules/theory.html#module-resolution-is-host-defined)
- [TypeScript AST Viewer](https://ts-ast-viewer.com/)
- [Are the types wrong?](https://github.com/arethetypeswrong/arethetypeswrong.github.io)

---
_Source: https://npm.io/package/ts2esm · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
