Find all Node.js projects under a directory

Node.js
PowerShell
Windows
PowerShell script to inventory Node.js projects under a directory on Windows.
Published

May 22, 2026

Walks a projects folder, finds every package.json that belongs to a real project, and prints the result as JSON. A parameter controls whether to include or exclude scanning under .venv packages — useful for machines with Python projects that contain .venv directories.

Settings

Variable Default Purpose
$RootPath C:\projects Root folder of your projects
$IncludeVenv $false Set to $true to include package.json under .venv in the JSON projects list

The script

Copy the block, edit the two settings at the top, paste into a PowerShell 7+ prompt, and run.

# --- settings (edit these) ---
$RootPath = "C:\projects"
$IncludeVenv = $false   # $true to include .venv package.json in results

# --- scan (no edits below) ---
function Get-DependencyCount {
    param($Section)
    if (-not $Section) { return 0 }
    return @($Section.PSObject.Properties).Count
}

$packageFiles = Get-ChildItem -Path $RootPath -Recurse -Filter "package.json" -ErrorAction SilentlyContinue

$projects = [System.Collections.Generic.List[object]]::new()
$venvPackageCount = 0

foreach ($file in $packageFiles) {
    $projectPath = $file.Directory.FullName
    $inVenv = $file.FullName -match '[\\/]\.venv[\\/]'

    if ($file.FullName -match '[\\/]node_modules[\\/]') { continue }

    if ($inVenv -and -not $IncludeVenv) {
        try {
            $venvData = Get-Content $file.FullName -Raw | ConvertFrom-Json
            if (-not [string]::IsNullOrWhiteSpace($venvData.name)) {
                $venvPackageCount++
            }
        }
        catch {
            Write-Warning "warning: unreadable venv package.json: $($_.Exception.Message)"
        }
        continue
    }

    try {
        $packageData = Get-Content $file.FullName -Raw | ConvertFrom-Json
        if ([string]::IsNullOrWhiteSpace($packageData.name)) { continue }

        $hasLockfile = Test-Path (Join-Path $projectPath "package-lock.json")
        $depsCount = Get-DependencyCount $packageData.dependencies
        $depsCount += Get-DependencyCount $packageData.devDependencies

        $projects.Add([ordered]@{
            project      = $packageData.name
            version      = if ($packageData.version) { $packageData.version } else { "N/A" }
            path         = $projectPath
            dependencies = $depsCount
            hasLockfile  = $hasLockfile
        })
    }
    catch {
        Write-Warning "Skipped ($($_.Exception.Message)): $($file.FullName)"
    }
}

if (-not $IncludeVenv) {
    Write-Host "Packages under .venv (excluded from scan): $venvPackageCount"
}

$result = [ordered]@{
    rootPath    = $RootPath
    includeVenv = [bool]$IncludeVenv
    count       = $projects.Count
    projects    = $projects
}

$result | ConvertTo-Json -Depth 5

Example output

When $IncludeVenv is false

A log line appears before the JSON as Packages under .venv (excluded from scan): N.

Packages under .venv (excluded from scan): 5
{
  "rootPath": "C:\\projects",
  "includeVenv": false,
  "count": 1,
  "projects": [
    {
      "project": "sample-nodejs-project",
      "version": "1.0.0",
      "path": "C:\\projects\\sample-nodejs-project",
      "dependencies": 2,
      "hasLockfile": true
    }
  ]
}

When $IncludeVenv is true

The JSON includes the .venv packages.

{
  "rootPath": "C:\\projects",
  "includeVenv": true,
  "count": 6,
  "projects": [
    {
      "project": "@jupyter-widgets/jupyterlab-manager",
      "version": "5.0.15",
      "path": "C:\\projects\\projectX\\.venv\\share\\jupyter\\labextensions\\@jupyter-widgets\\jupyterlab-manager",
      "dependencies": 40,
      "hasLockfile": false
    },
    ...
    {
      "project": "jupyterlab-plotly",
      "version": "6.0.1",
      "path": "C:\\projects\\projectY\\.venv\\share\\jupyter\\labextensions\\jupyterlab-plotly",
      "dependencies": 7,
      "hasLockfile": false
    },
    {
      "project": "sample-nodejs-project",
      "version": "1.0.0",
      "path": "C:\\projects\\sample-nodejs-project",
      "dependencies": 2,
      "hasLockfile": true
    }
  ]
}