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.
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',
});
dependenciesToRemove
string | string[]
required
Package name(s) to remove from both dependencies and devDependencies
Optional configuration objectoptions.packageJsonPath
string
default:"package.json"
Path to the target package.json file
Set to false to skip running package manager install after changes
Set to false to preview returned JSON without writing to disk
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
The function automatically detects the package manager in this order:
package.json packageManager field
- Lockfile detection:
pnpm-lock.yaml → pnpm
yarn.lock → yarn
- Defaults to npm
When runInstall is enabled (default), it runs <package-manager> install in the package directory.
Usage Examples
Basic Removal
Preview Mode
Monorepo Usage
// 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');
}
// 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);
}
// 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
});
}
Script Analysis
getScriptsNode
Finds the “scripts” section in a package.json AST.
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());
}
The root node of the package.json AST (parsed as JSON)
Returns: SgNode[] - Array of nodes representing pairs in the scripts section
getNodeJsUsage
Finds all references to node or node.exe in package.json scripts.
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
}
The root node of the package.json AST
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
replaceNodeJsArgs
Replaces Node.js script arguments in package.json scripts. Useful for normalizing or rewriting CLI arguments used with node.
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': ''
});
The root node of the package.json AST
argsToValues
Record<string, string>
required
A mapping of argument names to their replacement values. Use empty string to remove an argument.
Returns: Edit[] - Array of edit operations to apply
removeNodeJsArgs
Removes specified arguments from Node.js script usages in package.json.
import { removeNodeJsArgs } from '@nodejs/codemod-utils/ast-grep/package-json';
// Remove deprecated flags
const edits = removeNodeJsArgs(packageJsonAst, [
'--inspect',
'--experimental-modules'
]);
context.applyEdits(edits);
The root node of the package.json AST
Array of argument names to remove from Node.js commands in scripts
Returns: Edit[] - Array of edit operations to apply
Complete Example: Migrating Package Scripts
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
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
// 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);
}