Find your module's location
Tags: javascript, node
Published: 2024-03-25 08:31:25

---
title: Find your module's location
published: true
date: 2024-03-25 00:00:00 UTC
tags: javascript, nodejs
canonical_url: https://khendrikse.netlify.app/blog/find-your-modules-location/
description: This is how you can be sure where your node module is located in the filesystem. And how you can use that knowledge to copy a file from within the module to the repository that is using the module.
---

**Recently, I needed to create a node module that would copy a file from within the module into the repository that was using it. For this, I had to find the file's exact location within the node module. I needed to make sure that this script would work independently from where it was installed. Luckily, this is where `import.meta.url` came in.**

## `import.meta.url`

The very useful `import.meta.url` will return a string that [contains the full URL to the module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import.meta#url) that it is being called from. As MDN mentions, when you are using this outside of the browser and in a Node.js environment, this will actually be a file path. In my case, I was dealing with a Node.js environment (which is older than Node.js v20), which is why I'll focus on that here.

## `__dirname`

Some might wonder: why don't you just use `__dirname`? Well, if you want to use ES modules, this is simply not available. It means you're going to have to use `import.meta.url` instead. PLUS, you have to do some extra work as well. We'll get to that.

## Why not just use `process.cwd()`?

If you use `process.cwd()`, you will actually get the directory where you started the process. In the case of using a module within a repository, it would mean that you would get the repository's directory, not the module's directory. And that is something we do not want here. This is why you need to use `import.meta.url` to get the module's actual directory.

## Getting the actual directory

Speaking of, let's get that directory. So my file was inside of a `foo` folder (of course it wasn't, but let's pretend it was). I wanted to copy a file from within the `foo` folder to the repository that was using the module. I used `import.meta.url` which got me a filepath to the current module I was in.

I had to make sure that this filepath was a normal url first, which is where `fileURLToPath` from the `url` module came into play. After this, I passed this path to the `dirname` function (from the `path` module) to get the directory of the module. And voila. I had the directory of the module.

```js
// In Node.js version 14.14 and up:

import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const moduleDirectory = dirname(fileURLToPath(import.meta.url));
```

## Modern Node.js

With Node.js version 21.2, a new option called `import.meta.dirname` was introduced. While this [only works for file modules](https://nodejs.org/api/esm.html#importmetadirname), it would do the trick:

```js
const moduleDirectory = import.meta.dirname;
```

## Using the directory

Now that I had the directory, I could actually copy my files to the root folder of my repository. To do this I used the `fs` module to read the file and write it to the repository's directory. And this is also where `process.cwd()` came in.

```js
import { readFileSync, writeFileSync } from 'node:fs';
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const moduleDirectory = dirname(fileURLToPath(import.meta.url));

const file = readFileSync(`${moduleDirectory}/foo/file.txt`);
writeFileSync(`${process.cwd()}/file.txt`, file);
```

And that is how you can copy a file from within a module to the repository it's being used in. Voila!