Skip to main content

Overview

Devark automatically detects your package manager and uses it to install dependencies. It supports:
  • npm - Node Package Manager (default)
  • pnpm - Fast, disk-efficient package manager
  • yarn - Fast, reliable, and secure dependency management
  • bun - All-in-one JavaScript runtime and toolkit
You never need to manually specify your package manager. Devark figures it out automatically by checking for lock files or environment variables.

Auto-Detection Logic

Devark uses a two-phase detection strategy:

1. Lock File Detection

Devark first checks for lock files in your project directory:
src/utils/packageManager.js
export function detectPackageManager(targetPath) {
  const lockFiles = {
    pnpm: ["pnpm-lock.yaml"],
    yarn: ["yarn.lock"],
    npm: ["package-lock.json"],
    bun: ["bun.lock", "bun.lockb"],
  };

  for (const [manager, files] of Object.entries(lockFiles)) {
    if (files.some((file) => fs.existsSync(path.join(targetPath, file)))) {
      return manager;
    }
  }
  return null;
}
Detection order:
  1. Check for pnpm-lock.yaml → return pnpm
  2. Check for yarn.lock → return yarn
  3. Check for package-lock.json → return npm
  4. Check for bun.lock or bun.lockb → return bun
  5. If none found → return null
The order prioritizes specificity:
  • pnpm and yarn have unique lock files
  • npm is checked before bun as it’s more common
  • bun can coexist with other lock files, so it’s checked last
If multiple lock files exist (not recommended), the first match wins.

2. Command Detection (Fallback)

If no lock file is found, Devark checks the npm_config_user_agent environment variable:
src/utils/packageManager.js
export function detectByCommand() {
  const ua = process.env.npm_config_user_agent || "";
  if (ua.startsWith("yarn")) return "yarn";
  if (ua.startsWith("pnpm")) return "pnpm";
  if (ua.startsWith("bun")) return "bun";
  if (ua.startsWith("npm")) return "npm";
  return "bun"; // Default fallback
}
The npm_config_user_agent variable is automatically set by package managers when running scripts. For example:
  • yarn/1.22.19 npm/? node/v18.0.0
  • pnpm/8.6.0 npm/? node/v18.0.0

Detection in Action

When you install a module, you’ll see detection messages:
$ devark add google-oauth

 Installing Google OAuth module...
 pnpm detected

? Which version do you want to add for this module?

Lock File Behavior

Each package manager creates specific lock files:
my-project/
├── package.json
└── package-lock.json    # Generated by npm
Created when:
  • Running npm install
  • Installing packages with npm install <package>
Purpose:
  • Locks exact versions of all dependencies
  • Ensures reproducible installs
  • Speeds up subsequent installs
Never mix package managers in the same project.Having multiple lock files (e.g., both package-lock.json and yarn.lock) can cause:
  • Dependency version conflicts
  • Duplicated packages
  • Increased project size
  • Confusing team members
Choose one and commit only its lock file to version control.

Installation Commands

Devark uses the appropriate command for each package manager:
src/utils/packageManager.js
export function installDependencies(targetPath, dependencies) {
  const packageManager = detectPackageManager(targetPath);
  if (!packageManager) {
    console.error("  Could not detect package manager. Install manually:");
    console.log(`   npm install ${dependencies.join(" ")}`);
    return;
  }

  const commands = {
    npm: `npm install ${dependencies.join(" ")}`,
    yarn: `yarn add ${dependencies.join(" ")}`,
    pnpm: `pnpm add ${dependencies.join(" ")}`,
    bun: `bun add ${dependencies.join(" ")}`,
  };

  console.log(
    ` Installing dependencies using ${packageManager}`
  );
  execSync(commands[packageManager], { cwd: targetPath, stdio: "inherit" });
}

Command Comparison

Actionnpmyarnpnpmbun
Install depsnpm installyarnpnpm installbun install
Add packagenpm install pkgyarn add pkgpnpm add pkgbun add pkg
Add dev depnpm install -D pkgyarn add -D pkgpnpm add -D pkgbun add -d pkg
Remove packagenpm uninstall pkgyarn remove pkgpnpm remove pkgbun remove pkg
Run scriptnpm run devyarn devpnpm devbun dev

Manual Override

If detection fails, Devark provides fallback instructions:
  Could not detect package manager. Install manually:
   npm install express passport passport-google-oauth20 express-session dotenv
You can then run the command with your preferred package manager:
npm install express passport passport-google-oauth20 express-session dotenv

Best Practices for Teams

Document Your Choice

Add to your README:
README.md
## Setup

This project uses **pnpm**. Install dependencies:

```bash
pnpm install
Do not use npm or yarn.
</Card>

<Card title="Enforce with Scripts" icon="lock">
Add a preinstall script to `package.json`:

```json
{
  "scripts": {
    "preinstall": "npx only-allow pnpm"
  }
}
This prevents team members from accidentally using the wrong package manager.

Commit Lock Files

Always commit your lock file:
.gitignore
node_modules/
# Do NOT ignore lock files:
# package-lock.json
# pnpm-lock.yaml
# yarn.lock
# bun.lockb

CI/CD Consistency

Use the same package manager in CI:
.github/workflows/ci.yml
- uses: pnpm/action-setup@v2
  with:
    version: 8
- run: pnpm install --frozen-lockfile
- run: pnpm test

Choosing a Package Manager

Best for:
  • Beginners
  • Maximum compatibility
  • Projects with strict auditing needs
Pros:
  • Built into Node.js
  • Largest ecosystem
  • Well-documented
  • Automatic security audits
Cons:
  • Slower than alternatives
  • Uses more disk space
  • No native workspace support (until v7)

Speed Comparison

Based on typical project installs:
Install time (cold cache):
  npm:   45s
  yarn:  35s
  pnpm:  20s
  bun:   12s

Install time (warm cache):
  npm:   20s
  yarn:  15s
  pnpm:  8s
  bun:   3s

Disk space (node_modules):
  npm:   250MB
  yarn:  250MB
  pnpm:  100MB (uses hardlinks)
  bun:   230MB
These are approximate values for a medium-sized Express project. Your mileage may vary.

Troubleshooting

This happens when you have multiple lock files:
# Check for multiple lock files
ls -la | grep lock

# Remove unwanted lock files
rm package-lock.json  # If using yarn/pnpm
rm yarn.lock          # If using npm/pnpm
rm pnpm-lock.yaml     # If using npm/yarn
Then reinstall with your preferred manager.
If Devark can’t detect your package manager:
  1. Initialize your project first:
    npm init -y
    npm install
    
  2. Or create a lock file manually:
    # For pnpm
    touch pnpm-lock.yaml
    
    # For yarn
    touch yarn.lock
    
    # For npm
    npm install --package-lock-only
    
  3. Then run Devark again:
    devark add google-oauth
    
If someone on your team used the wrong package manager:
# 1. Remove node_modules and wrong lock file
rm -rf node_modules
rm package-lock.json  # or yarn.lock, pnpm-lock.yaml

# 2. Install with correct package manager
pnpm install  # or npm/yarn/bun

# 3. Commit the correct lock file
git add pnpm-lock.yaml
git commit -m "fix: use pnpm instead of npm"
When merging branches with lock file conflicts:
# 1. Accept one version (usually main/master)
git checkout --ours pnpm-lock.yaml
# or
git checkout --theirs pnpm-lock.yaml

# 2. Regenerate lock file
rm pnpm-lock.yaml
pnpm install

# 3. Commit resolved lock file
git add pnpm-lock.yaml
git commit

Source Code Reference

Devark’s package manager detection is implemented in:
  • src/utils/packageManager.js:7-21 - detectPackageManager() function
  • src/utils/packageManager.js:79-86 - detectByCommand() fallback
  • src/utils/packageManager.js:24-43 - installDependencies() with command mapping
  • src/utils/packageManager.js:58-76 - installDepsWithChoice() for runtime/dev deps
The detection logic runs every time you install a module, ensuring Devark always uses the correct package manager even if you switch mid-project (though this isn’t recommended).

Advanced: Workspaces

If you’re using monorepos, each package manager has workspace support:
package.json
{
  "name": "my-monorepo",
  "workspaces": [
    "packages/*"
  ]
}
Devark will detect npm and install dependencies at the workspace root.
Devark works seamlessly with workspaces. It will detect the package manager and install dependencies in the correct workspace package.

Build docs developers (and LLMs) love