How to configure import alias in React Native
Import aliases are better for maintenance and more readable. Learn how to set up them in React Native!
Look at those two examples:
1. import { InputArea } from '~components/InputArea'
2. import { InputArea } from '../../../../../components/InputArea'
We will learn how to set up our environment to have the first variant working.
Using Expo? You can skip the Babel plugin
If your project uses Expo — now the default way most people start a React Native project — none of the Babel setup below is necessary. Since SDK 50, Expo’s Metro config resolves tsconfig.json/jsconfig.json paths out of the box: the experiments.tsconfigPaths option is enabled by default, and it works for both TypeScript and JavaScript projects. Just declare your aliases:
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~*": ["src/*"]
}
}
}
No metro.config.js changes required — restart the Expo CLI after editing the config and it works, with VS Code autocomplete included. One caveat: that’s true for a project created with create-expo-app. An existing bare React Native project that later adopted Expo modules needs some additional Metro setup first — Expo’s docs cover that case separately. See Expo’s path aliases docs for details. If you’re on a bare React Native project instead, read on.
Aliases for src folder
For this tutorial, I assume that we have a standard React Native file structure. We want to create aliases to directories inside the src folder.
├── App.js
├── __tests__
├── android
├── app.json
├── babel.config.js
├── index.js
├── ios
├── metro.config.js
├── node_modules
├── package.json
├── src
│ ├── components
│ └── helpers
└── yarn.lock
Why is the tilde prefix ~ important?
The custom prefix is helpful when it comes to distinguishing your local imports from third-party packages. One look and you know which imports are from the project.
Here are two examples with the helpers folder:
1. import something from 'helpers' // - without prefix
2. import something from '~helpers' // - with prefix
There is a package in the npm registry that is called helpers. If you decide to alias your helpers folder without any prefix then you risk a naming conflict.
I decided to stick with ~ as I haven’t seen third party packages that use it. There are other popular prefixes as well — my recommendation is sticking with tilde
Install Babel plugin
First of all, we have to add a proper plugin for the Babel compiler.
▶ yarn add --dev babel-plugin-module-resolver
Adjust Babel config
Inside babel.config.js add plugins section. If it already exists, simply add module-resolver config like below. If you don’t have this file. Then check for .babelrc or create one. All possible config files are listed in the docs.
module.exports = {
// ... some other config
plugins: [
// ... some other plugins
[
'module-resolver',
{
root: ['./'],
alias: {
/**
* Regular expression is used to match all files inside `./src` directory and map each `.src/folder/[..]` to `~folder/[..]` path
*/
'^~(.+)': './src/\\1',
},
extensions: ['.ios.js', '.android.js', '.js', '.jsx', '.json', '.tsx', '.ts', '.native.js'],
},
],
],
}
Options are as described:
- root - a string or an array of root directories,
- alias - a map of aliases,
- extensions - an array of file extensions used in the resolver.
Regular expression as an alias
To prevent adding each src subfolder separately we want to use a regular expression for path completion. You can see the docs about using regular expressions on babel-plugin-module-resolver Github page.
Restart metro process
The last step to make it work is restarting the metro server. Simply use ctrl + c and then yarn start again in the terminal in your project.
If something is not working maybe you have to clear the cache - for that use yarn start --reset-cache command.
A note on resolver.alias
If you came here searching for a resolver.alias option in metro.config.js, like you’d find in Webpack or Vite — Metro doesn’t have one, it isn’t a real config key. What Metro does offer is resolver.extraNodeModules (map a module name to a directory) and resolver.resolveRequest (fully custom resolution logic, which people also reach for to build alias-like behaviour). See the Metro resolver docs for details — for this tutorial’s use case, babel-plugin-module-resolver remains the simpler option.
How to make VSCode alias autocomplete working?
With the config above code will compile and work as expected. Now we would like to have autocomplete work with our newly created aliases (or IntelliSense as named by Visual Studio Code creators).
We have to enter jsconfig.json file (or create it if it’s not working).
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~*": ["src/*"]
}
},
"exclude": ["node_modules"]
}
Inside jsconfig.json we have to specify two options: baseUrl and paths object. Here again, we are using a kind of regular expression to match all subdirectories in a single line.
TypeScript support
What is interesting - in the TypeScript project I had to make a config a bit different to make it work:
{
"compilerOptions": {
"baseUrl": ".",
"paths": { "~*": ["./src/*"] }
},
"exclude": ["node_modules"]
}
Notice the dot before src path — turns out it wasn’t actually required. TypeScript resolves paths entries relative to baseUrl (here, .), so src/* and ./src/* point to the exact same place; the leading dot is just a stylistic choice. (Since TypeScript 4.1, baseUrl isn’t even required for paths to work - omit it and paths resolve relative to the tsconfig.json file instead.)
You can also check config in the official docs for TypeScript aliases.
Restart TypeScript process in VSCode
Autocomplete with new aliases should work immediately. If it is not maybe you have to restart TypeScript server (even for pure JS project as this server is responsible for autocompletion).
To do this open the command palette and type Restart TS server.