# Audit Open Source Licenses in a Next.js Project

Yes. An agent resolves your Next.js lockfile in a sandbox and writes licenses.csv plus licenses.md flagging GPL, AGPL, LGPL, SSPL or unknown licenses.

[Run this on Rush](https://cloud.getrush.ai/run/license-audit/nextjs/).

## What the agent does

The agent clones the app into its sandbox. On a repository like nextjs/saas-starter it reads `package.json`: `next` at `15.6.0-canary.59`, `react` and `react-dom` at `19.1.0`, `drizzle-orm` `^0.43.1`, `drizzle-kit` `^0.31.1`, `stripe` `^18.1.0`, `zod` `^3.24.4`, `postgres` `^3.4.5`, Tailwind 4 (`tailwindcss` `4.1.7`), and scripts for `dev`, `build`, `start` and `db:*` with no `test` or `lint` script. The lockfile is `pnpm-lock.yaml` at `lockfileVersion: '9.0'` (about 3.8k lines) with no `packageManager` field in `package.json`. App code lives under `app/` and `lib/` (`lib/db/schema.ts`, `lib/auth`, `lib/payments/stripe.ts`).

It installs with `pnpm install --frozen-lockfile` so the tree matches the lockfile, then inventories every package in the virtual store: name, version, license from `package.json` or LICENSE, whether it is a direct dependency / devDependency from the root `package.json` or only transitive, and a dependency path from a top-level package (pnpm why / the lockfile importer graph).

Because the lockfile pins canary Next.js and React 19, the inventory includes whatever those packages declare transitively (compiler helpers, SWC bindings, scheduler). Stripe and Drizzle trees are expanded the same way. The agent records the license SPDX id when `package.json` has one, and falls back to reading a LICENSE file in the package directory when the field is missing or is only `SEE LICENSE IN …`.

From that inventory it writes `licenses.csv` and a short `licenses.md` that lists GPL, AGPL, LGPL, SSPL and unknown licenses only, each with the top-level package that pulls it in (for example a transitive of `next`, `stripe` or `drizzle-orm`). Packages with `UNLICENSED` or missing license fields are flagged as unknown. The starter's own `LICENSE` file is noted separately from dependency licenses.

The agent does not change `package.json`, does not open a pull request and does not run `next build` unless a license tool requires node_modules to be complete after install. Deliverables are the two report files as artifacts. Dev-only tools that appear in the lockfile but not in the starter's `package.json` dependencies block are still listed when pnpm materializes them for the frozen install.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Clone https://github.com/nextjs/saas-starter, resolve its full dependency tree from the lockfile, and write licenses.csv (package, version, license, direct or transitive, path from the root) plus licenses.md summarizing any GPL, AGPL, LGPL, SSPL or unknown license and which top-level dependency brings it in."
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is `licenses.csv` and `licenses.md` on the session. The CSV is the full pnpm tree; the Markdown is the exception list with the direct dependency responsible for each flagged license.

A reviewer filters the CSV for copyleft and unknown rows before a customer contract review or a release. The transcript shows the frozen install and the license scan, so disputed packages can be reopened in the same sandbox with a follow-up message.

## Run it on every Dependabot or Renovate pull request

When a dependency PR opens, start this run against the PR ref. The new CSV shows whether the bump introduced a flagged license before anyone merges.

On `run.completed`, comment on the PR with a link to `licenses.md` when the flagged section is non-empty so license review is part of the same checklist as tests.

## Why run it on Rush?

A Next.js license audit on a laptop means installing a large pnpm store just to read SPDX fields, then trying not to confuse it with your other apps' node_modules. Rush keeps that install inside one sandbox and returns portable CSV and Markdown.

You can run the same audit across many apps at once, each with its own lockfile and artifact, without tying up your machine or mixing lockfile majors.

## Frequently asked questions

### Does it work with npm or Yarn lockfiles?

Yes. The agent picks the lockfile present (`pnpm-lock.yaml`, `package-lock.json`, `yarn.lock` or `bun.lock`) and uses that package manager for a frozen install. SaaS Starter happens to ship pnpm.

### Are optional and peer dependencies included?

Whatever the frozen install materializes is listed. Peers that were not installed are omitted; the report can note peer warnings from the install log when they appear.

### Will it upgrade packages to fix a license?

No. This job only reports. A follow-up prompt on the same session can ask for a PR that replaces a flagged package after you choose the replacement.

### What about the Next.js canary release?

It is inventoried like any other package: name `next`, version `15.6.0-canary.59`, license from that package's metadata. Canary versus stable does not change how licenses are read.

### Is the canary Next.js license different from stable?

Usually both are MIT from Vercel, but the agent reads the installed package's metadata rather than assuming. If a canary build ever shipped with a different notice, the CSV would show that version's field.
