Semantic configuration tooling for webpack and rspack projects.
pack-config-diff supports both:
diff: compare two webpack/rspack configuration objects and explain what changed.dump: serialize live webpack/rspack configs to YAML/JSON/inspect for review or diffing.
Extracted from Shakapacker, battle-tested in production workflows.
- Debug "works in dev, broken in prod" by comparing two configs side by side
- Validate webpack -> rspack migration parity
- Audit config changes before/after dependency upgrades
- Compare CI vs local bundler behavior
- Generate PR-ready markdown diff reports
npm install pack-config-diffnpm install
npm run hooks:installRun npm run hooks:install once per clone to wire up lefthook locally.
The tool takes two config files (--left and --right) and shows what's different between them. Config files can be JavaScript, TypeScript, JSON, or YAML.
pack-config-diff --left=webpack.dev.js --right=webpack.prod.js================================================================================
Webpack/Rspack Configuration Comparison
================================================================================
Comparing: webpack.dev.js
vs: webpack.prod.js
Found 4 difference(s): 0 added, 0 removed, 4 changed
================================================================================
1. [~] mode
What it does:
Defines the environment mode (development, production, or none). Controls built-in optimizations and defaults.
Affects: Minification, tree-shaking, source maps, and performance optimizations
Values:
dev: "development"
prod: "production"
Impact: Enabling production optimizations (minification, tree-shaking)
Documentation: https://webpack.js.org/configuration/mode/
2. [~] output.filename
What it does:
Filename template for entry chunks. Can include [name], [hash], [contenthash].
Affects: Output filenames and cache busting strategy
Values:
dev: "bundle.js"
prod: "bundle-[contenthash].js"
Impact: Cache busting enabled - better long-term caching
Documentation: https://webpack.js.org/configuration/output/#outputfilename
...
================================================================================
Legend:
[+] = Added in prod
[-] = Removed from prod
[~] = Changed between configs
pack-config-diff dump webpack.config.js --format=yaml --mode=development --output=webpack-development-client.ymlSecurity note:
dumpoutput without--cleanmay include sensitive plugin/env values. Use--cleanwhen sharing snapshots. For trusted internal automation, add--no-warn-sensitiveto suppress the warning. For build-matrix dumps, add--no-warn-env-labelto suppress only theNODE_ENVfallback environment-label note.
# Quick summary for CI scripts
pack-config-diff --left=dev.json --right=prod.json --format=summary
# => 3 changes: +1 -0 ~2
# Markdown table for PR comments
pack-config-diff --left=baseline.json --right=current.json --format=markdown
# Ignore plugin noise when comparing JS configs with class instances
pack-config-diff --left=webpack.dev.js --right=webpack.prod.js --plugin-aware
# Evaluate JS/TS function exports with a specific mode
pack-config-diff --left=webpack.dev.js --right=webpack.prod.js --mode=development
# Ignore rule reorder noise
pack-config-diff --left=before.yaml --right=after.yaml --match-rules-by-test
# Focus on specific areas by ignoring paths
pack-config-diff --left=a.json --right=b.json --ignore-paths="plugins.*,devServer"
# Save report to a file
pack-config-diff --left=a.json --right=b.json --format=json --output=report.json
# Dump a config with inline docs (YAML only)
pack-config-diff dump webpack.config.js --annotate
# Dump as JSON with special value placeholders for functions/RegExp/class instances
pack-config-diff dump webpack.config.js --format=json
# Dump with independent mode + metadata environment labels
pack-config-diff dump webpack.config.js --mode=development --environment=staging
# Dump one named build from a build-matrix config
pack-config-diff dump --build=prod --config-file=config/pack-config-diff-builds.yml --save-dir=./config-exports
# Dump every build in the matrix
pack-config-diff dump --all-builds --config-file=config/pack-config-diff-builds.yml
# Keep sensitive warning but suppress build NODE_ENV label note
pack-config-diff dump --build=dev --config-file=config/pack-config-diff-builds.yml --no-warn-env-labelAny file that contains a webpack/rspack configuration object:
| Format | Extensions | Notes |
|---|---|---|
| JavaScript | .js |
Loaded via require(). Supports object exports and function exports (env, argv) => config |
| TypeScript | .ts |
Same as JS, requires ts-node as a peer dependency |
| JSON | .json |
A plain JSON object representing the config |
| YAML | .yaml, .yml |
Same structure as JSON, just in YAML syntax |
You can mix formats: --left=config.yaml --right=webpack.config.js works fine.
YAML and JSON configs are snapshots of resolved webpack configuration objects — the same data structure that webpack.config.js exports, just serialized to a different format. They're useful when you want to compare configs generated by a framework (like Shakapacker), dump configs from CI builds, or store config snapshots in version control.
See Input Formats for full details and examples.
const { DiffEngine, DiffFormatter, loadConfigFile, serializeConfig } = require("pack-config-diff");
const engine = new DiffEngine({ ignorePaths: ["plugins.*"] });
const result = engine.compare(leftConfig, rightConfig, {
leftFile: "webpack.dev.js",
rightFile: "webpack.prod.js",
});
const formatter = new DiffFormatter();
console.log(formatter.formatDetailed(result));
const config = loadConfigFile("webpack.config.js");
const output = serializeConfig(
config,
{
exportedAt: new Date().toISOString(),
bundler: "webpack",
environment: "development",
configType: "client",
configCount: 1,
},
{ format: "yaml" },
);
console.log(output);See Programmatic API docs for full API reference.
- Getting Started — what this tool does and how to use it
- Input Formats — JS, TS, JSON, and YAML config files explained
- CLI Reference — all options and flags
- Output Formats — detailed, summary, json, yaml, and markdown
- Comparison Modes — plugin-aware mode, rule matching, path normalization
- Programmatic API — using pack-config-diff from Node.js
- Releasing — how to publish new versions
- Update changelog for release prep:
/update-changelog release(see .claude/commands/update-changelog.md) - Run release dry run:
npm run release:dry-run - Publish release:
npm run release(script: scripts/release.sh) - Address PR reviews (Claude command): .claude/commands/address-review.md
- Address PR reviews (command mirror): commands/address-review.md
- Address PR reviews (portable workflow prompt): .agents/workflows/address-review.md
npm testMIT