> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/nodejs/userland-migrations/llms.txt
> Use this file to discover all available pages before exploring further.

# Package.json Utilities

> Utilities for analyzing and transforming package.json files

Utilities for removing dependencies, analyzing scripts, and transforming Node.js arguments in package.json files.

## Dependency Management

### removeDependencies

Removes dependencies from `dependencies` and `devDependencies` in `package.json`, then optionally runs the detected package manager install command.

```typescript theme={null}
import removeDependencies from '@nodejs/codemod-utils/remove-dependencies';

// Remove single dependency
await removeDependencies('chalk');

// Remove multiple dependencies
await removeDependencies(['chalk', 'lodash']);

// Remove without running install
await removeDependencies(['chalk', 'lodash'], {
  runInstall: false,
});

// Use custom package.json path
await removeDependencies('old-package', {
  packageJsonPath: './packages/app/package.json',
});
```

<ParamField path="dependenciesToRemove" type="string | string[]" required>
  Package name(s) to remove from both `dependencies` and `devDependencies`
</ParamField>

<ParamField path="options" type="object">
  Optional configuration object

  <ParamField path="options.packageJsonPath" type="string" default="package.json">
    Path to the target package.json file
  </ParamField>

  <ParamField path="options.runInstall" type="boolean" default="true">
    Set to `false` to skip running package manager install after changes
  </ParamField>

  <ParamField path="options.persistFileWrite" type="boolean" default="true">
    Set to `false` to preview returned JSON without writing to disk
  </ParamField>
</ParamField>

**Returns**: `Promise<string | null>`

* Returns updated `package.json` content as a string when changes are applied
* Returns `null` when:
  * There is nothing to remove
  * No `package.json` exists at the specified path
  * A parsing or runtime failure occurs

### Package Manager Detection

<Note>
  The function automatically detects the package manager in this order:

  1. `package.json` `packageManager` field
  2. Lockfile detection:
     * `pnpm-lock.yaml` → pnpm
     * `yarn.lock` → yarn
  3. Defaults to npm

  When `runInstall` is enabled (default), it runs `<package-manager> install` in the package directory.
</Note>

### Usage Examples

<Tabs>
  <Tab title="Basic Removal">
    ```typescript theme={null}
    // Remove deprecated package after migration
    const result = await removeDependencies('deprecated-package');

    if (result) {
      console.log('Successfully removed dependency');
    } else {
      console.log('Package not found in dependencies');
    }
    ```
  </Tab>

  <Tab title="Preview Mode">
    ```typescript theme={null}
    // Preview changes without writing to disk
    const preview = await removeDependencies(['pkg1', 'pkg2'], {
      persistFileWrite: false,
      runInstall: false
    });

    if (preview) {
      console.log('Would update package.json to:');
      console.log(preview);
    }
    ```
  </Tab>

  <Tab title="Monorepo Usage">
    ```typescript theme={null}
    // Remove from multiple packages in a monorepo
    const packages = [
      './packages/app/package.json',
      './packages/api/package.json'
    ];

    for (const pkgPath of packages) {
      await removeDependencies('old-dep', {
        packageJsonPath: pkgPath
      });
    }
    ```
  </Tab>
</Tabs>

## Script Analysis

### getScriptsNode

Finds the "scripts" section in a package.json AST.

```typescript theme={null}
import { getScriptsNode } from '@nodejs/codemod-utils/ast-grep/package-json';
import astGrep from 'codemod:ast-grep';

const packageJsonContent = context.readFile('package.json');
const ast = astGrep.parse('json', packageJsonContent);
const scriptsNodes = getScriptsNode(ast);

for (const scriptNode of scriptsNodes) {
  console.log(scriptNode.text());
}
```

<ParamField path="packageJsonRootNode" type="SgRoot" required>
  The root node of the package.json AST (parsed as JSON)
</ParamField>

**Returns**: `SgNode[]` - Array of nodes representing pairs in the scripts section

### getNodeJsUsage

Finds all references to `node` or `node.exe` in package.json scripts.

```typescript theme={null}
import { getNodeJsUsage } from '@nodejs/codemod-utils/ast-grep/package-json';

const nodeUsages = getNodeJsUsage(packageJsonAst);

// Finds scripts like:
// "start": "node server.js"
// "build": "node.exe build.js"
// "dev": "node --inspect app.js"

for (const usage of nodeUsages) {
  console.log(usage.text()); // Unquoted script content
}
```

<ParamField path="packageJsonRootNode" type="SgRoot" required>
  The root node of the package.json AST
</ParamField>

**Returns**: `Array<{ node: SgNode, text: () => string }>` - Array of objects containing:

* `node`: The AST node for the script
* `text()`: Function that returns the unquoted script content

## Node.js Argument Transformation

### replaceNodeJsArgs

Replaces Node.js script arguments in `package.json` scripts. Useful for normalizing or rewriting CLI arguments used with `node`.

```typescript theme={null}
import { replaceNodeJsArgs } from '@nodejs/codemod-utils/ast-grep/package-json';

// Replace --inspect with --inspect-brk
const edits = replaceNodeJsArgs(packageJsonAst, { 
  '--inspect': '--inspect-brk' 
});
context.applyEdits(edits);

// Remove an argument by replacing with empty string
const edits2 = replaceNodeJsArgs(packageJsonAst, { 
  '--experimental-modules': '' 
});

// Multiple replacements
const edits3 = replaceNodeJsArgs(packageJsonAst, {
  '--inspect': '',
  '--experimental-worker': ''
});
```

<ParamField path="packageJsonRootNode" type="SgRoot" required>
  The root node of the package.json AST
</ParamField>

<ParamField path="argsToValues" type="Record<string, string>" required>
  A mapping of argument names to their replacement values. Use empty string to remove an argument.
</ParamField>

**Returns**: `Edit[]` - Array of edit operations to apply

### removeNodeJsArgs

Removes specified arguments from Node.js script usages in `package.json`.

```typescript theme={null}
import { removeNodeJsArgs } from '@nodejs/codemod-utils/ast-grep/package-json';

// Remove deprecated flags
const edits = removeNodeJsArgs(packageJsonAst, [
  '--inspect',
  '--experimental-modules'
]);

context.applyEdits(edits);
```

<ParamField path="packageJsonRootNode" type="SgRoot" required>
  The root node of the package.json AST
</ParamField>

<ParamField path="argsToRemove" type="string[]" required>
  Array of argument names to remove from Node.js commands in scripts
</ParamField>

**Returns**: `Edit[]` - Array of edit operations to apply

## Complete Example: Migrating Package Scripts

```typescript theme={null}
import astGrep from 'codemod:ast-grep';
import { 
  getNodeJsUsage, 
  replaceNodeJsArgs,
  removeNodeJsArgs 
} from '@nodejs/codemod-utils/ast-grep/package-json';
import removeDependencies from '@nodejs/codemod-utils/remove-dependencies';

const packageJsonPath = 'package.json';
const content = context.readFile(packageJsonPath);
const ast = astGrep.parse('json', content);

// Find all node usage in scripts
const nodeUsages = getNodeJsUsage(ast);

if (nodeUsages.length > 0) {
  console.log(`Found ${nodeUsages.length} Node.js script(s)`);
  
  // Remove deprecated --experimental-modules flag
  const removeEdits = removeNodeJsArgs(ast, ['--experimental-modules']);
  
  // Replace --harmony flag with modern equivalent
  const replaceEdits = replaceNodeJsArgs(ast, {
    '--harmony': ''
  });
  
  // Apply all edits
  const allEdits = [...removeEdits, ...replaceEdits];
  if (allEdits.length > 0) {
    let updatedContent = content;
    for (const edit of allEdits) {
      updatedContent = edit.commitEdits(updatedContent);
    }
    context.writeFile(packageJsonPath, updatedContent);
  }
}

// Remove any deprecated dependencies
await removeDependencies(['deprecated-pkg']);
```

## Migration Patterns

### Detecting Build Tool Usage

```typescript theme={null}
const scripts = getScriptsNode(ast);
let usesWebpack = false;
let usesVite = false;

for (const script of scripts) {
  const text = script.text();
  if (text.includes('webpack')) usesWebpack = true;
  if (text.includes('vite')) usesVite = true;
}

if (usesWebpack && !usesVite) {
  console.log('Consider migrating from webpack to vite');
}
```

### Updating Node.js Flags Across Scripts

```typescript theme={null}
// Remove all deprecated flags at once
const deprecatedFlags = [
  '--experimental-modules',
  '--experimental-worker',
  '--experimental-json-modules'
];

const edits = removeNodeJsArgs(ast, deprecatedFlags);

if (edits.length > 0) {
  console.log(`Removing ${edits.length} deprecated flag usage(s)`);
  context.applyEdits(edits);
}
```
