Automating Dependency Audits for npm and NuGet Projects

Managing third-party dependencies across large projects can get messy. Tools like npm, dotnet, and license-checker give you great diagnostics, but their JSON outputs aren't exactly easy to share with a compliance team, non-technical stakeholders, or Excel-centric auditors.

coding laptop

Recently, I needed to:

  • Run multiple CLI tools across JavaScript and .NET projects
  • Capture things like outdated packages, licenses, and vulnerabilities
  • Convert all the output into clean, timestamped CSV files
  • Automate the entire process via PowerShell

Here’s how I tackled it and how you can too.

The Goal

I needed to process the following CLI outputs:

ToolCommandFormat
npmnpm outdated --jsonJSON
npmnpm audit --jsonJSON
license-checkerlicense-checker --csvCSV
dotnetnuget-license -i <sln> -o jsonPretty JSON
dotnetdotnet list <sln> package --vulnerable --format jsonJSON
dotnetdotnet list <sln> package --outdated --format jsonJSON

In my case, I needed the output to be in a structured CSV format with only the relevant fields.

The Problem with JSON

While JSON is great for APIs and machines, it’s:

  • Unfriendly for manual review
  • A pain to open in Excel unless you know how to wrangle it
  • Not what the stakeholders wanted

The Solution: json-to-csv-helper.js

I've seen a lot of different versions of "JSON to CSV" tools out there. They work, I tried them, but the output is very generic which left the output files looking pretty messy, still hard to read and with data I didn't necessarily need on the final CSV.

Instead of writing a bunch of one-off parsers for each of the different reports I had, I created one single Node.js script that can handle all the above formats. It takes in JSON via stdin, and outputs a clean CSV to stdout (or to a file if you give it a path).

npm audit --json | node json-to-csv-helper.js npm-audit > audit.csv #(or without "> audit.csv" to send back to stdout)
nuget-license -i My.sln -o jsonPretty | node json-to-csv-helper.js nuget-licenses"
dotnet list My.sln package --outdated --include-transitive --format json | node json-to-csv-helper.js nuget-outdated

It supports five modes:

  • npm-outdated
  • npm-audit
  • nuget-licenses
  • nuget-outdated
  • nuget-vulnerable

Each mode maps to a predefined flattening function and CSV schema.

You can find the scripts and documentation here: 3rd Party Library Reports

Automation with PowerShell

It really didn't make sense to run these reports one by one, so the next step was wrapping them in a script that would orchestrate running the reports one after another. We work in a Windows environment, portability to other systems was not a requirement, so PowerShell made the most sense.

The script:

  • Defines which reports to run
  • Verifies if needed tools are installed
  • Resolves relative project paths
  • Runs each command, pipes it through the JSON-to-CSV helper when needed (if extension is configured to ".csv")
  • Writes a timestamped CSV to a target folder

Example usage:

# Output saves to configurable folder name
.\third-party-reports.ps1

Each report is saved as:

npm_audit_20250521_142300.csv
nuget_licenses_20250521_142301.csv

Example folder structure:

project-root/
├── json-to-csv-helper.js
├── third-party-reports.ps1
├── src/
│   ├── MyNpmProject/
│   └── MySolution/
└── OutputReports/
    └── npm_audit_20250521_142300.csv

Why This Pattern Works

  • Extensible - Adding a new format is just one new mode inside the json-to-csv-helper.js
  • Flexible - Output can be changed to just JSON as well if there is a need to analyze output (for instance, to create alerts)
  • Separation of concerns - Node handles parsing, PowerShell manages orchestration
  • Portable - You can schedule this via CI/CD, cron or run it ad hoc in the terminal

Bonus Tips

  • Depending on the environment and tooling, this can be rewritten in Python:
    • Handles orchestration with subprocess.run() to run tools like npm, dotnet, etc.
    • The json module handles the output parser
    • Python's built in csv.DictWriter takes care of the CSV output
    • Works on macOS, Linux and Windows
  • Plug in to CI pipelines like Github Actions or Azure Devops for further automation
  • Use the CSV output to feed Power BI dashboards or share with stakeholders

Conclusion

If you're juggling multiple package managers and trying to extract license, security, or version insights across a polyglot codebase, standardizing your report generation via a single JSON-to-CSV pipeline is a flexible and maintainable approach.

Let the CLI tools give you JSON. Let the helper turn that into CSV. Let PowerShell glue it all together.

Hope this helps!