brainstorming
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or planning anything new, in software or out of it (a talk, a business, a renovation).
upgrade-packages-jsSafely upgrade JavaScript packages with breaking change detection, migration guidance, and automated code migrations (npm/pnpm/yarn). Cross-platform with git safety branch enforcement.
Independent GitHub snapshot · Automated classification · Original documentation governs
Safely upgrade JavaScript packages while minimizing breaking change risk, with migration guidance and automated code upgrades.
This skill is for JavaScript/TypeScript (Node.js) projects only. Run this check before anything else.
node -e "
const fs=require('fs'),p=require('path'),cwd=process.cwd();
const checks=[
['package.json','javascript/typescript','This skill supports this project type'],
['go.mod','go','Use: go get -u ./... or go-mod-upgrade'],
['Cargo.toml','rust','Use: cargo update or cargo-upgrades'],
['requirements.txt','python','Use: pip-review --auto or pip-upgrader'],
['pyproject.toml','python','Use: poetry update or pdm update'],
['Pipfile','python','Use: pipenv update'],
['composer.json','php','Use: composer update'],
['Gemfile','ruby','Use: bundle update'],
['pubspec.yaml','dart','Use: dart pub upgrade'],
['pom.xml','java','Use: mvn versions:use-latest-releases'],
['build.gradle','java','Use: gradle dependencyUpdates'],
['*.csproj','dotnet','Use: dotnet outdated or nukeeper'],
['Package.swift','swift','Use: swift package update'],
['mix.exs','elixir','Use: mix deps.update --all'],
];
const found=checks.filter(([f])=>f.includes('*')?require('fs').readdirSync(cwd).some(x=>x.endsWith(f.slice(1))):fs.existsSync(p.join(cwd,f)));
if(found.length===0){console.error('ERROR: No recognized project files found');process.exit(1)}
const js=found.find(([_,l])=>l==='javascript/typescript');
if(js){console.log('OK: JavaScript/TypeScript project detected (package.json found)');process.exit(0)}
const other=found[0];
console.error('ERROR: This skill is for JavaScript/TypeScript (Node.js) projects only.');
console.error('Detected: '+other[0]+' ('+other[1]+' project)');
console.error('Suggestion: '+other[2]);
process.exit(2);
"
| File | Language | Supported | Alternative Command |
|---|---|---|---|
package.json | JavaScript/TypeScript | ✅ Yes | This skill |
go.mod | Go | ❌ No | go get -u ./... |
Cargo.toml | Rust | ❌ No | cargo update |
requirements.txt | Python | ❌ No | pip-review --auto |
pyproject.toml | Python (Poetry/PDM) | ❌ No | poetry update / pdm update |
composer.json | PHP | ❌ No | composer update |
Gemfile | Ruby | ❌ No | bundle update |
pom.xml | Java (Maven) | ❌ No | mvn versions:use-latest-releases |
build.gradle | Java (Gradle) | ❌ No | gradle dependencyUpdates |
pubspec.yaml | Dart/Flutter | ❌ No | dart pub upgrade |
*.csproj | .NET | ❌ No | dotnet outdated |
Package.swift | Swift | ❌ No | swift package update |
mix.exs | Elixir | ❌ No | mix deps.update --all |
| Code | Meaning |
|---|---|
| 0 | JavaScript/TypeScript project - proceed with skill |
| 1 | No recognized project files found |
| 2 | Non-JavaScript/TypeScript project detected - use alternative |
IMPORTANT: If exit code is not 0, STOP and inform the user. Do not proceed with the rest of this skill.
Use {PM} = detected package manager. Use {PMX} = npx | pnpm dlx | yarn dlx.
| Purpose | npm | pnpm | yarn v1 | yarn Berry |
|---|---|---|---|---|
| Install | npm install | pnpm install | yarn | yarn |
| Add pkg | npm install {pkg} | pnpm add {pkg} | yarn add {pkg} | yarn add {pkg} |
| Add dev | npm install -D {pkg} | pnpm add -D {pkg} | yarn add -D {pkg} | yarn add -D {pkg} |
| Outdated | npm outdated | pnpm outdated | yarn outdated | yarn upgrade-interactive |
| Why installed | npm explain {pkg} | pnpm why {pkg} | yarn why {pkg} | yarn why {pkg} |
| Audit | npm audit | pnpm audit | yarn audit | yarn npm audit |
| Run ncu | npx npm-check-updates | pnpm dlx npm-check-updates | yarn dlx npm-check-updates | yarn dlx npm-check-updates |
| Frozen install | npm ci | pnpm install --frozen-lockfile | yarn --frozen-lockfile | yarn --immutable |
| Workspaces | npm -ws | pnpm -r | yarn workspaces | yarn workspaces foreach |
# One-command gate: checks + creates branch
node -e "const {execSync}=require('child_process');const run=(c)=>execSync(c,{stdio:['ignore','pipe','pipe']}).toString().trim();try{run('git --version')}catch(e){console.error('ERROR: git not installed');process.exit(10)}try{if(run('git rev-parse --is-inside-work-tree')!=='true')throw 0}catch(e){console.error('ERROR: not a git repo');process.exit(11)}try{if(run('git status --porcelain')){console.error('ERROR: working tree not clean');process.exit(12)}}catch(e){process.exit(13)}const d=new Date();const pad=n=>String(n).padStart(2,'0');const name='chore/upgrade-packages-'+d.getFullYear()+pad(d.getMonth()+1)+pad(d.getDate())+'-'+pad(d.getHours())+pad(d.getMinutes());try{run('git checkout -b '+name);console.log('OK: created branch '+name)}catch(e){process.exit(14)}"
Rules:
package.json + lockfile on this branchnode -e "const fs=require('fs'),p=require('path');const cwd=process.cwd();let pm='';try{pm=JSON.parse(fs.readFileSync(p.join(cwd,'package.json'),'utf8')).packageManager||''}catch{}const locks=[['pnpm','pnpm-lock.yaml'],['yarn','yarn.lock'],['npm','package-lock.json']].filter(([_,f])=>fs.existsSync(p.join(cwd,f)));if(pm){console.log(pm);process.exit(0);}if(locks.length===1){console.log(locks[0][0]);process.exit(0);}if(locks.length>1){console.error('ERROR: multiple lockfiles');process.exit(2);}console.error('ERROR: unable to detect PM');process.exit(1);"
Priority: package.json.packageManager > single lockfile > STOP
Yarn v1 vs Berry: Check yarn --version (1.x = Classic, 2+ = Berry)
node -e "const pkg=require('./package.json');console.log(pkg.workspaces?'MONOREPO: '+JSON.stringify(pkg.workspaces):'SINGLE_PACKAGE')"
# npm: npm ci --dry-run | pnpm: pnpm install --frozen-lockfile --dry-run | yarn: yarn --frozen-lockfile --check-files
node -e "const pkg=require('./package.json');console.log('Engines:',pkg.engines?.node||'any','Current:',process.version)"
npm view {package}@latest engines
node -e "const pkg=require('./package.json');console.log('Type:',pkg.type||'commonjs')"
npm view {package} type exports
| Project | Package | Compatible | Notes |
|---|---|---|---|
| commonjs | module | Maybe | Need dynamic import() or bundler |
| module | commonjs | Yes | Node handles interop |
npm view {package} time.modified
Flag packages >2 years since last publish.
npm view {package} license
npx license-checker --summary
# View tree
{PM} ls --depth=0
# Why installed
{PM} explain {pkg} # npm
{PM} why {pkg} # pnpm/yarn
# Peer deps
npm view {pkg} peerDependencies
| PM | Location | Example |
|---|---|---|
| npm | overrides | "overrides": {"glob": "^10.0.0"} |
| pnpm | pnpm.overrides | "pnpm": {"overrides": {"glob": "^10.0.0"}} |
| yarn | resolutions | "resolutions": {"glob": "^10.0.0"} |
npm view {pkg} repository homepage --json
{repo}/releases{repo}/blob/main/CHANGELOG.md{repo}/blob/main/UPGRADING.md or MIGRATION.mdBREAKING, Removed, Renamed, Deprecated, Migration, Codemod, engines, peerDependencies
Package: {name} | From: {current} To: {target}
Evidence: Releases: {link} | Changelog: {link} | Migration: {link} | Codemod: {cmd}
Breaking changes: {...}
Required actions: {...}
Peer constraints: {...}
Node.js requirement: {...}
If no evidence found: Proceed to Automatic Web Search (next section).
When GitHub Releases, CHANGELOG, or MIGRATION docs are not found or insufficient, automatically search the web for migration guides before asking the user.
For a package {pkg} upgrading from {from} to {to}:
Official migration guide:
"{pkg}" migration guide {from} to {to}
"{pkg}" upgrade guide v{majorFrom} to v{majorTo}
Breaking changes:
"{pkg}" {to} breaking changes
"{pkg}" v{majorTo} changelog breaking
Codemods:
"{pkg}" codemod {majorTo}
"{pkg}" migration codemod
Community guides:
"{pkg}" upgrade tutorial {majorTo}
"{pkg}" migration blog post
Prioritize results from these domains:
| Priority | Source | Examples |
|---|---|---|
| 1 | Official docs | {pkg}.dev, {pkg}.io, {pkg}js.org |
| 2 | GitHub | github.com/{org}/{pkg} (releases, discussions, wiki) |
| 3 | Dev blogs | dev.to, medium.com, hashnode.dev |
| 4 | Stack Overflow | stackoverflow.com (tagged answers) |
| 5 | Package news | npmjs.com, socket.dev |
Extract and verify:
npx {pkg}-codemod, etc.)| Search Result | Action |
|---|---|
| Official migration guide found | Follow the guide, proceed with upgrade |
| Community guide found (verified) | Use as reference, proceed cautiously |
| Breaking changes documented | Apply changes, test thoroughly |
| Only partial info found | Combine sources, ask user to verify approach |
| No useful results | Stop - Ask user before proceeding |
Package: recharts 2.x → 3.x
Step 1: Check GitHub releases → Found but sparse
Step 2: Search "recharts migration guide 2 to 3" → Found official guide
Step 3: Search "recharts 3 breaking changes" → Found API changes list
Step 4: Search "recharts codemod 3" → No codemod available
Result: Proceed with manual migration using official guide
Package: {pkg} | From: {from} To: {to}
Search performed: Yes
Sources found:
- Official: {url} (migration guide)
- GitHub: {url} (release notes)
- Community: {url} (tutorial)
Breaking changes identified:
- {change 1}
- {change 2}
Migration steps:
1. {step 1}
2. {step 2}
Codemod: {available/not available}
Confidence: {high/medium/low}
Recommendation: {proceed/ask user/skip}
If no useful migration information is found after web search:
npx ts-prune, eslint --fix){PM} install && npx tsc --noEmit && npm run lint && npm test && npm run buildgit commit -m "chore(deps): upgrade {pkg} {from}→{to}"| Type | Max | If exceeded |
|---|---|---|
| Patch | 5min | Investigate |
| Minor | 15min | Check for hidden breaks |
| Major | 30min-1hr | Document, defer |
| Group | Packages | Why |
|---|---|---|
| React | react, react-dom, @types/react* | Must align |
| Next.js | next, eslint-config-next | Paired releases |
| Prisma | prisma, @prisma/client | Must match exactly |
| TypeScript | typescript, @types/node | Compatibility |
| Tailwind | tailwindcss, postcss, autoprefixer | Paired releases |
{PM_ADD} next@latest react@latest react-dom@latest
npx @next/codemod@latest {codemod-name}
{PM_ADD} prisma@latest @prisma/client@latest
npx prisma generate && npx prisma validate
{PM_ADD} -D typescript@latest
npx tsc --noEmit
| Issue | Solution |
|---|---|
| Peer conflicts | npm view {pkg} peerDependencies, check tree |
| ESM errors | Use dynamic import() or add "type": "module" |
| Type errors | Update @types/{pkg}@latest |
| Cache issues | rm -rf .next node_modules/.cache |
| Deprecated pkg | npm view {pkg} deprecated, find alternative |
git checkout package.json {lockfile}
{PM} install
HUSKY=0 git commit -m "chore(deps): upgrade packages"
# or: git commit --no-verify -m "..."
Check .npmrc before upgrading. Verify auth:
npm whoami --registry={registry-url}
| Package | Current | Latest | Reason | Revisit |
|---------|---------|--------|--------|---------|
| old-lib | 2.0.0 | 3.0.0 | Needs React 19 | After React upgrade |
# Package Upgrade Report
**Date:** {date} | **PM:** {npm|pnpm|yarn} | **Branch:** {branch}
## Summary
- Upgraded: {count} | Major: {count} | Minor: {count} | Patch: {count} | Skipped: {count}
## Upgrades
| Package | From | To | Breaking | Migration |
|---------|------|----|---------:|-----------|
## Breaking Changes
### {pkg} {from}→{to}
- Docs: {link}
- Codemods: {cmd}
- Manual changes: {...}
- Tests added: {...}
## Verification
- [ ] Type check | [ ] Lint | [ ] Tests | [ ] Build
## Skipped
| Package | Reason |
## Rollback
`git checkout main -- package.json {lockfile} && {PM} install`
git push -u origin $(git branch --show-current)
gh pr create --title "chore(deps): upgrade packages $(date +%Y-%m-%d)" --body "## Package Upgrade\nSee upgrade report for details."
| Situation | Action |
|---|---|
| No errors | Continue |
| Minor type errors | Fix and continue |
| Major API changes | Follow migration + codemods + tests |
| No docs found | Web search first, then ask user if nothing found |
| Tests fail | Fix or revert |
| Time exceeded | Document, defer, create issue |
| ESM/CJS incompatible | Check bundler or find alternative |
| Node incompatible | Defer or find alternative |
Before upgrading any major version, run these checks to detect potential blockers.
node -e "const pkg=require('./package.json'); console.log('Project type:', pkg.type || 'commonjs')"
| Result | Meaning |
|---|---|
commonjs | Default Node.js, may have issues with ESM-only packages |
module | ESM project, compatible with all modern packages |
# Check the target version's module type
npm view {package}@{version} type
# Returns "module" = ESM-only
# Returns nothing/undefined = CommonJS compatible
| Your Project | Package Type | Compatible? | Action |
|---|---|---|---|
commonjs | module (ESM-only) | ❌ No | Skip, find alternative, or migrate project to ESM |
commonjs | (empty/commonjs) | ✅ Yes | Safe to upgrade |
module | module (ESM-only) | ✅ Yes | Safe to upgrade |
module | (empty/commonjs) | ✅ Yes | Safe to upgrade |
# Check required Node.js version
npm view {package}@{version} engines
# Compare with your project's Node version
node --version
If package requires newer Node.js than your project supports, skip or upgrade Node.js first.
# Check if package is deprecated
npm view {package} deprecated
# If deprecated, find alternative
npm search {alternative-keywords}
# View peer dependency requirements
npm view {package}@{version} peerDependencies
# Ensure your installed versions satisfy requirements
Run this before any major upgrade:
# Replace {pkg} and {ver} with actual values
node -e "
const pkg='{pkg}', ver='{ver}';
const {execSync}=require('child_process');
const run=c=>{try{return execSync(c,{encoding:'utf8'}).trim()}catch{return''}};
const projType=require('./package.json').type||'commonjs';
const pkgType=run('npm view '+pkg+'@'+ver+' type');
const engines=run('npm view '+pkg+'@'+ver+' engines');
const deprecated=run('npm view '+pkg+' deprecated');
console.log('Package:', pkg+'@'+ver);
console.log('Project type:', projType);
console.log('Package type:', pkgType||'commonjs');
console.log('Engines:', engines||'any');
console.log('Deprecated:', deprecated||'no');
console.log('---');
if(projType==='commonjs'&&pkgType==='module'){
console.log('⚠️ BLOCKER: ESM-only package in CommonJS project');
console.log('Options: 1) Skip upgrade 2) Find alternative 3) Migrate project to ESM');
}else if(deprecated){
console.log('⚠️ BLOCKER: Package is deprecated');
}else{
console.log('✅ No blockers detected - verify build after upgrade');
}
"
If you encounter an ESM-only package in a CommonJS project:
const pkg = await import('{package}') (async only)"type": "module" to package.json (major change)