Search code examples
node.jsnpmyarnpkgpnpm

Is there a cross-platform way to get the name of the parent process in Node.js?


I'm working on an npm package initializer, that is, a program that runs when the user runs the npm init <my-package-initializer> command.

npm is not the only package manager for Node.js any more, yarn is also quite popular and pnpm is a personal favorite of mine and I want to support all three. The easy way is to ask the user which package manager they prefer or provide a command-line switch like CRA does.

But the user has already shown their preference by running, say, yarn create instead of npm init. It feels annoying to ask again. We could just check if yarn or pnpm is our parent process.

Is there a cross-platform way to get this information?


Solution

  • For future googlers, I ended up using the following snippet. I use it for picking the default choice but I still ask the user explicitly for their package manager preference, better safe than sorry.

    function getPackageManager() {
        // This environment variable is set by npm and yarn but pnpm seems less consistent
        const agent = process.env.npm_config_user_agent;
    
        if (!agent) {
            // This environment variable is set on Linux but I'm not sure about other OSes.
            const parent = process.env._;
    
            if (!parent) {
                // No luck, assume npm
                return "npm";
            }
    
            if (parent.endsWith("pnpx") || parent.endsWith("pnpm")) return "pnpm";
            if (parent.endsWith("yarn")) return "yarn";
    
            // Assume npm for anything else
            return "npm";
        }
    
        const [program] = agent.split("/");
    
        if (program === "yarn") return "yarn";
        if (program === "pnpm") return "pnpm";
    
        // Assume npm
        return "npm";
    }