---
title: Use TypeScript
description: An in-depth guide on configuring an Expo project with TypeScript.
---
import { Terminal } from '~/ui/components/Snippet';
import { BoxLink } from '~/ui/components/BoxLink';
import { GithubIcon } from '@expo/styleguide-icons';
import { Tabs, Tab, TabsGroup } from '~/ui/components/Tabs';
Expo has first-class support for [TypeScript](https://www.typescriptlang.org/). The JavaScript interface of the Expo SDK is completely written in TypeScript.
## Get started
### Quick start with a template
The easiest way to get started is to initialize your new project using a TypeScript template:
For npm, add the following `script` to the **package.json**:
{/* prettier-ignore */}
```json package.json
{
"scripts": {
"tsc": "tsc"
/* @hide ... */ /* @end */
}
}
```
Then, to type-check the project, run the following command:
When you create new source files in your project you should use the **.ts** extension or the **.tsx** if the file includes React components.
### In an existing project
Rename files to convert them to TypeScript. For example, rename **App.js** to **App.tsx**. Use the **.tsx** extension if the file includes React components (JSX). If the file does not include any JSX, you can use the **.ts** file extension.
> **For SDK 48 and higher**, running `npx expo start` prompts you to install the required dependencies, such as `typescript` and `@types/react`. **For SDK 47 and below**, the command also prompts you to install `@types/react-native` as an additional dependency.
For npm, add the following `script` to the **package.json**:
{/* prettier-ignore */}
```json package.json
{
"scripts": {
"tsc": "tsc"
/* @hide ... */ /* @end */
}
}
```
You can now run `npm run tsc` or `yarn tsc` to type-check the project.
## Base configuration
> You can disable the TypeScript setup in Expo CLI with the environment variable `EXPO_NO_TYPESCRIPT_SETUP=1`
A project's **tsconfig.json** should extend the `expo/tsconfig.base` by default. This sets the following default [compiler options](https://www.typescriptlang.org/docs/handbook/compiler-options.html) (which can be overwritten in your project's **tsconfig.json**):
## Project configuration
Expo CLI will automatically modify your **tsconfig.json** to the preferred default which is optimized for universal React development:
```json tsconfig.json
{
"extends": "expo/tsconfig.base",
"compilerOptions": {}
}
```
The default configuration for TypeScript is user-friendly and encourages adoption. However, if you prefer strict type checking, you can enable it by adding `"strict": true` to the `compilerOptions`. We recommend enabling this to minimize the chance of introducing runtime errors.
Some language features may require additional configuration. For example, if want to use decorators you'll need to add the `experimentalDecorators` option. For more information on the available properties see the [TypeScript compiler options](https://www.typescriptlang.org/docs/handbook/compiler-options.html) documentation.
## Path aliases
> Available in SDK 49 and higher.
In SDK 49 projects, you'll need to enable path aliases in the project's [app config](/workflow/configuration/):
```json app.json
{
"expo": {
"experiments": {
"tsconfigPaths": true
}
}
}
```
Expo CLI supports [path aliases](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping) in your project's **tsconfig.json** automatically. This enables you to import modules using a custom alias instead of a relative path.
For example, if you have a file at **src/components/Button.tsx** and wish to import it using the alias **@/components/Button** as follows:
```tsx
import Button from '@/components/Button';
```
Then simply add the alias **@/\*** in the project's **tsconfig.json** and set it to the **src** directory:
```json tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
}
}
```
Consider the following when using path aliases:
- Restart Expo CLI after changing **tsconfig.json** to update path aliases. You don't need to clear the Metro cache when the aliases change.
- If not using TypeScript, **jsconfig.json** can serve as an alternative to **tsconfig.json**.
- Path aliases add additional resolution time when defined.
- Path aliases are only supported by Metro (including Metro web) and not by `@expo/webpack-config`.
- Bare projects require additional setup for this feature. See the [versioned Metro setup guide](/versions/latest/config/metro#bare-workflow-setup) for more information.
## Absolute imports
> Available in SDK 49 and higher.
In SDK 49 projects, you'll need to enable absolute imports in the project's [app config](/workflow/configuration/):
```json app.json
{
"expo": {
"experiments": {
"tsconfigPaths": true
}
}
}
```
Absolute imports from the project root directory are enabled automatically when the project contains a **tsconfig.json** or **jsconfig.json** file. For example:
```tsx
import Button from 'src/components/Button';
// Imports `/src/components/Button`
```
You can modify the base directory in the tsconfig.json (or jsconfig.json) using the [baseUrl](https://www.typescriptlang.org/docs/handbook/module-resolution.html#base-url) option:
```json tsconfig.json
{
"compilerOptions": {
"baseUrl": "src"
}
}
```
Consider the following when using absolute imports:
- [`compilerOptions.baseUrl`](https://www.typescriptlang.org/docs/handbook/module-resolution.html#base-url) is automatically set to `.` when the `tsconfig.json` or **jsconfig.json** file exists.
- Absolute imports in Node modules cannot be overwritten by absolute imports, as they take precedence.
- Restarting Expo CLI is necessary to update [`compilerOptions.baseUrl`](https://www.typescriptlang.org/docs/handbook/module-resolution.html#base-url) after modifying **the tsconfig.json**.
- If not using TypeScript, **jsconfig.json** can serve as an alternative to **tsconfig.json**.
- Absolute imports are only supported by Metro (including Metro web) and not by `@expo/webpack-config`.
- Bare projects require additional setup for this feature. See the [versioned Metro setup guide](/versions/latest/config/metro#bare-workflow-setup) for more information.
## TypeScript for config files
If you want to use TypeScript for configuration files such as **webpack.config.js**, **metro.config.js**, or **app.config.js**, additional setup is needed. You can utilize the [`ts-node` require hook](https://github.com/TypeStrong/ts-node#programmatic) to import TypeScript files within your JS config file, allowing TypeScript imports while keeping the root file as JavaScript.
### webpack.config.js
> Install the `@expo/webpack-config` package.
```js webpack.config.js
require('ts-node/register');
module.exports = require('./webpack.config.ts');
```
```ts webpack.config.ts
import createExpoWebpackConfigAsync from '@expo/webpack-config/webpack';
import { Arguments, Environment } from '@expo/webpack-config/webpack/types';
module.exports = async function (env: Environment, argv: Arguments) {
const config = await createExpoWebpackConfigAsync(env, argv);
// Customize the config before returning it.
return config;
};
```
### metro.config.js
```js metro.config.js
require('ts-node/register');
module.exports = require('./metro.config.ts');
```
```ts metro.config.ts
import { getDefaultConfig } from 'expo/metro-config';
const config = getDefaultConfig(__dirname);
module.exports = config;
```
### app.config.js
**app.config.ts** is supported by default. However, it doesn't support external TypeScript modules, or **tsconfig.json** customization. You can use the following approach to get a more comprehensive TypeScript setup:
```js app.config.js
require('ts-node/register');
module.exports = require('./app.config.ts');
```
```ts app.config.ts
import { ExpoConfig } from 'expo/config';
// In SDK 46 and lower, use the following import instead:
// import { ExpoConfig } from '@expo/config-types';
const config: ExpoConfig = {
name: 'my-app',
slug: 'my-app',
};
export default config;
```
## Learn how to use TypeScript
A good place to start learning TypeScript is the official [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html).
**For TypeScript and React components,** we recommend referring to the [React TypeScript CheatSheet](https://github.com/typescript-cheatsheets/react) to learn how to type your React components in a variety of common situations.