Package Exports
- nostics
- nostics/formatters/ansi
- nostics/formatters/json
- nostics/package.json
- nostics/reporters/dev
- nostics/reporters/fetch
- nostics/reporters/node
- nostics/unplugin
Readme
nostics
Errors and warnings your users (and their agents) can actually act on.
Every diagnostic is a typed, structured object with a stable code, a clear explanation, a suggested fix, and a docs link. No more grepping log output or guessing what an error means.
[NUXT_B2011] Invalid plugin `/plugins/bad.ts`. src option is required.
├▶ fix: Pass a string path or an object with a `src` property to `addPlugin()`.
├▶ sources: /Users/me/projects/my-nuxt-app/nuxt.config.ts:14:3
╰▶ see: https://nuxt.com/e/b2011Why
Library errors today are strings. Users scan them, agents pattern-match them, and everyone loses context. nostics turns each diagnostic into a Diagnostic instance: stable code, human why, actionable fix, structured sources, and a per-code docs URL. Humans get a searchable code and a fix in the same glance. Agents get machine-readable fields to dispatch on, instead of regexing message text.
Quick start
import { defineDiagnostics, reporterLog } from 'nostics'
const diagnostics = defineDiagnostics({
docsBase: 'https://nuxt.com/e',
reporters: [reporterLog],
codes: {
NUXT_B2011: {
why: (p: { src: string }) => `Invalid plugin \`${p.src}\`. src option is required.`,
fix: 'Pass a string path or an object with a `src` property to `addPlugin()`.',
},
},
})
// Report (continues execution) or throw — both are fully typed.
diagnostics.NUXT_B2011({ src: pluginPath })
throw diagnostics.NUXT_B2011({ src: pluginPath })That's it. diagnostics.NUXT_B2011 is cmd+clickable, TypeScript checks params at the call site, and the result extends Error, so it works anywhere an Error does.
Dev reporter: pipe browser diagnostics to a file
Browser diagnostics are invisible to terminal-bound agents. The dev reporter fixes that: it forwards each diagnostic over Vite's HMR channel to a server-side plugin, which appends them to a log file your agent can tail. The Claude Code plugin sets this up automatically.
// src/diagnostics.ts
import { defineDiagnostics, reporterLog } from 'nostics'
import { devReporter } from 'nostics/reporters/dev'
export const diagnostics = defineDiagnostics({
reporters: [reporterLog, devReporter],
codes: {
/* ... */
},
})import { nosticsServer } from 'nostics/unplugin'
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
nosticsServer.vite({
logFile: '.nostics.log', // default: .nostics.log
}),
],
})Now every diagnostic call in the browser is appended to .nostics.log as it happens. reporterLog still prints to the browser console. devReporter runs alongside it, not as a replacement.
Features
- Organized, stable codes. cmd+click to jump to your organized diagnostics definitions
- Structured
Diagnosticinstances. ExtendError, serialize viatoJSON(), survive process boundaries - Pluggable reporters. Console, file, HTTP, dev (Vite HMR), or your own
- Pluggable formatters. Plain text, ANSI colors, JSON
- Zero runtime dependencies
Claude Code plugin
Includes a Claude Code plugin so agents learn the API automatically: an auto-loaded reference skill and a /add-diagnostic command for scaffolding new codes.
gh api repos/vercel-labs/nostics/contents/install.sh --jq '.content' | base64 -d | bash