Using @/ path mapping on Create React App projects
Tags: react, path, mapping, alias
Published: 2023-07-05 21:55:13

---
title: Using @/ path mapping on Create React App projects
published: true
description: A tutorial on how to use path aliases on React projects created with Create React App (CRA)
tags: react, path, mapping, alias
# cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3lswnwnbqsstilgqt0g.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-07-05 20:57 +0000
---

![Path Mapping in a Map](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ma4s7iku4d3vhv8iqaw.jpg)

I recently configured an old project created with Create React App (CRA) to use path mapping/aliasing like `@atoms`, `@molecules` or `@organisms`.

After using NextJS for a while, I got used to the idea of using `@/` instead of just `@` as a prefix for path mapping as it makes it a little bit clearer what is a path alias and what's not, like `@apollo-client` or `@fortawesome`. 

The point in this post is how to enable your project to use `@/` path mapping, but you can use the same settings to be able to use any other aliases, like `@utils` or just `utils`.

## Configuring the path mapping

Considering you're using CRA, the first thing is to install `@craco/craco` in your project to enable overriding original CRA's configuration.

To install `@craco/craco`, just run:

```sh
yarn add -D @craco/craco
```

or

```sh
npm i -D @craco/craco
```

After installing `@craco/craco`, in your `package.json`, update your `start`, `build` and `test` scripts to use `craco` instead of `react-scripts`, like recommended in [CRACO's docs](https://www.npmjs.com/package/@craco/craco).

And then create a `craco.config.js` file in your project's root adding your aliases to the `alias` property of the `webpack` property, where the key should be the alias's name and the value its path:

```js
const path = require('path');

module.exports = {
  webpack: {
    alias: {
      '@atoms': path.resolve(__dirname, './src/atoms'),
      '@molecules': path.resolve(__dirname, './src/molecules'),
    },
  },
};
```

If you're using TypeScript, you should add those same path aliases to your `tsconfig` file. In your `tsconfig` file, look for `compilerOptions` and add a `paths` object like the following:

```json
{
  "compilerOptions": {
    "paths": {
      "@atoms/*": [
        "./src/atoms/*"
      ],
      "@molecules/*": [
        "./src/molecules/*"
      ],
    }
  }
}
```

At this point, you should be able to import your components using the aliases you just defined:

```ts
import Button from '@atoms/Button'; 
import Table from '@molecules/Table'
``` 

Remember `@atoms` and `@molecules` are just examples. You can use any other aliases.

## Allowing @/ path aliases

If you prefer to use `@/` instead of `@` as the alias prefix, you might face some trouble with ESLint as it might be complaining about missing file extensions on your imports:

```sh
Missing file extension for "@/pages/MainPage" eslint(import/extensions)
```

To allow ESLint to understand `@/` aliases, you'll have to install the `eslint-import-resolver-typescript` plugin.

Run

```sh
yarn add -D eslint-import-resolver-typescript
```

or

```sh
npm i -D eslint-import-resolver-typescript
```

Then, go to your `.eslintrc` file and add the following configuration within the `settings` section:

```json
  "settings": {
    "import/resolver": {
      "typescript": {}
    }
  }
```

Now ESLint should've stopped complaining about missing file extensions. If you're still getting a warning about extensions, check your `import/extensions` rule inside the `rules` section. You can read more about this rule [here](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/extensions.md).

## 🎁 Bonus round: enabling Jest to use path aliases

Again, considering you're using TypeScript, to allow Jest to read your path aliases you'll have to install and configure `ts-jest`.

Run

```sh
yarn add -D ts-jest
```

or

```sh
npm i -D ts-jest
```

After installing `ts-jest`, update your `craco.config.js` file like the following, telling Jest to use the paths configured in your `tsconfig` file:

```js
const path = require('path');
const { pathsToModuleNameMapper } = require('ts-jest');
const { compilerOptions } = require('./tsconfig.json');

module.exports = {
  webpack: {
    alias: {
      '@atoms': path.resolve(__dirname, './src/atoms'),
      '@molecules': path.resolve(__dirname, './src/molecules'),
    },
  },
  jest: {
    configure: {
      preset: 'ts-jest',
      moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
        prefix: '<rootDir>/',
      }),
    },
  },
};
```

That's it! You now should be able to use path mapping in your project, including your unit tests and also using `@/` path aliases.