Next.js package
One route in your app lets CheckRoost check the packages it actually has deployed against published vulnerabilities.
@checkroost/next adds a route to your app that answers CheckRoost’s application health check with the Node, Next.js and React versions it runs and the exact version of every package it ships. CheckRoost checks those against OSV.dev every hour and lists anything affected, with the release that fixes it.
This is a change to your app's code, not to the server
package.json, on the computer where you work on it. You commit the change and deploy the way you always do. The only thing that goes on the server by hand is the token, in step 5. Running npm install on the server does nothing: the app never sees a package installed outside its own project.What it reports, and what it does not
- Reports: the Node, Next.js and React versions, and the name and version of every production package in the app’s lockfile. Development tools are left out.
- Never: the environment, any file’s contents, or a path on the server.
- Sends nothing. CheckRoost asks; the route answers, and only to a request carrying your token. With no token set it answers 503 to everybody. It is never cacheable.
Setting it up
Step 1. Add the package, in the app’s project folder
cd path/to/your-appnpm install @checkroost/nextStep 2. Add the route
Create
app/api/checkroost/route.ts(orsrc/app/api/checkroost/route.ts):export { GET } from '@checkroost/next'export const dynamic = 'force-dynamic'Step 3. Let it past your proxy or middleware
If your app has a
proxy.tsormiddleware.tsthat sends signed-out visitors to a login page, or moves requests between hostnames, the health check will be caught by it — it carries a token, never a session. Addapi/checkroostto the paths its matcher skips:export const config = { matcher: ['/((?!_next/static|_next/image|api/checkroost|favicon.ico).*)'],}Step 4. If you build with output: ‘standalone’, include the lockfile
A standalone build copies only the files the app imports, and the lockfile is not one of them. One line in
next.config.tsputs it in the build:output: 'standalone',outputFileTracingIncludes: { '/api/checkroost': ['./package-lock.json'] },Use
./pnpm-lock.yamlfor pnpm. An app run withnext startfrom its project folder already has its lockfile and needs nothing here.Step 5. Put a token on the server
Make one — a random string of at least 32 characters — and keep it to hand for step 7:
openssl rand -hex 32Add it to the app’s environment on the server as
CHECKROOST_TOKEN=…: the.envfile orEnvironmentFileits service reads, or your host’s environment variables screen. Never commit it.Step 6. Commit and deploy as usual
The app starts answering at/api/checkroost. It reads the token when it starts, so if you add the token after deploying, restart the app.Step 7. Turn on the health check
In CheckRoost, open the site’s monitor, choose Edit, and turn on Application health with the addresshttps://your-app/api/checkroostand a header namedX-CheckRoost-Tokenholding the same token. The first reading arrives within five minutes, and its packages are matched within the hour.
Checking it from outside
Ask for the route with no token, from anywhere:
curl -i https://your-app/api/checkroost403Working: it is deployed, the token is set, and it refused you because you sent none. This is the answer you want.503Deployed, but CHECKROOST_TOKEN is not set where the app can read it — or it was added without restarting the app.404The route is not in the deployed app. Check the file is at app/api/checkroost/route.ts and that the deploy carried it.- A redirect, or your login page Your proxy or middleware is catching it — step 3.
On the monitor, a reading that names no packages means the app could not find its lockfile — step 4. A reading that fails with HTTP 403 means the header on the monitor does not match CHECKROOST_TOKEN on the server.
Can't change the app, or deploy without a lockfile?