Want Absolute Imports in React Native? Just Add a Little JSON

If you’ve spent any time working with React Native, you’ve probably run into a peculiar quirk where you’re seemingly forced to use relative imports in all of your source files. Things start to look a bit like this:


import {Thing} from "../../../../core/thing";
import {Foo} from "../../foo";

It all quickly becomes unwieldy because it requires you to perform relative-path computations in your head while you’re trying to figure out what you’re importing or where exactly you need to import other things from. That is to say, it obscures meaning both when reading and writing code. And it wastes your precious brain-cycles and time.

Good news! You can use absolute imports with React Native without resorting to brittle configurations or third-party libraries. And it’s actually not that hard. (It’s just not documented anywhere on reactnative.dev.)

Sprinkle Some package.json Files Around Your Codebase!

The trick is to drop some package.json files into the folders that you would like to be able to absolute-import from. Let’s presume that all of your source lives under the folder src/ and that you have a folder src/redux that’s commonly imported from. In this case, you could create a file, src/redux/package.json with the following content:


{"name": "redux"}

After you do this, it’s possible to import from any other file in your source tree using an absolute path. For example, from src/screens/onboarding/welcome.ts:


import * as Actions from "redux/actions";

I think this is a great improvement over:


import * as Actions from "../../redux/actions"

Don’t you?

But Now TypeScript Is Unhappy!

Even though you’ve resorted to using React Native, you are still a professional, so you’re using TypeScript. And you’ll quickly discover that TypeScript isn’t happy about your new import situation.

What’s this “redux” package? TypeScript doesn’t know anything about it. That’s because TypeScript is as blissfully unaware of metro bundler as I wish I could be.

Fortunately, you can also remedy TypeScript’s complaints by updating your tsconfig.json:


{
    ...
    "paths": {
        "redux/*": ["./src/redux/*"]
    }
}

Worth It!

Yes, you’ll need to manually edit two files for each top-level “module” or “package” that you’d like to exist in your application. Fortunately, at least for us, those don’t seem to come along too often. On my current project, there are only a dozen of them.

For TypeScript in particular, you could conceivably set the "baseUrl" option in your tsconfig.json instead of manually enumerating your top-level modules. (There are various reasons this wasn’t going to work for our project.)

If you’re developing with React Native, I hope this helps you. Having absolute imports has been a big benefit to our team.