---
# System prepended metadata

title: Relative and absolute imports in NextJS

---

# Relative and absolute imports in NextJS

Working on a project requires accessing files. Most of these files are deeply nested, which makes them confusing and difficult to manage, highlighting the necessity for a developer in any discipline to be familiar with file access. 

In this article, we will be focusing on accessing files on a [`Nextjs`](https://nextjs.org/) project.

As we all know, Nextjs is a framework built with the `Nodejs` ([`Javascript`](https://www.javascript.com/)) programming language, meaning it follows the rules defined by [`Nodejs`](https://nodejs.org/). In `Nodejs`, for one to import a file into a module, it specifies the path to that particular file. It can be either `Absolute` e.g `c:/user/javascript/src/absolute_path` or `Relative` e.g `../src/absolute_path`. Let's explain the two methods.

`Absolute` and `Relative` imports in details

## Relative imports
In a relative import, the path should be relative to where the [module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) importing the file exists. In relative importation, the path usually starts with a dot and a backslash eg `./`

To understand the relative import better, let's consider a file structure in a `Nextjs` project

            ```
            project root

                ├── src
                │    ├── components
                |    |     |___ todoItem.js
                │    |     |___ todoDesc.js
                │    |     |___ todoHeader.js
                |    |     |
                |    |__ pages
                |    |    |__ todo.js
                |    |    |

            ```
In relative imports the dot can be either one `./` or two `../`, with each pointing to a different level. Using the file structure let's make it clear.

If we are importing the todo.js file into the todoItem.js file, because the todo.js file exits in another folder outside the current folder, we must change the pointer from the current folder to the current folder's parent in order to access it using the `../` method. In our case, if we use the `../` method the pointer will move to the src folder making it possible to access the pages folder and then the todo file. The code looks like this.

```javascript
    /*
    Before using the "../" method the pointer exists in the current folder which in our case is the component folder
    
    File structure
    |__ components
    |     |__ todoItem.js
    |     |__ todoDesc.js
    |     |__ todoHeader.js
    |     |  

    making it impossible for us to access the pages folder
    */

    import todo from "../pages/todo"

    /* After using the "../" method the pointer moves back to the parent folder of our current folder which in our case is the src folder

    The New File structure becomes
    ├── src
    │    ├── components
    |    |     |___ todoItem.js
    │    |     |___ todoDesc.js
    │    |     |___ todoHeader.js
    |    |     |
    |    |__ pages
    |    |    |__ todo.js
    |    |    |

    By using the path "../pages/todo we can access the file
    */

```

What if we want to import a file inside our current folder how do we access it? This is where the `./` comes into effect. the `./` method tells the pointer to look for the file inside the current folder. Using our file structure as an example, let's say we want to import the todoHeader.js into the todoItem.js.

```javascript
    /*
    Before using the "./" method the pointer exists in the current folder which in our case is the component folder
    
    File structure
    |__ components
    |     |__ todoItem.js
    |     |__ todoDesc.js
    |     |__ todoHeader.js
    |     |  
    */

    import todo from "./todoHeader"

    /* After using the "./" method the pointer still exists in our current folder which in our case is the component folder
    
    New file structure
    |__ components
    |     |__ todoItem.js
    |     |__ todoDesc.js
    |     |__ todoHeader.js
    |     |  

    By using the path "./todoHeader we can access the file
    */

```
### Drawback of relative imports

Not all relative imports are amicable. In actuality, they might be rather perplexing! The level of the directory we are now in has to be carefully monitored, as we can see from the example above.

Furthermore, relative imports might make development difficult, particularly in large projects. If our application expands, we can end up with a more complicated path.

Imagine a scenario where a deeply nested file called by another file is being moved to another folder, what happens is with I call a development disaster because you have to change the path of all files that imported the file which you might end up creating bugs for yourself and decreasing your production time.

## NextJS absolute imports
A simple method of importing modules is through an absolute import. This import type designates a path that begins at the root of the project.

As in the case of relative imports, there will be no need to keep track of directory levels we'll have a better method to access files.

We can also use an alias that looks like so:
'@components/todo.js';

To use absolute imports in a Next.js project we need to configure it.

### Creating a jsconfig.json file
We can set a project's base directory in the jsconfig.json file. Since 9.4, we may utilize this file to determine the root files and carry out the path mapping required for absolute imports using Next.js

To do this we create a jsconfig.json in the root of our project and add the following configuration:

```javascript
    {
        "compilerOptions": {
            "baseUrl": "."
        }
    }
```

Note that we would have added the code to tsconfig.json if we were using [TypeScript](https://www.typescriptlang.org/).

The baseUrl key lets us specify the base directory to locate modules. Making the value of the baseUrl ".", tells JavaScript or TypeScript to start searching for files in the root directory.

Note that we must restart the dev server if we make changes to the jsconfig.json or tsconfig.json files.

### Configuring the baseUrl
Using our previous structure and adding jsconfig.json, our structure should be:


```
project root

    ├── src
    │    ├── components
    |    |     |___ todoItem.js
    │    |     |___ todoDesc.js
    │    |     |___ todoHeader.js
    |    |     |
    |    |__ pages
    |    |    |__ todo.js
    |    |    |
    |    |    |
    |    |    |
    |__ jsconfig.json
    |
    |

```
Instead of assigning "." as the value of baseUrl, we can assign a directory as its value eg

```javascript
{
  "compilerOptions": {
    "baseUrl": "src"
  }
}

```
The src directory must be located relative to the project root as mentioned in the file. This will allow absolute imports from the src directory. eg

```javascript
// Importing todo.js into todoItem.js using relative import
import todo from "../pages/todo"

// After configuring our project we can import it using absolute import
import todo from "pages/todo"
```

### Configuring module aliases 
Absolute import is much simpler to utilize when custom module aliases are created to match different directories rather than only the basic directories for larger projects with several layers of deeply nested directories containing files.

Consider the following structure:


```
project root

    ├── src
    │    ├── components
    |    |     |___ todoItem.js
    │    |     |___ todoDesc.js
    │    |     |___ todoHeader.js
    |    |     |
    |    |__ pages
    |    |    |__ todo.js
    |    |    |
    |    |    |
    |    |    |
    |__ jsconfig.json
    |
    |

```
For us to configure the module alias we will introduce a new key known as paths. Paths is a key that accepts the alias of a path as its values. We will update the config file to include paths entries in light of the aforementioned file structure. The jsconfig.json file will seem as follows when beginning from the root:

```javascript
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@components/*": ["src/components/*"],
      "@pages/*": ["src/pages*"],
    }
  }
}

```

The paths object contains entries whose paths, are located relative to the baseUrl. In the above code, the entries are relative to the project root, because the value of baseUrl is ".".

If we use src as the value of baseUrl, the path entries will appear as follows:

```javascript
{
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
      "@components/*": ["components/*"],
      "@pages/*": ["pages/*"],
    }
  }
}

```
If you notice when specifying the paths, src was omitted because the baseUrl is pointing to src already.

The configuration shown above generates path aliases for each file in the:

pages folder using @pages
component folder using @components

The new path to access files in the components folder will become

```javascript
// using absolute import
import todo from "pages/todo"

// Using module aliases
import todo from "@pages/todo"

// This is because all files in pages have been aliased to @pages
```

While configuring our projects to use the absolute imports we might run into some problems. Below is the way we can troubleshoot them.

First, we must make sure that Next.js is at least version 9.4 on our system. Then, if we make changes to the jsconfig.json configuration file, we must restart the Next.js project.

## Best use case
- Relative imports should be used while working on a little project that doesn't need much configuration that is needed in the case of absolute imports.

- If you are working on a very large project which involves many folders that are deeply nested it is advised to use the absolute imports. This is because it protects your project from a future problem that comes from using a relative import.


## Conclusion
As we've learned, unlike absolute imports, relative imports don't require any setting. However, relative imports can occasionally be unclear and have a negative impact on the development experience. With absolute imports, we have a clearer and shorter method for importing modules in Next.js.
I sincerely hope you liked reading this article.