Absolute imports are an essential developer experience feature for me in any JavaScript application. In this post, I’ll explain what they are, how to use them, and why they matter.
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 theviews/pagesdirectory.”
Here’s that same import with an absolute path:
import { Page } from 'views/pages/Page';
In words:
“Bring in the named export
Page, which can be found in theview/pagesdirectory.”
That directory is relative to some place we don’t know about. Typically it’s the src/ directory, but we can’t say that with just this much information.
The difference between these two statements is subtle; just a few characters.
It’s configurable on every kind of JavaScript and TypeScript project I’ve
worked on. Here’s how to enable it on a TypeScript Create React App application:
in the file tsconfig.json:
{
"compilerOptions": {
"baseUrl": "./src"
}
}
Search “absolute imports in X framework” for the implementation in your framework.
I love absolute imports, and strongly prefer them to relative! Here are a few reasons why.
Reasons They’re Great: Good Completions
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.
Absolute import paths are 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 correct given
my current buffer’s location.
Reasons They’re Great: Moving Files Easily
Second, absolute imports let me easily move files around. When all imports are absolute, there’s less friction to moving a file, because all of the imports will just boringly work in the new directory.
Reasons They’re Great: Readability
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 I think 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'
Reasons They’re Great: Decoupling Code from Directories
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 time thinking about.
An Exception: 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.tsx
Component.module.scss
Component.test.tsx
Relative imports are arguably a helpful convention for the co-located files:
// Component.tsx importing its stylesheet
import { styles } from './Component.module.scss';
// Component.test.tsx 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 strongly recommend absolute imports for a more joyful JavaScript coding experience.