# Tsx
> Compiling your TypeScript files to JavaScript is not handled by _tsx_, but it's a necessary step in most setups.
---
# Source: https://tsx.is/
# Compilation
Compiling your TypeScript files to JavaScript is not handled by _tsx_, but it's a necessary step in most setups.
::: info Should I publish TypeScript files?
No. While _tsx_ is capable of running TypeScript files in dependencies if need be (e.g. monorepos), it's highly discouraged to publish uncompiled TypeScript. Source files require a specific compilation configuration in `tsconfig.json` which may not be read, and [TypeScript performance will degrade](https://x.com/atcb/status/1705675335814271157).
:::
## Compiling an npm package
npm packages are distinguished from applications by defining package entry-points in `package.json`.
[pkgroll](https://github.com/privatenumber/pkgroll) is the recommended bundler for projects using _tsx_. It's developed by the same author and used to compile _tsx_.
Given your source files are in the `src` directory, it automatically infers how to build your package based on the entry points defined in `package.json` by outputting them to the `dist` directory.
### Setup
::: details Basic setup
Set your entry-point in [`exports`](https://nodejs.org/api/packages.html#exports):
```json5
// package.json
{
"exports": "./dist/index.mjs"
}
```
:::
::: details Dual package (CJS & ESM)
Set your CommonJS & Module entry-points in [`exports`](https://nodejs.org/api/packages.html#exports):
```json5
// package.json
{
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.cts",
"exports": {
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
},
"import": {
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
}
}
}
```
:::
::: details Command-line package
Set your CLI entry-point in [`bin`](https://docs.npmjs.com/cli/v10/configuring-npm/package-json#bin):
```json5
// package.json
{
"bin": "./dist/cli.mjs"
}
```
:::
### Build
In your directory, simply run `pkgroll`:
::: code-group
```sh [npm]
$ npx pkgroll
```
```sh [pnpm]
$ pnpm pkgroll
```
```sh [yarn]
$ yarn pkgroll
```
:::
Optionally, add a `build` script for convenience:
```json
// package.json
{
// Optional: build script
"scripts": {// [!code ++]
"build": "pkgroll"// [!code ++]
}// [!code ++]
}
```
---
# Source: https://tsx.is/
# Contact
---
# Source: https://tsx.is/
# Entry-point
Import `tsx` at the top of your entry-file:
```js
import 'tsx'
// Now you can load TS files
await import('./file.ts')
```
Note, because of the order of static import evaluatation in ESM, the enhancement only works on [dynamic imports after registeration](https://nodejs.org/docs/latest-v22.x/api/module.html#:~:text=dynamic%20import()%20must%20be%20used%20for%20any%20code%20that%20should%20be%20run%20after%20the%20hooks%20are%20registered).
::: danger
Enhancing Node.js by loading _tsx_ from within your source code at run-time can be unexpected for collaborators who aren’t aware of it.
When possible, it's recommended to use a more visible method, such as passing it as a [CLI flag](/dev-api/node-cli).
:::
## Advanced usage
### CommonJS mode only
Require `tsx/cjs` at the top of your entry-file:
```js
require('tsx/cjs')
// Now you can load TS files
require('./file.ts')
```
### Module mode only
Import `tsx/esm` at the top of your entry-file:
```js
import 'tsx/esm'
// Now you can load TS files
await import('./file.ts')
```
---
# Source: https://tsx.is/
# Developer API
The Developer API allows you to enhance Node.js with _tsx_ without needing to use the `tsx` command.
Note that CLI features such as [_Watch mode_](/watch-mode.md) and the [REPL](/usage#repl) will not be available.
## Use-cases
### Directly running `node`
Sometimes, you may need to run `node` directly but still want to use _tsx_. Instead of using the `tsx` command, you can pass it to Node with [`node --import tsx`](/dev-api/node-cli) or you can do [`import 'tsx'`](/dev-api/entry-point) at the top of your script. This is helpful when you need more control over the Node.js environment, are integrating with tools that specifically call `node`, or simply prefer using the `node` command.
### 3rd party packages
Some third-party packages need to load TypeScript files, like configuration files, without affecting the entire runtime environment. The [`tsImport()` API](/dev-api/ts-import) allows these packages to load TypeScript files natively, without causing side effects to the environment.
## Understanding module types
Understanding the Node.js module types, CommonJS (CJS) and ES Module (ESM), can be helpful when using the Developer API.
ESM is the modern standard, indicated by the file extensions `.mjs` for JavaScript and `.mts` for TypeScript. CommonJS, the older format, uses the file extensions `.cjs` for JavaScript and `.cts` for TypeScript. When the file extension is ambiguous, such as `.js` or `.ts`, [`package.json#type`](https://nodejs.org/api/packages.html#type) is used to determine the module type. If `type` is set to `module`, the files are treated as ES Modules. If `type` is set to `commonjs` or not set at all, the files are treated as CommonJS modules.
Although both module types can coexist in the same environment, they have distinct scopes and behaviors. _tsx_ offers APIs to enhance both CommonJS and ES modules selectively. Being aware of these distinctions and knowing which module type you are using will allow you to make informed decisions when opting into these enhancements.
---
# Source: https://tsx.is/
# Node.js CLI
To use the `node` command directly with _tsx_, pass it as a flag:
```sh
node --import tsx ./file.ts
```
::: details (Deprecated) Node.js v20.5.1 and below
Older Node.js versions use a deprecated API `--loader` instead of `--import`.
```sh
node --loader tsx ./file.ts
```
:::
## Custom `tsconfig.json` path
To specify a custom path to `tsconfig.json`, use an environment variable:
```sh
TSX_TSCONFIG_PATH=./path/to/tsconfig.custom.json node --import tsx ./file.ts
```
## Binaries
If you don't have direct access to the `node` command, use the Node.js [`NODE_OPTIONS` environment variable](https://nodejs.org/api/cli.html#node_optionsoptions) to pass in the flag:
```sh
NODE_OPTIONS='--import tsx' npx some-binary
```
## Advanced usage
### CommonJS mode only
To use _tsx_ for CommonJS files only:
```sh
node --require tsx/cjs ./file.ts
```
### Module mode only
To use _tsx_ for Module files only:
```sh
node --import tsx/esm ./file.ts
```
---
# Source: https://tsx.is/
# CommonJS Register API
The CommonJS Register API allows you to manually register the enhancement at runtime. But note, this only affects CommonJS modules (`.cjs`/`.cts`, and `.js`/`.ts` when `package.json#type` is unset or `commonjs`).
::: warning Caveats
- `import()` calls in the loaded files are not enhanced because they're handled by Node's ESM hook. Use with the [`ESM Register API`](/dev-api/register-esm).
- Because it compiles ESM syntax to run in CommonJS mode, top-level await is not supported
:::
## Usage
```js
const tsx = require('tsx/cjs/api')
// Register tsx enhancement
const unregister = tsx.register()
const loaded = require('./file.ts')
// Unregister when needed
unregister()
```
### Scoped registration
If you want to register without affecting the entire runtime environment, you can add a namespace.
When a namespace is provided, it will return a private `require()` method for you to load files with:
```js
const tsx = require('tsx/cjs/api')
const api = tsx.register({
// Pass in a unique namespace
namespace: Date.now().toString()
})
// Pass in the request and the current file path
const loaded = api.require('./file.ts', __filename)
api.unregister()
```
---
# Source: https://tsx.is/
# ESM Register API
The ESM Register API allows you to manually register the enhancement at runtime. But note, this only affects ESM (`.mjs`/`.mts`, and `.js`/`.ts` when `package.json#type` is `module`).
## Usage
```js
import { register } from 'tsx/esm/api'
// Register tsx enhancement
const unregister = register()
await import('./file.ts')
// Unregister when needed
unregister()
```
### Scoped registration
If you want to register without affecting the entire runtime environment, you can add a namespace.
When a namespace is provided, it will return a private `import()` method for you to load files with:
```js
import { register } from 'tsx/esm/api'
const api = register({
// Pass in a unique namespace
namespace: Date.now().toString()
})
// Pass in the request and the current file path
// Since this is namespaced, it will not cache hit from prior imports
const loaded = await api.import('./file.ts', import.meta.url)
// This is using the same namespace as above, so it will yield a cache hit
const loaded2 = await api.import('./file.ts', import.meta.url)
api.unregister()
```
### Tracking loaded files
Detect files that get loaded with the `onImport` hook. This can be useful when you want to track dependencies when setting up a watcher.
```ts
register({
onImport: (file: string) => {
console.log(file) // 'file:///foo.ts'
}
})
```
---
# Source: https://tsx.is/
# `tsImport()`
Native dynamic `import()` function to import TypeScript files (supports [top-level await](https://v8.dev/features/top-level-await)).
Use this function for importing TypeScript files without adding TypeScript support to the entire runtime.
The current file path must be passed in as the second argument to resolve the import context.
Since this is designed for one-time use, it does not cache loaded modules.
## Usage
### ESM
```js
import { tsImport } from 'tsx/esm/api'
const loaded = await tsImport('./file.ts', import.meta.url)
// If tsImport is used to load file.ts again,
// it does not yield a cache-hit and re-loads it
const loadedAgain = await tsImport('./file.ts', import.meta.url)
```
If you'd like to leverage module caching, see the [ESM scoped registration](/dev-api/register-esm.md) section.
### CommonJS
```js
const { tsImport } = require('tsx/esm/api')
const loaded = await tsImport('./file.ts', __filename)
```
## `tsconfig.json`
### Custom `tsconfig.json` path
```ts
tsImport('./file.ts', {
parentURL: import.meta.url,
tsconfig: './custom-tsconfig.json'
})
```
### Disable `tsconfig.json` lookup
```ts
tsImport('./file.ts', {
parentURL: import.meta.url,
tsconfig: false
})
```
## Tracking loaded files
Detect files that get loaded with the `onImport` hook:
```ts
tsImport('./file.ts', {
parentURL: import.meta.url,
onImport: (file: string) => {
console.log(file)
// file:///foo.ts
}
})
```
---
# Source: https://tsx.is/
# `tsx.require()`
Native `require()` function enhanced with TypeScript & ESM support.
Use this function for importing TypeScript files in CommonJS mode without adding TypeScript support to the entire runtime.
Note, the current file path must be passed in as the second argument to resolve the import context.
::: warning Caveats
- `import()` calls in the loaded files are not enhanced. Use [`tsImport()`](/dev-api/ts-import) instead.
- Because it compiles ESM syntax to run in CommonJS mode, top-level await is not supported
:::
## Usage
### CommonJS
```js
const tsx = require('tsx/cjs/api')
const tsLoaded = tsx.require('./file.ts', __filename)
const tsFilepath = tsx.require.resolve('./file.ts', __filename)
```
### ESM
```js
import { require } from 'tsx/cjs/api'
const tsLoaded = require('./file.ts', import.meta.url)
const tsFilepath = require.resolve('./file.ts', import.meta.url)
```
## Tracking loaded files
Because the CommonJS API tracks loaded modules in `require.cache`, you can use it to identify loaded files for dependency tracking. This can be useful when implementing a watcher.
```js
const resolvedPath = tsx.require.resolve('./file', import.meta.url)
const collectDependencies = module => [
module.filename,
...module.children.flatMap(collectDependencies)
]
console.log(collectDependencies(tsx.require.cache[resolvedPath]))
// ['/file.ts', '/foo.ts', '/bar.ts']
```
---
# Source: https://tsx.is/
# Frequently Asked Questions
## How can I do ______ in _tsx_?
We understand that searching for answers about _tsx_ can be challenging due to its name. However, since _tsx_ is essentially an alias for `node` and adheres to TypeScript behavior, asking how to do something in _tsx_ might not be the best approach.
Instead, consider these questions:
- _"How can I do ______ in Node.js?"_
- _"How can I do ______ in TypeScript?"_
If your question specifically relates to _tsx_, you can use the search feature in the documentation or [ask a question](#ask-a-question).
## I found a bug in _tsx_. What should I do?
If you've confirmed that the bug is in _tsx_, please file an issue in the _tsx_ GitHub repository. Make sure to include a minimal reproduction of the bug.
File a bug report ↗
## Who uses _tsx_?
_tsx_ is recognized by both [Node.js](https://nodejs.org/en/learn/getting-started/nodejs-with-typescript#running-typescript-code-with-tsx) and [TypeScript](https://www.typescriptlang.org/docs/handbook/modules/guides/choosing-compiler-options.html#im-using-tsx) as a popular tool for running TypeScript code. It is widely adopted, as indicated by its npm download stats:
.
### Companies
### Projects
To find more examples of where & how _tsx_ is used, [search on GitHub](https://github.com/search?q=path%3Apackage.json+%22%5C%22tsx%5C%22%3A+%5C%22%22&type=code).
## How does _tsx_ compare to [`ts-node`](https://github.com/TypeStrong/ts-node)?
`tsx` and `ts-node` are both tools for running TypeScript in Node.js, each offering different approaches to suit user preferences.
**Installation**
- **tsx**: Can be used without installation (via `npx tsx ./script.ts`) and comes as a single binary with no peer dependencies.
- **ts-node**: Requires installation of TypeScript or SWC as peer dependencies.
**Configuration**
- **tsx**: Works out of the box without needing a `tsconfig.json` file, making it easy for beginners.
- **ts-node**: May require initial setup and configuration.
**Defaults**
- **tsx**: Uses sensible defaults based on file imports and Node.js version, reducing the need for certain `tsconfig.json` settings.
- **ts-node**: Relies on TypeScript's defaults, which might need adjusting.
**Module Support**
- **tsx**: Automatically adapts between CommonJS and ESM modules, supporting `require()` for ESM modules.
- **ts-node**: Provides module support but may need configuration for certain scenarios.
**Syntax and Features**
- **tsx**: Supports new JS & TS syntax and features based on Node.js version and includes support for `tsconfig.json` paths.
- **ts-node**: Uses the TypeScript compiler and may require additional settings for certain features.
**Speed**
- **tsx**: Uses [esbuild](https://esbuild.github.io/faq/#:~:text=typescript%20benchmark) for fast compilation and does not perform type checking.
- **ts-node**: Uses the TypeScript compiler by default, with an option to use the SWC compiler for faster performance.
**Watcher**
As a DX bonus, _tsx_ also comes with [Watch mode](/watch-mode.md) to help you iterate faster!
For a detailed technical comparison, refer to this [exhaustive comparison](https://github.com/privatenumber/ts-runtime-comparison) between `tsx`, `ts-node`, and other runtimes.
## Can/should _tsx_ be used in production?
Deciding whether to use _tsx_ in production depends on your specific needs and risk tolerance. Here are a few points to consider:
- _tsx_ is simply a Node.js enhancement, so you can generally expect a similar level of stability.
- _tsx_ uses [esbuild](https://esbuild.github.io) for transforming TypeScript and ESM. Although esbuild is already adopted in many production ready tools, keep in mind that it technically hasn't reached a stable release yet.
Here are some questions to help guide your decision:
- What are the benefits versus the costs of using _tsx_ in production? Are there performance improvements?
- Does _tsx_ run your code as expected? Are there any differences between development and production environments?
- Can you rely on this open-source project and its maintainers? Consider [sponsoring](https://github.com/sponsors/privatenumber/sponsorships?tier_id=416984) the project to support its growth and stability.
Ultimately, it's a decision you'll need to make based on your specific production requirements and comfort level with potential risks.
---
# Ask a question
_tsx_ offers support via [Discussions](https://github.com/pvtnbr/tsx/discussions) for [sponsors](https://github.com/sponsors/privatenumber/sponsorships?tier_id=416984). If you're a sponsor, feel free to ask more questions there!
---
# Source: https://tsx.is/
# Getting started
### Prerequisites
Before you can start using _tsx_, ensure that you have [Node.js installed](https://nodejs.org/en/download/). _tsx_ is designed to be compatible with all [maintained versions](https://endoflife.date/nodejs) of Node.js.
## Quickstart
`tsx` can be executed with [npx](https://docs.npmjs.com/cli/commands/npx/)—a tool to run npm packages without installing them.
In your command-line, simply pass in a TypeScript file you'd like to run. It's that simple!
```sh
npx tsx ./script.ts
```
## Project installation
To install `tsx` as a project development dependency, run the following command in your project directory:
::: code-group
```sh [npm]
$ npm install -D tsx
```
```sh [pnpm]
$ pnpm add -D tsx
```
```sh [yarn]
$ yarn add -D tsx
```
:::
#### Using `tsx`
Once installed, you can invoke it with your package manager while in the project directory:
::: code-group
```sh [npm]
$ npx tsx ./file.ts
```
```sh [pnpm]
$ pnpm tsx ./file.ts
```
```sh [yarn]
$ yarn tsx ./file.ts
```
:::
#### Using it in `package.json#scripts`
Project commands are usually organized in the [`package.json#scripts`](https://docs.npmjs.com/cli/v10/using-npm/scripts) object.
In the `scripts` object, you can reference `tsx` directly without `npx`:
```js
// package.json
{
"scripts": {
"start": "tsx ./file.ts"// [!code highlight]
}
}
```
## Global installation
If you want to use `tsx` anywhere on your computer (without [`npx`](https://docs.npmjs.com/cli/commands/npx/)), install it globally:
::: code-group
```sh [npm]
$ npm install -g tsx
```
```sh [pnpm]
$ pnpm add -g tsx
```
```sh [yarn]
Yarn 2 doesn't support global installation
https://yarnpkg.com/migration/guide#use-yarn-dlx-instead-of-yarn-global
```
:::
This allows you to call `tsx` directly:
```sh
tsx file.ts
```
---
# Source: https://tsx.is/
---
outline: false
---
# TypeScript Execute (_tsx_)
_tsx_ stands for _TypeScript Execute_ and it's a Node.js enhancement to run [TypeScript](https://www.typescriptlang.org).
For starters, think of `tsx` as an alias to `node` and use it the same way:
```sh
node file.js
```
→
↓
```sh
tsx file.ts
```
You can pass in Node CLI flags and JS files too:
```sh
tsx --env-file=.env ./file.js
```
## Features
### Seamless TypeScript execution
Run TypeScript code without worrying about configuration!
_tsx_ runs your TypeScript code with modern and sensible defaults, making it user-friendly and especially great for beginners.
### Seamless CJS ↔ ESM imports
No need to wonder whether a package is CommonJS or ESM again.
If you've encountered the `ERR_REQUIRE_ESM` error in Node, you'll never see it again!
### Watch mode
As a DX bonus, _tsx_ comes with [Watch mode](/watch-mode.md) to re-run your files whenever you save them.
Iterate on your code faster and boost productivity!
---
Who uses _tsx_?
## About the project
The idea for _tsx_ came about during a time when the Node.js ecosystem was getting fragmented due to the release of [ES Modules (ESM)](https://nodejs.org/api/esm.html). As packages migrated to ESM, projects struggled to reconcile their CommonJS apps with ESM dependencies.
Back then, _ts-node_ was the go-to tool for running TypeScript in Node.js, but it lacked ESM support and was quite complicated to use. We noticed several open-source tools using esbuild to run TypeScript in Node.js and decided to bring these efforts together into one simple, cohesive project.
**_tsx_ is designed to simplify your TypeScript experience.** It enhances Node.js with TypeScript support in both CommonJS and ESM modes, allowing you to switch between them seamlessly. It also supports `tsconfig.json` paths and includes a Watch mode to make development even easier.
Right now, the _tsx_ project development relies on user donations, which isn't sustainable in the long run. To keep _tsx_ reliable and growing, we need funding to cover maintenance and development costs.
If your company uses _tsx_ and would like to support the project, consider [sponsoring us](https://github.com/sponsors/privatenumber/sponsorships?pay_prorated=false&tier_id=388346)—in return we'll put up your logo + link!
## Sponsors
---
# Source: https://tsx.is/
# Learning resources
TypeScript can be difficult to get started with and _tsx_ is all about lowering that barrier of entry.
Here are some great resources for your reference.
::: info
This page is currently a work in progress.
If you're a TypeScript educator or you know any TS courses that use tsx, [let us know](/contact)!
:::
## Documentation
- [TypeScript documentation](https://www.typescriptlang.org/docs/)
- [Node.js documentation](https://nodejs.org/docs/latest/api/)
---
# Source: https://tsx.is/
# Node.js enhancement
## Swap `node` for `tsx`
`tsx` is a drop-in replacement for `node`, meaning you can use it the exact same way (supports all [command-line flags](https://nodejs.org/api/cli.html)).
If you have an existing `node` command, simply substitute it with `tsx`.
```sh
node --no-warnings --env-file=.env ./file.js
```
↓
```sh
tsx --no-warnings --env-file=.env ./file.js
```
::: warning Node.js version matters
Under the hood, `tsx` calls `node`. This means the Node.js features supported in `tsx` depend on the Node.js version you have installed.
:::
## Flag & arguments positioning
Just like with `node`, correctly positioning flags and arguments is important when using `tsx`.
Place _tsx_ flags immediately after `tsx`, and place flags and arguments for your script after the script path.
```sh
tsx [tsx flags] ./file.ts [flags & arguments for file.ts]
```
## TypeScript REPL
_tsx_ extends the Node.js REPL to support TypeScript, allowing interactive coding sessions directly in TypeScript.
```sh
tsx
```
::: info What is the Node.js REPL?
The [Node.js REPL](https://nodejs.org/en/learn/command-line/how-to-use-the-nodejs-repl) is an interactive prompt that immediately executes input code, ideal for learning and experimenting. _tsx_ enhances this tool by adding TypeScript support.
:::
## Test runner
_tsx_ enhances the Node.js built-in [test runner](https://nodejs.org/api/test.html) with TypeScript support. You can use it the same way:
```sh
tsx --test
```
It will automatically recognize test files with TypeScript extensions:
- `**/*.test.?[cm][jt]s`
- `**/*-test.?[cm][jt]s`
- `**/*_test.?[cm][jt]s`
- `**/test-*.?[cm][jt]s`
- `**/test.?[cm][jt]s`
- `**/test/**/*.?[cm][jt]s`
---
# Source: https://tsx.is/
# Shell scripts
You can write a shell script in TypeScript by specifying _tsx_ in the [hashbang](https://bash.cyberciti.biz/guide/Shebang). The hashbang tells the shell how to run the script, making it executable.
### Project scripts
If `tsx` is installed in your project, use your package manager to reference _tsx_:
::: code-group
```ts [npm]
#!/usr/bin/env -S npx tsx
console.log('argv:', process.argv.slice(2))
```
```ts [pnpm]
#!/usr/bin/env -S pnpm tsx
console.log('argv:', process.argv.slice(2))
```
```ts [yarn]
#!/usr/bin/env -S yarn tsx
console.log('argv:', process.argv.slice(2))
```
:::
Make the file executable:
```sh
chmod +x ./file.ts
```
Now, you can run `./file.ts` directly:
```sh
./file.ts hello world
# Output: argv: [ 'hello', 'world' ]
```
### Global scripts
If `tsx` is installed globally, you can reference `tsx` directly in the hashbang:
_file.ts_:
```ts
#!/usr/bin/env tsx
console.log('argv:', process.argv.slice(2))
```
Don't forget to `chmod` the file to make it executable!
---
# Source: https://tsx.is/
# TypeScript
_tsx_ does not type check your code on its own and expects it to be handled separately. While _tsx_ doesn’t require TypeScript to be installed, and the type checks provided by your IDE might suffice for quick scripts, it is highly recommended to include a type checking step in your projects.
## Development workflow
Type checking is important but it can be time-consuming and expensive to do on every run.
`tsx` alleviates this problem by allowing you to execute TypeScript code directly without being blocked by type errors. Modern IDEs like VSCode provide real-time type checking via [IntelliSense](https://code.visualstudio.com/docs/languages/typescript), reducing the need for manual type checks. This workflow lets you iterate faster on functionality and treat type errors as linting errors rather than compilation requirements.
To incorporate type checking, include it with other linters (e.g. ESLint) in pre-commit hooks or CI checks.
## Installation
Start by installing the following in your project:
- [`typescript`](https://npmjs.com/package/typescript) to type-check with the `tsc` CLI command
- [`@types/node`](https://npmjs.com/package/@types/node) to provide TypeScript with Node.js API types
::: code-group
```sh [npm]
$ npm install -D typescript @types/node
```
```sh [pnpm]
$ pnpm add -D typescript @types/node
```
```sh [yarn]
$ yarn add -D typescript @types/node
```
:::
## tsconfig.json
[`tsconfig.json`](https://www.typescriptlang.org/tsconfig/) is the configuration file used by TypeScript.
### Recommendation
Here's the recommended configuration to make type-checking behave consistently.
```jsonc
{
"compilerOptions": {
// Treat files as modules even if it doesn't use import/export
"moduleDetection": "force",
// Ignore module structure
"module": "Preserve",
// Allow JSON modules to be imported
"resolveJsonModule": true,
// Allow JS files to be imported from TS and vice versa
"allowJs": true,
// Use correct ESM import behavior
"esModuleInterop": true,
// Disallow features that require cross-file awareness
"isolatedModules": true,
},
}
```
::: tip
It's also recommended to enable [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax) which requires you to write your type imports & exports using explicit syntax. Refactoring may be necessary.
[Read more](https://www.typescriptlang.org/docs/handbook/modules/reference.html#type-only-imports-and-exports)
:::
### JSX
_tsx_ respects the following configurations for JSX in `.jsx` and `.tsx` files:
- [`jsx`](https://www.typescriptlang.org/tsconfig/#jsx)
- [`jsxFactory`](https://www.typescriptlang.org/tsconfig/#jsxFactory)
- [`jsxFragmentFactory`](https://www.typescriptlang.org/tsconfig/#jsxFragmentFactory)
- [`jsxImportSource`](https://www.typescriptlang.org/tsconfig/#jsxImportSource)
## Custom `tsconfig.json` path
By default, `tsconfig.json` is detected from the current working directory.
To pass in a `tsconfig.json` file from a custom path, use the `--tsconfig` flag:
```sh
tsx --tsconfig ./path/to/tsconfig.custom.json ./file.ts
```
## Type checking
Use TypeScript to type check:
```sh
tsc --noEmit
```
(You can omit `--noEmit` if it's already specified in your `tsconfig.json`)
### `package.json` script
Since `tsc` is also a compiler, you can add a script to your `package.json` to specify that it's used for type checking only:
```js
// package.json
{
// ...
"scripts": {
"type-check": "tsc --noEmit"// [!code ++]
},
// ...
}
```
### Pre-commit hook
To type check on pre-commit, use [simple-git-hooks](https://www.npmjs.com/package/simple-git-hooks):
```js
// package.json
{
// ...
"scripts": {
// Register Git hooks on `npm install`
"prepare": "simple-git-hooks"// [!code ++]
},
"simple-git-hooks": {
"pre-commit": "npm run type-check",// [!code ++]
// Or if you have multiple commands
"pre-commit": [
"npm run lint",
"npm run type-check"// [!code ++]
]
}
}
```
## Compiler limitations
_tsx_ uses [esbuild](https://esbuild.github.io) to compile TypeScript and ESM, so it shares some of the same limitations:
- Compatibility with `eval()` is not preserved
- Only [certain `tsconfig.json` properties](https://esbuild.github.io/content-types/#tsconfig-json) are supported
- [`emitDecoratorMetadata`](https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata) is not supported
For detailed information, refer to esbuild's [JavaScript caveats](https://esbuild.github.io/content-types/#javascript-caveats) and [TypeScript caveats](https://esbuild.github.io/content-types/#typescript-caveats) documentation.
---
# Source: https://tsx.is/
# VS Code debugging
If you use [VS Code](https://code.visualstudio.com), you can configure it to use _tsx_ to enhance your debugging experience.
To learn more about VS Code configuration, refer to the [_Launch Configuration_](https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_launch-configuration) documentation.
## Setup
1. Create the config file
Create a launch configuration file in your project at `.vscode/launch.json`:
```json5
{
"version": "0.2.0",
"configurations": [
/*
* Each config in this array corresponds to an option
* in the debug drop-down
*/
],
}
```
2. Pick and choose debugging methods
::: details Method 1: Run _tsx_ from inside VSCode
1. Add the following configuration to the `configurations` array in `.vscode/launch.json`:
```json5
{
"name": "tsx",
"type": "node",
"request": "launch",
// Debug current file in VSCode
"program": "${file}",
/*
* Path to tsx binary
* Assuming locally installed
*/
"runtimeExecutable": "tsx",
/*
* Open terminal when debugging starts (Optional)
* Useful to see console.logs
*/
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
// Files to exclude from debugger (e.g. call stack)
"skipFiles": [
// Node.js internal core modules
"/**",
// Ignore all dependencies (optional)
"${workspaceFolder}/node_modules/**",
],
}
```
2. In VSCode, open the JS/TS file you want to run
3. Go to VSCode's debug panel, select "tsx" in the drop down, and hit the play button (F5).
:::
::: details Method 2: Attach the VS Code debugger to a running Node.js process
> This method works for any Node.js process like _tsx_, and is not specific to _tsx_.
1. Add the following configuration to the `configurations` array in `.vscode/launch.json`:
```json
{
"name": "Attach to process",
"type": "node",
"request": "attach",
"port": 9229,
"skipFiles": [
// Node.js internal core modules
"/**",
// Ignore all dependencies (optional)
"${workspaceFolder}/node_modules/**",
],
}
```
2. Run _tsx_ with [`--inspect-brk`](https://nodejs.org/api/cli.html#--inspect-brkhostport) in a terminal window:
```sh
tsx --inspect-brk ./your-file.ts
```
3. Go to VSCode's debug panel, select "Attach to process" in the drop down, and hit the play button (F5).
:::
---
# Source: https://tsx.is/
# Watch mode
::: warning Not to be confused with [Node's Watch mode](https://nodejs.org/docs/latest/api/cli.html#--watch)
_tsx_ introduced _Watch mode_ before Node.js released the `--watch` flag in [v18.11.0](https://github.com/nodejs/node/releases/tag/v18.11.0). Although it is similar in functionality, it does not yet match the robustness of _tsx_'s Watch mode.
:::
## Overview
Watch mode will automatically re-run your script whenever any of its dependencies are changed.
```sh
tsx watch ./file.ts
```
## Watch behavior
By default, _tsx_ watches all imported files, except those in the following directories:
- `node_modules`
- `bower_components`
- `vendor`
- `dist`
- Hidden directories (`.*`)
## Customizing watched files
### Including files to watch
To include specific files or directories to watch, use the `--include` flag:
```sh
tsx watch --include ./other-dep.txt --include "./other-deps/*" ./file.ts
```
### Excluding files from watch
To exclude specific files from being watched, use the `--exclude` flag:
```sh
tsx watch --exclude ./ignore-me.js --exclude ./ignore-me-too.js ./file.ts
```
### Using glob patterns
Glob patterns allow you to define a set of files or directories to ignore. To prevent your shell from expanding the glob patterns, wrap them in quotes:
```sh
tsx watch --exclude "./data/**/*" ./file.ts
```
## Tips
- Press Return to manually rerun the script.
- Use `--clear-screen=false` to prevent the screen from clearing on rerun.