Skip to main content

CleanLibrary JavaScript SDK

@cleanstart/cleanlib-sdk is the JavaScript / TypeScript client library for CleanLibrary. It wraps the same HTTP surface that powers the CLI, the MCP server, and the VS Code extension behind a small, typed API you can drop into any Node.js or browser-side program.

1. What it does​

The JavaScript SDK answers the same package-manager-layer questions as the CLI, but from inside a JS / TS program rather than from a shell:

  1. Is this version safe to install? — client.fetchVerdict(...)
  2. What does my policy do with this package? — client.policyPreview(...)
  3. Should I accept the risk on this finding? — client.riskAccept(...)

The wire contract is identical to every other CleanLibrary client. A verdict returned by the JavaScript SDK has the same shape as a verdict returned by the CLI or the MCP server, so you can mix-and-match clients within one workflow.

2. Install​

npm install @cleanstart/cleanlib-sdk

pnpm / yarn users:

pnpm add @cleanstart/cleanlib-sdk
yarn add @cleanstart/cleanlib-sdk

The SDK ships as ESM + CJS dual-package and includes TypeScript types. It targets Node.js 18+ and modern browsers; it has no native dependencies.

3. Quickstart​

import { HttpVerdictClient } from "@cleanstart/cleanlib-sdk";

const client = new HttpVerdictClient("https://cleanapp.clnstrt.dev", {
apiKey: process.env.CLEANLIB_API_KEY!,
});

const verdict = await client.fetchVerdict("npm", "lodash", "4.17.21");

console.log(`verdict_id: ${verdict.verdict_id}`);
console.log(`severity: ${verdict.severity}`);
console.log(`source: ${verdict.source}`);

Output:

verdict_id: <stable-identifier>
severity: NONE
source: ALLOWED_NO_FINDINGS

4. Configuration​

The HttpVerdictClient constructor accepts an endpoint positional argument plus an options object:

OptionPurposeDefault
apiKeyBearer token (typically from CLEANLIB_API_KEY env var); alias: bearer(required)
apiVersionAPI version path segment"v1"
timeoutMsPer-request timeout in milliseconds30_000
fetchOptional fetch implementation override (for testing or custom transports)global fetch

The convention for production deployments is to read endpoint and apiKey from environment variables and let everything else default:

const client = new HttpVerdictClient(process.env.CLEANLIB_ENDPOINT!, {
apiKey: process.env.CLEANLIB_API_KEY!,
});

5. API reference​

client.fetchVerdict(ecosystem, package, version) -> Promise<Verdict>​

Returns a verdict for a single (ecosystem, package, version) tuple. The Verdict shape conforms to VerdictEnvelopeV1Schema and carries the verdict identifier, severity, source label, freshness fields, and remediation hints.

interface Verdict {
verdict_id: string; // stable identifier for this decision
source: string; // ALLOWED_NO_FINDINGS | VECTOR_VERDICT | DM_THRESHOLD_BLOCK | INSUFFICIENT_DATA
severity: string; // NONE | LOW | MEDIUM | HIGH | CRITICAL
composite_score: number; // 0-100 confidence in the decision
reasoning: string;
suggested_actions: string[];
// Plus freshness, similar_to, evidence_gaps, attestation, and rich-data fields
}

client.scan(packages) -> Promise<ScanResponse>​

Scans a list of package references in one round-trip and returns a ScanResponse containing a verdict per package. Suitable for CI pipelines or admission controllers that need a single round-trip.

client.policyPreview(policyYaml, packages) -> Promise<PolicyPreviewResponse>​

Returns what your candidate policy would decide for the given packages, with the matching policy rule attached. Useful for "if I add this rule, will it break my CI?" checks.

client.riskAccept(verdictId, justification) -> Promise<RiskAcceptResponse>​

Records a customer-side risk-acceptance against a specific verdict.

client.audit(window) -> Promise<AuditWindowResponse>​

Returns the customer-side audit log for a time window.

client.fetchBytes(ecosystem, package, version) -> Promise<Uint8Array>​

Returns the verified upstream bytes for an (ecosystem, package, version) tuple.

deriveStatus(source, severity) -> Status​

Helper function exposed at the top of the package that derives a renderable status from a verdict's source and severity fields — useful for clients that build their own UI without going through the underlying enrichment client.

5a. Other clients in the package​

The package also exports specialized clients for the supporting surfaces:

import { HttpEnrichClient, HttpRemediationClient } from "@cleanstart/cleanlib-sdk";
  • HttpEnrichClient — vulnerability-intelligence and EPSS/KEV lookups for known CVEs
  • HttpRemediationClient — upgrade-path search for a vulnerable package

Use HttpVerdictClient for the verdict surface (most customers); the enrichment and remediation clients sit alongside it for richer flows.

6. Error handling​

The SDK throws typed errors for known failure modes. Common error classes:

ClassWhen it throws
CleanlibErrorBase class for all SDK errors
HttpErrorNon-2xx HTTP response surfaced as a structured error
VerdictNotFoundErrorThe catalog has no verdict for this (ecosystem, package, version) yet
TransportErrorNetwork, DNS, or TLS failure — wraps the underlying fetch error

A verdict is not thrown — it's a successful response with a verdict-aware shape. Use the verdict's severity and source to drive flow control, not try / catch.

7. CI integration​

Drop the SDK into a build step and exit non-zero on a denied verdict:

// scripts/precheck.ts
import { HttpVerdictClient, VerdictNotFoundError } from "@cleanstart/cleanlib-sdk";

const client = new HttpVerdictClient(process.env.CLEANLIB_ENDPOINT!, {
apiKey: process.env.CLEANLIB_API_KEY!,
});

try {
const v = await client.fetchVerdict("npm", "lodash", "4.17.21");
if (v.source === "DM_THRESHOLD_BLOCK") {
console.error(`BLOCKED: npm/lodash@4.17.21 — ${v.reasoning}`);
process.exit(1);
}
} catch (e) {
if (e instanceof VerdictNotFoundError) {
console.error("BLOCKED: no verdict on file for this version yet");
process.exit(2);
}
throw e;
}

For multi-package scans, prefer client.scan(...) over a loop of client.fetchVerdict(...) calls — one round-trip is cheaper than N.

8. Versioning​

The SDK follows Semantic Versioning. The verdict envelope wire contract is stable across the v0.4 series — clients can mix v0.4.0 and v0.4.4 against the same backend without coordination.

v0.4.x envelopes are byte-identical with the Python, Go, and Rust SDKs against the same backend version — verdicts produced by each SDK derive the same status for the same (ecosystem, package, version) tuple.

9. Where to go next​

  • CLI — the same verdicts and remediation surface from the terminal, for ad-hoc queries and CI gates
  • MCP Server — surface CleanLibrary inside any MCP-compatible AI coding agent
  • SDK — Go — Go programmatic access to the same verdict surface
  • SDK — Python — Python programmatic access
  • SDK — Rust — Rust programmatic access
  • Integration Surfaces — the full integration matrix (admission, CI, IDE, agent)
  • Architecture — how CleanLibrary's verdict-and-enrichment surface composes end to end