Jake Worth

Jake Worth

The Joy of JavaScript Absolute Imports

Published: May 02, 2023 3 min read

  • javascript

Absolute imports are an essential feature for me in any JavaScript application. In this post, I’ll explain what they are and why they’re great.

What Is An Absolute Import?

It’s easier to think of an absolute import in contrast to a relative import, which looks like this:

import { Page } from '../../views/pages/Page';

Translating this code into words, “bring in the named export Page, which can be found ‘up’ two directories and then inside the views/pages directory.”

Here’s that same import via an absolute path:

import { Page } from 'views/pages/Page';

In words, “bring in the named export Page, which can be found in the view/pages directory.” That directory is relative to some place we don’t know about. Typically it’s the src/ directory, but we can’t say that in this context.

The difference between these two statements is subtle, just a few characters. It’s easy to enable this option in every kind of JavaScript application I’ve worked on. Google “absolute imports in X framework” for the implementation in your framework.

Why Are They Great?

I love absolute imports; here are a few reasons why.

First, absolute imports auto-complete well. I use Vim’s ctrl-x ctrl-l to autocomplete my import statements, which compares what I’ve typed so far in a line against other lines in my project, suggesting completions that I can tab through. Our absolute import is the same regardless of where Page is imported, which lets our autocomplete give me a correct suggestion if it’s ever seen a similar line before. Relative imports won’t work this way reliably, because my text editor is going to suggest a relative path that’s not necessary valid given my current buffer’s location.

Second, absolute imports let me easily move files around. When all imports are absolute, there’s no friction to moving a file. All of the imports will just boringly work.

Third, absolute imports scale well. A large React component is typically going to have a lot of imports:

import { AboutUs } from '../../../views/pages/AboutUs';
import { Blog } from '../../../views/pages/Blog';
import { Dashboard } from '../../../views/pages/Dashboard';
import { Login } from '../../../views/pages/Login';
import { Navbar } from '../../navbars/Navbar';
import { PasswordReset } from '../../../views/pages/PasswordReset';

import '../../../stylesheets/Dashboard.scss'

What value are these dots and slashes providing? Remove them and readability increases:

import { AboutUs } from 'views/pages/AboutUs';
import { Blog } from 'views/pages/Blog';
import { Dashboard } from 'views/pages/Dashboard';
import { Login } from 'views/pages/Login';
import { Navbar } from 'navbars/Navbar';
import { PasswordReset } from 'views/pages/PasswordReset';

import 'stylesheets/Dashboard.scss'

Most importantly, absolute imports decouple my code from the directory structure. The location of Page relative to where it’s imported is not important enough information to encode. Or spend any time thinking about.

An Exception For Co-located Stylesheets and Tests

Even with absolute imports as a convention, I still use relative imports occasionally. One use case is a React app with co-located stylesheets and tests. In a directory such as this:

$ ls src/components/
Component.jsx
Component.module.scss
Component.test.jsx

Relative imports are arguably a helpful convention for the co-located files:

// Component.jsx importing its stylesheet
import { styles } from './Component.module.scss';
// Component.test.jsx importing its test subject
import { Component } from './Component';

Conclusion

For an exploration of JavaScript imports, check out my post on the subject, How to Organize JavaScript Imports. I recommend absolute imports for a more joyful JavaScript coding experience.

What are your thoughts on absolute imports? Let me know!


Join 100+ engineers who subscribe for advice, commentary, and technical deep-dives into the world of software.