npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pathmix

v1.0.1

Published

Static class for unified path management across ESM and CommonJS

Readme

PathMix

Unified path utilities for Node.js that work the same way in both ESM and CommonJS.

The problem

Whenever you need the path of the current file or its directory, Node.js requires different boilerplate depending on the module system you are using.

In ESM, __dirname and __filename do not exist. You have to reconstruct them every time:

// Without pathmix
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';

const __filename = fileURLToPath(import.meta.url);
const __dirname  = dirname(__filename);

const config = join(__dirname, 'config.json');

With pathmix, the boilerplate disappears:

// With pathmix
import PathMix from 'pathmix';

const config = PathMix.dir('config.json');

The same applies to building paths relative to the working directory:

// Without pathmix
import { join } from 'node:path';

const output = join(process.cwd(), 'dist', 'bundle.js');
// With pathmix
import PathMix from 'pathmix';

const output = PathMix.cwd('dist', 'bundle.js');

That boilerplate is easy to forget, easy to get slightly wrong, and has to be repeated in every file that needs it. If you are working across a mixed codebase — or publishing a package that must support both module systems — you end up maintaining two separate conventions.

pathmix collapses all of that into a single, consistent API.

Installation

npm install pathmix

Usage

ESM

import PathMix from 'pathmix';

// Directory of the current file (no import.meta.url needed)
PathMix.dir()               // /home/user/project/src
PathMix.dir('config.json')  // /home/user/project/src/config.json

// Current file path
PathMix.file()              // /home/user/project/src/index.js

// Or pass import.meta.url explicitly when auto-detection is not desired
PathMix.dir(import.meta.url, 'assets')  // /home/user/project/src/assets

CommonJS

const PathMix = require('pathmix');

// Identical API — no boilerplate required
PathMix.dir()               // /home/user/project/src
PathMix.dir('config.json')  // /home/user/project/src/config.json
PathMix.file()              // /home/user/project/src/index.js

API

File-relative paths

PathMix.dir(...segments)

Returns the directory of the calling file. Optionally joins one or more path segments onto it.

PathMix.dir()                    // /project/src
PathMix.dir('data', 'seed.json') // /project/src/data/seed.json
PathMix.dir(import.meta.url)     // same, explicit (ESM only)

PathMix.file(...args)

Returns the absolute path of the calling file.

PathMix.file()               // /project/src/utils.js
PathMix.file(import.meta.url) // same, explicit (ESM only)

PathMix.__dirname() / PathMix.__filename()

Drop-in equivalents for the CommonJS globals, available in both module systems.

PathMix.__dirname()   // /project/src
PathMix.__filename()  // /project/src/utils.js

Well-known base paths

PathMix.home(...segments)

PathMix.home()              // /home/user
PathMix.home('.ssh')        // /home/user/.ssh
PathMix.home('.config/app') // /home/user/.config/app

PathMix.cwd(...segments)

PathMix.cwd()               // /project
PathMix.cwd('src', 'index') // /project/src/index

PathMix.tmp(...segments)

PathMix.tmp()               // /tmp
PathMix.tmp('session-1')    // /tmp/session-1

Token expansion

PathMix.resolve(...segments)

Like path.resolve, but also expands ~ and $HOME to the user home directory.

PathMix.resolve('~/.ssh/config')    // /home/user/.ssh/config
PathMix.resolve('$HOME/.config/app') // /home/user/.config/app

Standard path utilities

All core node:path methods are re-exported on the same class, so you can import one thing and have everything:

PathMix.join('a', 'b', 'c')   // a/b/c
PathMix.basename('/a/b.js')   // b.js
PathMix.extname('app.ts')     // .ts
PathMix.dirname('/a/b/c')     // /a/b
PathMix.normalize('a//b/../c') // a/c
PathMix.relative('/a', '/a/b') // b
PathMix.isAbsolute('/foo')    // true
PathMix.parse('/a/b.js')      // { root, dir, base, ext, name }
PathMix.format({ dir: '/a', base: 'b.js' }) // /a/b.js
PathMix.sep                   // '/' on Unix, '\\' on Windows

AI Skill

You can add PathMix as a skill for AI agentic development:

npx skills add https://github.com/clasen/PathMix --skill pathmix

Requirements

Node.js >= 16