1--- 2title: Use TypeScript 3description: An in-depth guide on configuring an Expo project with TypeScript. 4--- 5 6import { Terminal } from '~/ui/components/Snippet'; 7import { BoxLink } from '~/ui/components/BoxLink'; 8import { GithubIcon } from '@expo/styleguide-icons'; 9import { Tabs, Tab, TabsGroup } from '~/ui/components/Tabs'; 10 11Expo has first-class support for [TypeScript](https://www.typescriptlang.org/). The JavaScript interface of the Expo SDK is completely written in TypeScript. 12 13<BoxLink 14 title="with-typescript" 15 description="See the example project on GitHub." 16 href="https://github.com/expo/examples/tree/master/with-typescript" 17 Icon={GithubIcon} 18/> 19 20<TabsGroup> 21 22## Get started 23 24### Quick start with a template 25 26The easiest way to get started is to initialize your new project using a TypeScript template: 27 28<Terminal cmd={['$ npx create-expo-app -t expo-template-blank-typescript']} /> 29 30For npm, add the following `script` to the **package.json**: 31 32{/* prettier-ignore */} 33```json package.json 34{ 35 "scripts": { 36 "ts:check": "tsc" 37 /* @hide ... */ /* @end */ 38 } 39} 40``` 41 42Then, to type-check the project, run the following command: 43 44<Tabs> 45<Tab label="npm"> 46 47<Terminal cmd={['$ npm run ts:check']} /> 48 49</Tab> 50 51<Tab label="yarn"> 52 53<Terminal cmd={['$ yarn tsc']} /> 54 55</Tab> 56</Tabs> 57 58When you create new source files in your project you should use the **.ts** extension or the **.tsx** if the file includes React components. 59 60### In an existing project 61 62Rename 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. 63 64<Terminal cmd={['$ mv App.js App.tsx']} /> 65 66> **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. 67 68For npm, add the following `script` to the **package.json**: 69 70{/* prettier-ignore */} 71```json package.json 72{ 73 "scripts": { 74 "ts:check": "tsc" 75 /* @hide ... */ /* @end */ 76 } 77} 78``` 79 80You can now run `npm run ts:check` or `yarn tsc` to type-check the project. 81 82## Base configuration 83 84> You can disable the TypeScript setup in Expo CLI with the environment variable `EXPO_NO_TYPESCRIPT_SETUP=1` 85 86A 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**): 87 88You can automatically generate a **tsconfig.json** file by running the command: 89 90<Terminal cmd={['$ npx expo customize tsconfig.json']} /> 91 92## Project configuration 93 94Expo CLI will automatically modify your **tsconfig.json** to the preferred default which is optimized for universal React development: 95 96```json tsconfig.json 97{ 98 "extends": "expo/tsconfig.base", 99 "compilerOptions": {}, 100 "include": ["**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts"] 101} 102``` 103 104The 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. 105 106Some 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. 107 108## Path aliases 109 110Expo 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. 111 112For example, if you have a file at **src/components/Button.tsx** and wish to import it using the alias **@/components/Button** as follows: 113 114```tsx 115import Button from '@/components/Button'; 116``` 117 118Then simply add the alias **@/\*** in the project's **tsconfig.json** and set it to the **src** directory: 119 120```json tsconfig.json 121{ 122 "compilerOptions": { 123 "baseUrl": ".", 124 "paths": { 125 "@/*": ["src/*"] 126 } 127 } 128} 129``` 130 131Consider the following when using path aliases: 132 133- Restart Expo CLI after changing **tsconfig.json** to update path aliases. You don't need to clear the Metro cache when the aliases change. 134- If not using TypeScript, **jsconfig.json** can serve as an alternative to **tsconfig.json**. 135- Path aliases add additional resolution time when defined. 136- Path aliases are only supported by Metro (including Metro web) and not by `@expo/webpack-config`. 137- Bare projects require additional setup for this feature. See the [versioned Metro setup guide](/versions/latest/config/metro#bare-workflow-setup) for more information. 138 139<Tabs> 140 141<Tab label="SDK 50 and above"> 142 143`tsconfigPaths` is enabled by default. You can disable it by setting `tsconfigPaths` to `false` in the project's [app config](/workflow/configuration/): 144 145```json app.json 146{ 147 "expo": { 148 "experiments": { 149 "tsconfigPaths": false 150 } 151 } 152} 153``` 154 155</Tab> 156 157<Tab label="SDK 49"> 158 159Set `tsconfigPaths` to `true` to enable path aliases in the project's [app config](/workflow/configuration/): 160 161```json app.json 162{ 163 "expo": { 164 "experiments": { 165 "tsconfigPaths": true 166 } 167 } 168} 169``` 170 171</Tab> 172 173</Tabs> 174 175## Absolute imports 176 177> Available in SDK 49 and higher. 178 179In SDK 49 projects, you'll need to enable absolute imports in the project's [app config](/workflow/configuration/): 180 181```json app.json 182{ 183 "expo": { 184 "experiments": { 185 "tsconfigPaths": true 186 } 187 } 188} 189``` 190 191Absolute imports from the project root directory are enabled automatically when the project contains a **tsconfig.json** or **jsconfig.json** file. For example: 192 193```tsx 194import Button from 'src/components/Button'; 195// Imports `<project root>/src/components/Button` 196``` 197 198You 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: 199 200```json tsconfig.json 201{ 202 "compilerOptions": { 203 "baseUrl": "src" 204 } 205} 206``` 207 208Consider the following when using absolute imports: 209 210- [`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. 211- Absolute imports in Node modules cannot be overwritten by absolute imports, as they take precedence. 212- 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**. 213- If not using TypeScript, **jsconfig.json** can serve as an alternative to **tsconfig.json**. 214- Absolute imports are only supported by Metro (including Metro web) and not by `@expo/webpack-config`. 215- Bare projects require additional setup for this feature. See the [versioned Metro setup guide](/versions/latest/config/metro#bare-workflow-setup) for more information. 216 217## Type generation 218 219Some Expo libraries provide both static types and type generation capabilities. These types are automatically generated when the project builds or by running the `npx expo customize tsconfig.json` command. 220 221## TypeScript for config files 222 223If 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. 224 225<Tabs> 226<Tab label="npm"> 227 228<Terminal cmd={['$ npm install ts-node typescript --save-dev']} /> 229 230</Tab> 231 232<Tab label="yarn"> 233 234<Terminal cmd={['$ yarn add -D ts-node typescript']} /> 235 236</Tab> 237</Tabs> 238 239### webpack.config.js 240 241> Install the `@expo/webpack-config` package. 242 243```js webpack.config.js 244require('ts-node/register'); 245module.exports = require('./webpack.config.ts'); 246``` 247 248```ts webpack.config.ts 249import createExpoWebpackConfigAsync from '@expo/webpack-config/webpack'; 250import { Arguments, Environment } from '@expo/webpack-config/webpack/types'; 251 252module.exports = async function (env: Environment, argv: Arguments) { 253 const config = await createExpoWebpackConfigAsync(env, argv); 254 // Customize the config before returning it. 255 return config; 256}; 257``` 258 259### metro.config.js 260 261```js metro.config.js 262require('ts-node/register'); 263module.exports = require('./metro.config.ts'); 264``` 265 266```ts metro.config.ts 267import { getDefaultConfig } from 'expo/metro-config'; 268 269const config = getDefaultConfig(__dirname); 270 271module.exports = config; 272``` 273 274### app.config.js 275 276**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: 277 278```js app.config.js 279require('ts-node/register'); 280module.exports = require('./app.config.ts'); 281``` 282 283```ts app.config.ts 284import { ExpoConfig } from 'expo/config'; 285 286// In SDK 46 and lower, use the following import instead: 287// import { ExpoConfig } from '@expo/config-types'; 288 289const config: ExpoConfig = { 290 name: 'my-app', 291 slug: 'my-app', 292}; 293 294export default config; 295``` 296 297## Learn how to use TypeScript 298 299A good place to start learning TypeScript is the official [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html). 300 301**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. 302 303</TabsGroup> 304