PSA: Getting __dirname and Package Information with ES Modules


tl;dr - __dirname and package information are a bit harder to get from an ES module.

In case you’re not using them yet, take a second to read up on Javascript (“ES” – EMCAScript) modules – they’re quite the large feature/platform change, big steps up (mostly) from CommonJS and RequireJS (AMD).

One of the things that isn’t quite as nice as RequireJS in NodeJS-land was is how difficult it is to programmatically get package and version information!

Before (RequireJS in the NodeJS context)

// RequireJS resolves JSON imports too!
const PACKAGE_INFO = require("../path/to/package.json");

Doing it that way is a bit unsafe though – I often use the pkginfo instead. Setting that up looks like this:

var pkginfo = require('pkginfo')(module);


After (ES Module in the NodeJS context)

//// Getting dirname and package information With ES modules
import * as fs from "node:fs";
import * as path from "node:path";
import * as url from "node:url";

// Getting __dirname
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

// Parsing package.json
const PACKAGE_INFO = JSON.parse(
  fs.readFileSync(path.resolve(path.join(__dirname, '../package.json'))).toString()

NOTE: beware the path to package.json if you’re using a transpiled language like Typescript. You’ll also have to make sure to copy package.json and your dist/build folder over when containerizing.

I frequently find myself having to look up this incantation… It’s kind of annoying that this isn’t a single import/more built in, but I guess that’s a standards/platform level RFC to be filed (if it hasn’t already been!).