Skip to content

How to Use the tsconfig.json “paths” Option in Node.js

Enabling import aliases with tsconfig-paths

When working on a Node.js project, managing module imports can become a cumbersome task. Thanks to TypeScript and its tsconfig.json configuration file, you can use the paths option to simplify the process of importing modules. This feature allows you to define custom aliases, making the import or require instructions much more readable. At the same time, Node.js does not support that feature out of the box.

In this tutorial, you will learn how to use tsconfig.json‘s paths option in Node.js through the tsconfig-paths package. Time to make module management more efficient and maintainable!

Why ts-node Does Not Support Paths

Suppose your tsconfig.json file contains the following code:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "lib": ["es6"],
    "strict": true,
    "esModuleInterop": true,
    "outDir": "./build",
    "sourceMap": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}

Note the paths option, which allows you to specify a set of aliases that re-map imports to lookup locations. This makes the require/import instructions in your code easier to read, as below:

import * as Constants from "@/constants"
import express from "express"

const app = express()

app.get("/hello-world", (req, res) => {
    res.json(Constants.HELLO_WORLD_MESSAGE)
})

Note how elegant the first import instruction is compared to something like this:

import * as Constants from "./../../constants"

paths are cool, but unfortunately Node.js does not support them. Let’s understand why!

In TypeScript, modules are resolved similarly to the way Node.js does. However, the paths option allows you to specify arbitrary module paths that don’t start with / or .. These special aliases can be mapped to physical paths on the file system, which the TypeScript compiler can resolve from the tsconfig.json file. So, TypeScript will be able to compile the code successfully.

However, when trying to run files compiled ts-node, they will only look for modules in the node_modules folders up to the root of the file system. As a result, modules specified by paths in tsconfig.json will not be found and the Node.js server will fail with the following error:

Error: Cannot find module '@/contants'

Luckily, there is a solution and it is called tsconfig-paths. Time to learn how to configure it to make paths works in ts-node!

Using paths in ts-node With tsconfig-paths

tsconfig-paths is an npm library that allows ts-node to load modules imported using the aliases defined in the paths section of tsconfig.json.

Add it to your project’s dependencies with:

npm i tsconfig-paths

Then, update the command to launch your ts-nodeproject as follows:

ts-node -r tsconfig-paths/register index.ts

Where index.js is your Node.js main TypeScript file.

Et voilà! The “Cannot find module” error is now gone and your ts-node project is working with paths aliases.

At the same time, if try to compile your TypeScript code with tsc and then launch it with node, you will still get a “Cannot find module” error. tsconfig-paths works like a charm with ts-node but still have some issues with node.

As you can read on the official GitHub page of the issue, there are several workarounds to address the problem. An effective solution is to change the Node.js start command of the tsc compiled code to:

node -r ts-node/register/transpile-only -r tsconfig-paths/register build/index.js

Where build/index.js is the path to the main Node.js file in your outDir folder.

If you are worried about using ts-nodein production, note that ts-node/register/transpile-only does not introduce significant performance overhead.

Congrats! Error fixed!

Conclusion

In this article, you saw what paths are, how to configure them in tsconfig.json, why Node.js does not support them, and how to address this issue. Specifically, you learned that the tsconfig-paths library can help you make Node.js work with imports involving aliases defined in paths.

Thanks for reading! I hope you found this article helpful.

nv-author-image

Antonello Zanini

I'm a software engineer, but I prefer to call myself a Technology Bishop. Spreading knowledge through writing is my mission.View Author posts

Want technical content like this in your blog?