derrick-torkornoo/uws-boost · v1.0.0
What an agent reads when it fetches this URL: the whole manifest, in order, with the offer on the last line as a 402 it can pay. Nothing here is a button — an agent does not click, it signs. The page a person reads is here.
Pack · 42 source files · 63 test files · 19 examples · 4 docs · 3 CI files · 5 config files · 2 assets · 1 other file · 139 files · text 585 kB · binary 491 B (0%) · TypeScript 100% · JavaScript 0% · MIT, resale permitted
scan passed 2026-11-02 · scanner 2026.10.1 · 1 release · last release 5 days ago · 0% of files seen elsewhere
computed 2026-11-02 09:34 UTC · analyzer 0.1.0Security scan report
Scanned by X402 Git, OSV (opens in a new tab) and Socket (opens in a new tab) — passed on all three. Findings from all three are listed below.
- secrets
- none found
- X402 Git
- size limits
- within caps
- X402 Git
- known malware
- none in 317 packages
- OSV
- known vulnerabilities
- 1 moderate, 1 low in 317 packages — see below
- OSV
- dependency behaviour
- 8 direct packages declare network access, filesystem access, environment variables and more · 451 more in transitive packages · 28 packages flagged for review
- Socket
- instruction smuggling
- none found
- X402 Git
- what it can do
- listed below
- X402 Git
What this can do
- Tools
- none
- Runs
- .github/workflows/ci.yml (push, pull_request, workflow_dispatch)
- .github/workflows/release.yml (push)
- Talks to
- 127.0.0.1 (local)
- a
- a.com
- allowed.com
- app.akwaabahr.com
- app.com
- app.example.com
- b.com
- eslint.org
- evil.com
- example.com
- facial.akwaabahr.com
- foo.com
- github.com
- given.example.com
- header.example.com
- localhost (local)
- localhost:3000 (local)
- localhost:3009 (local)
- localhost:3010 (local)
- localhost:5173 (local)
- opencollective.com
- paulmillr.com
- registry.npmjs.org
- tidelift.com
- x.com
- Reads
- COMPOSE_FILE
- COOKIE_SECRET
- GH_TOKEN
- GITHUB_REF_NAME
- GITHUB_TOKEN
- OLD_COOKIE_SECRET
- PORT
- TEMP_DIR
- At install
- nothing runs
- Links to
- app.example.com
- github.com
- keepachangelog.com
- localhost:3000
- semver.org
- www.conventionalcommits.org
Findings (147)
- MODERATEminimatch 10.2.6 — minimatch@10.2.6 (npm): minimatch has potential denial of service via globparts amplification GHSA-g3hv-75wg-m249 CVE-2026-118764
- flagged for reviewload-tsconfig 0.2.5 (dev only) — load-tsconfig 0.2.5 (transitive, dev only) — flagged for review by Socket's classifier as a security risk
- flagged for reviewload-tsconfig 0.2.5 (dev only) — load-tsconfig 0.2.5 (transitive, dev only) — flagged for review by Socket's classifier as a security risk
- MODERATEesbuild 0.27.7 (dev only) — esbuild 0.27.7 (transitive, dev only) — install scripts run when installed
- MODERATEvitest 5.0.5 (dev only) — vitest 5.0.5 (direct, dev only) — makes network requests at runtime
- flagged for reviewes-module-lexer 2.3.2 (dev only) — es-module-lexer 2.3.2 (transitive, dev only) — flagged for review as a possible vulnerability
- MODERATEtsup 8.5.1 (dev only) — tsup 8.5.1 (direct, dev only) — evaluates code at runtime
- MODERATEvitest 5.0.5 (dev only) — vitest 5.0.5 (direct, dev only) — evaluates code at runtime
- MODERATE.github/workflows/ci.yml — A GitHub Actions workflow runs on push, pull_request, workflow_dispatch
- MODERATE.github/workflows/release.yml — A GitHub Actions workflow runs on push
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — can attach a debugger
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — can attach a debugger
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — can attach a debugger
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — can attach a debugger
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — can attach a debugger
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — can attach a debugger
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — deprecated by its author
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — loads modules by a computed name
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — loads modules by a computed name
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — loads modules by a computed name
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — loads modules by a computed name
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — loads modules by a computed name
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — loads modules by a computed name
- LOW.github/workflows/ci.yml — Reads the environment variable COMPOSE_FILE
- LOWREADME.md — Reads the environment variable COOKIE_SECRET
- LOW.github/workflows/release.yml — Reads the environment variable GH_TOKEN
- LOW.github/workflows/release.yml — Reads the environment variable GITHUB_REF_NAME
- LOW.github/workflows/release.yml — Reads the environment variable GITHUB_TOKEN
- LOWREADME.md — Reads the environment variable OLD_COOKIE_SECRET
- LOWexamples/docker/docker-compose.yml — Reads the environment variable PORT
- LOWexamples/env.ts — Reads the environment variable TEMP_DIR
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads environment variables
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads environment variables
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads environment variables
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads environment variables
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads environment variables
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads environment variables
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads environment variables
- LOWeslint-config-prettier 10.1.8 (dev only) — eslint-config-prettier 10.1.8 (direct, dev only) — reads environment variables
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — reads environment variables
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — reads environment variables
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — reads environment variables
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — reads environment variables
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — reads environment variables
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — reads environment variables
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — reads environment variables
- LOWvitest 5.0.5 (dev only) — vitest 5.0.5 (direct, dev only) — reads environment variables
- LOWvitest 5.0.5 (dev only) — vitest 5.0.5 (direct, dev only) — reads environment variables
- LOWvitest 5.0.5 (dev only) — vitest 5.0.5 (direct, dev only) — reads environment variables
- LOWvitest 5.0.5 (dev only) — vitest 5.0.5 (direct, dev only) — reads environment variables
- LOW@vitest/coverage-istanbul 5.0.5 (dev only) — @vitest/coverage-istanbul 5.0.5 (direct, dev only) — reads or writes files
- LOW@vitest/coverage-istanbul 5.0.5 (dev only) — @vitest/coverage-istanbul 5.0.5 (direct, dev only) — reads or writes files
- LOW@vitest/coverage-istanbul 5.0.5 (dev only) — @vitest/coverage-istanbul 5.0.5 (direct, dev only) — reads or writes files
- LOW@vitest/coverage-istanbul 5.0.5 (dev only) — @vitest/coverage-istanbul 5.0.5 (direct, dev only) — reads or writes files
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads or writes files
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads or writes files
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads or writes files
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads or writes files
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads or writes files
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads or writes files
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads or writes files
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads or writes files
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — reads or writes files
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — reads or writes files
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — reads or writes files
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — reads or writes files
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — reads or writes files
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — reads or writes files
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — reads or writes files
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — reads or writes files
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — reads or writes files
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — reads or writes files
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — reads or writes files
- LOWtsup 8.5.1 (dev only) — tsup 8.5.1 (direct, dev only) — reads or writes files
- LOWtsup 8.5.1 (dev only) — tsup 8.5.1 (direct, dev only) — reads or writes files
- LOWtsup 8.5.1 (dev only) — tsup 8.5.1 (direct, dev only) — reads or writes files
- LOWesbuild 0.27.7 — esbuild@0.27.7 (npm): esbuild allows arbitrary file read when running the development server on Windows GHSA-g7r4-m6w7-qqqr
- flagged for reviewprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — flagged for review by Socket's classifier as anomalous
- flagged for reviewts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — flagged for review by Socket's classifier as anomalous
- flagged for reviewts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — flagged for review by Socket's classifier as anomalous
- flagged for reviewtsup 8.5.1 (dev only) — tsup 8.5.1 (direct, dev only) — flagged for review by Socket's classifier as anomalous
- flagged for reviewtsup 8.5.1 (dev only) — tsup 8.5.1 (direct, dev only) — flagged for review by Socket's classifier as anomalous
- LOWtests/multipart/parsing.test.ts — Talks to a
- LOWtests/cors/preflight.test.ts — Talks to a.com
- LOWtests/responder/createResponder.test.ts — Talks to allowed.com
- LOWexamples/cors-variant.ts — Talks to app.akwaabahr.com
- LOWtests/cors/registerGlobalCors.test.ts — Talks to app.com
- LOWtests/responder/asyncSafety.test.ts — Talks to app.example.com
- LOWtests/cors/preflight.test.ts — Talks to b.com
- LOWpackage-lock.json — Talks to eslint.org
- LOWtests/cors/createCors.test.ts — Talks to evil.com
- LOWtests/responder/moreResponses.test.ts — Talks to example.com
- LOWtests/cors/createCors.test.ts — Talks to facial.akwaabahr.com
- LOWtests/responder/createResponder.test.ts — Talks to foo.com
- LOWpackage-lock.json — Talks to github.com
- LOWtests/responder/asyncSafety.test.ts — Talks to given.example.com
- LOWtests/responder/asyncSafety.test.ts — Talks to header.example.com
- LOWpackage-lock.json — Talks to opencollective.com
- LOWpackage-lock.json — Talks to paulmillr.com
- LOWpackage-lock.json — Talks to registry.npmjs.org
- LOWpackage-lock.json — Talks to tidelift.com
- LOWtests/integration/responder.int.test.ts — Talks to x.com
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — ships minified code with no source
- LOWconvert-source-map 2.0.0 (dev only) — convert-source-map 2.0.0 (transitive, dev only) — published by an author new to this package
- LOWeslint 9.39.5 (dev only) — eslint 9.39.5 (direct, dev only) — contains hard-coded URLs
- LOWeslint-config-prettier 10.1.8 (dev only) — eslint-config-prettier 10.1.8 (direct, dev only) — contains hard-coded URLs
- LOWprettier 3.9.10 (dev only) — prettier 3.9.10 (direct, dev only) — contains hard-coded URLs
- LOWts-node 10.9.2 (dev only) — ts-node 10.9.2 (direct, dev only) — contains hard-coded URLs
- LOWtsup 8.5.1 (dev only) — tsup 8.5.1 (direct, dev only) — contains hard-coded URLs
- LOWtypescript-eslint 8.72.1 (dev only) — typescript-eslint 8.72.1 (direct, dev only) — contains hard-coded URLs
- LOWvitest 5.0.5 (dev only) — vitest 5.0.5 (direct, dev only) — contains hard-coded URLs
- flagged for reviewgptDidYouMean — 2 transitive packages, e.g. obug@2.2.1, obug@3.0.0
- flagged for reviewgptAnomaly — 18 transitive packages, e.g. @cspotcode/source-map-support@0.8.1, ajv@6.15.0, any-promise@1.3.0
- MODERATEshellAccess — 10 transitive packages, e.g. commander@4.1.1, cross-spawn@7.0.6, detect-libc@2.1.2
- MODERATEusesEval — 5 transitive packages, e.g. @babel/traverse@8.0.10, ajv@6.15.0, lodash.merge@4.6.2
- MODERATEnetworkAccess — 3 transitive packages, e.g. esbuild@0.27.7, mz@2.7.0, rollup@4.66.0
- LOWunmaintained — 40 transitive packages, e.g. acorn-jsx@5.3.2, any-promise@1.3.0, create-require@1.1.1
- LOWfilesystemAccess — 38 transitive packages, e.g. @cspotcode/source-map-support@0.8.1, @eslint/eslintrc@3.3.7, argparse@2.0.1
- LOWenvVars — 29 transitive packages, e.g. @babel/core@8.0.10, @babel/helper-compilation-targets@8.0.7, minimatch@10.2.6
- LOWurlStrings — 25 transitive packages, e.g. @babel/core@8.0.10, @babel/helpers@8.0.10, @eslint/eslintrc@3.3.7
- LOWdebugAccess — 16 transitive packages, e.g. @eslint/eslintrc@3.3.7, @humanwhocodes/module-importer@1.0.1, bundle-require@5.1.0
- LOWdynamicRequire — 10 transitive packages, e.g. @cspotcode/source-map-support@0.8.1, browserslist@4.29.5, esbuild@0.27.7
- LOWminifiedFile — 6 transitive packages, e.g. baseline-browser-mapping@2.11.34, confbox@0.1.8, es-module-lexer@2.3.2
Description self_reported
Written by the creator. Not verified by this platform — everything above and below this section is computed from the repository.
Zero-dependency, high-performance HTTP toolkit and router for uWebSockets.js with native TypeScript support, validation, and request parsing.
When to use it. When building lightning-fast Node.js microservices or APIs requiring maximum throughput and minimal overhead.
Readme
uws-akwaaba
Project type: TypeScript library, published as an npm package that you import into your own uWebSockets.js server. Runnable example servers live in
examples/.
A lightweight, dependency-free web framework and toolkit for building HTTP APIs on uWebSockets.js:
- a router with Koa-style middleware, params, typed query access and central error handling
- response helpers (
json,text,html,send,redirect,empty,error) with compression and ETags - body readers for JSON (with schema validation), text, urlencoded and raw bytes, readable even after
await - a streaming multipart/form-data parser (memory, disk or spill-over) with size, count and type limits
- static files with ETag/304, byte ranges, HEAD and backpressure-aware streaming
- authentication (bearer, API key, session + CSRF, roles and scopes), rate limiting, CSRF middleware
- CORS, cookies (including HMAC-signed values), security headers
- request ids and structured access logs, graceful shutdown, JSON WebSockets
- typed HTTP errors that map straight to responses
uWS is fast because it is low-level: the request object dies as soon as your handler returns or awaits, the body is lost unless you subscribe to it immediately, aborted responses must never be written, and the status line must come before every header. This library handles those rules for you, and its test suite checks them against a real uWS server.
Install
npm install uws-akwaaba uNetworking/uWebSockets.js#v20.52.0
uWebSockets.js is a peer dependency. Node.js 20 or newer is required (uWebSockets.js v20.52 ships no Node 18 binary). uWebSockets.js ships glibc builds only, so Alpine (musl) based environments are not supported.
Quick start
import uWS from "uWebSockets.js";
import pino from "pino";
import { createRouter, authenticate, bearerAuth, readJson, HttpError, structuredLogger } from "uws-akwaaba";
const app = uWS.App();
const logger = pino();
const api = createRouter(app, {
prefix: "/api",
compress: true,
// one JSON line per request: id, method, url, status, durationMs, bytes
requestLog: { log: structuredLogger(logger) },
// unexpected errors (not 4xx HttpErrors), e.g. for Sentry.captureException
onException: (err, ctx) => logger.error({ err, route: ctx.route, requestId: ctx.state.requestId }),
});
api.get("/users/:id", async (ctx) => {
const user = await db.findUser(ctx.params.id);
if (!user) throw new HttpError(404, "No such user");
ctx.respond.json(user, { etag: true });
});
api.post("/users", authenticate({ strategies: [bearerAuth({ verify: verifyJwt })] }), async (ctx) => {
// The body is captured at request start, so reading it after awaits is fine.
const input = await readJson(ctx.res, ctx.req, { validate: (v) => UserSchema.parse(v) });
ctx.respond.json(await db.createUser(input), { status: 201 });
});
app.listen(3000, (token) => token && logger.info({ port: 3000 }, "listening"));
Errors thrown anywhere in the chain are rendered for you: an HttpError (or a body reader's 400/413/415/422) becomes its status and a JSON body; anything else becomes a 500 without leaking the message. A route that finishes without responding gets a 404.
Prefer plain uWS handlers? Every helper also works without the router; see Without the router.
examples/router-app.ts (npm run dev:example-router) is a complete small API using most of the features below.
Modules
Each module is its own build entry, so importing a subpath pulls in only that code.
| Import path | What it provides |
|---|---|
uws-akwaaba | everything below |
uws-akwaaba/router | createRouter, compose, timeout, authenticate, limit, csrf |
uws-akwaaba/responder | createResponder, withResponder, withSafeResponder |
uws-akwaaba/body | readJson, readText, readUrlencoded, readBuffer, readRawBody, parseUrlencoded, decodeText |
uws-akwaaba/multipart | parseMultipart, parseContentDisposition, getBoundary |
uws-akwaaba/static | serveStatic, resolveSafePath |
uws-akwaaba/auth-register | registerGlobalAuth, bearerAuth, apiKeyAuth, sessionAuth, getAuth, TinyTTLCache |
uws-akwaaba/rate-limit | rateLimit, createRateLimiter, MemoryRateLimitStore |
uws-akwaaba/cors | createCors(config) → { applyHeaders, preflight } |
uws-akwaaba/cors-register | registerGlobalCors(app, config, opts) |
uws-akwaaba/cookies | parseCookieHeader, serializeCookie, buildCookieHeaders, clearCookie, createCookieSigner |
uws-akwaaba/security-headers | securityHeaders(opts) |
uws-akwaaba/request-log | withRequestLog, getRequestId, jsonLineLogger |
uws-akwaaba/lifecycle | createLifecycle (graceful shutdown) |
uws-akwaaba/websocket | jsonWebSocket, sendJson, publishJson |
uws-akwaaba/query | parseQuery, queryReader |
uws-akwaaba/errors | HttpError, BadRequestError, PayloadTooLargeError, UnsupportedMediaTypeError, UnprocessableEntityError |
uws-akwaaba/http | Status, reasonPhrase, statusLine |
uws-akwaaba/file-ops | ensureDir, moveFile, copyFile, removeFile, fileHash, hashBuffer, detectMimeFromBytes, safeFilename |
Router and middleware
const router = createRouter(app, { prefix: "/api", trustProxy: false });
router.use(timeout(5_000)); // 503 if nothing responded in time
router.use(limit({ max: 100, windowMs: 60_000 })); // RateLimit-* headers, 429 + Retry-After
router.post("/transfer", csrf(), authenticate({ strategies, require: { roles: ["admin"] } }), handler);
Each handler receives a Context:
| Field | Description |
|---|---|
ctx.res | the live uWS response (for body readers and streaming) |
ctx.req | a snapshot of the request that stays valid after await |
ctx.respond | the responder (below) |
ctx.params | named route parameters, { id: "42" } for /users/:id |
ctx.query | string/list/number/int/bool accessors over the query string |
ctx.state | per-request storage for middleware; starts with ip |
Middleware runs onion-style (await next()); calling next() twice is an error. onError and onUnhandled options customise error and 404 responses.
Responses
const respond = createResponder(res, req, {
cors: { origin: ["https://app.example.com"], credentials: true },
defaultHeaders: securityHeaders(),
compress: true, // brotli/gzip for text-like bodies over 1 KB
etag: true, // weak ETag + 304 on If-None-Match
});
respond.json({ ok: true }); // 200 application/json
respond.text("pong", { status: 201 });
respond.html("<h1>Hi</h1>");
respond.send(pngBytes, "image/png");
respond.redirect("/login", 303); // refuses //host, javascript: and CR/LF
respond.empty(); // 204
respond.error("Bad input"); // 400 { "error": "Bad input" }
respond.header("Server-Timing", "db;dur=12"); // queue a header for whatever is sent later
respond.json(data, {
cookies: [{ name: "sid", value: token, options: { httpOnly: true, secure: true, sameSite: "Lax" } }],
cors: false, // skip CORS for this response only
});
respond.sent; // true once a response went out; later calls are ignored
The status line is always written first (uWS fixes it at 200 as soon as any header is written), a second response is dropped instead of throwing, and nothing is written to a client that has disconnected.
Request bodies
All readers enforce maxBytes (default 1 MB), copy uWS's short-lived buffers, and reject with typed errors (413 too large, 400 malformed, 415 wrong type with strictContentType, 422 failed validation).
const user = await readJson(res, req, { validate: (v) => UserSchema.parse(v) }); // zod, valibot, ajv...
const form = await readUrlencoded(res, req, { strictContentType: true });
const text = await readText(res, req); // any WHATWG charset, e.g. ISO-8859-1
const raw = await readBuffer(res, req, { maxBytes: 10 * 1024 * 1024 });
uWS only delivers the body to a handler subscribed during the request callback. The router does this for you; in plain handlers call deferBody(res) first if you need to await before reading.
Multipart uploads
const { fields, files } = await parseMultipart(res, req, {
fileStrategy: "auto", // "buffer" | "file" | "auto" (spill to disk above bufferFileThreshold)
tempDir: "/var/tmp/uploads",
maxBytes: 50 * 1024 * 1024,
maxFileSize: 20 * 1024 * 1024,
maxFileCount: 5,
maxFieldSize: 64 * 1024,
allowedMimeTypes: ["image/*", "application/pdf"],
});
// files[i]: { fieldName, filename, mime, size, buffer? , path? }
The parser streams with disk backpressure, enforces every limit as data arrives, sanitises file names (including Windows ..\ traversal), resolves only after files are flushed to disk, and deletes the temp files it created when anything fails. It never deletes a file it did not create.
Static files
const assets = serveStatic("./public", { prefix: "/assets", maxAgeSeconds: 3600, immutable: true });
app.get("/assets/*", assets);
app.head("/assets/*", assets);
Weak ETag + Last-Modified with 304, single byte ranges (206/416, If-Range), HEAD, index files, and streaming through tryEnd/onWritable so slow clients do not buffer whole files in memory. Encoded, backslash and .. traversal, NUL bytes and dotfiles are refused.
Authentication
Inside the router use authenticate(...). For plain handlers, register rules once for the whole app:
registerGlobalAuth(app, {
default: { handlers: [bearerAuth({ verify: verifyJwt })] },
rules: [
{ match: { prefix: "/public" }, skip: true },
{ match: { prefix: "/admin" }, require: { roles: ["admin"] } },
{ match: { prefix: "/ingest" }, handlers: [apiKeyAuth({ lookup: findKey })] },
],
cache: { enabled: true, ttlMs: 5000 },
});
app.get("/me", (res) => {
const auth = getAuth(res); // { user, claims, token }
});
Rules match exact path first, then longest prefix, then regex. Strategies may be async; the registrar keeps the request usable for your handler and turns a throwing strategy into a 500. Role and scope policies apply to cached tokens too.
Rate limiting, CSRF, cookies and headers
app.post("/login", rateLimit(loginHandler, { max: 5, windowMs: 60_000 }));
const signer = createCookieSigner([process.env.COOKIE_SECRET!, process.env.OLD_COOKIE_SECRET!]);
const value = signer.sign("user:42"); // "user:42.<hmac>"
signer.unsign(value); // "user:42", or undefined if tampered
buildCookieHeaders([{ name: "sid", value, options: { httpOnly: true, csrfToken: createCsrfToken() } }]);
securityHeaders({ strictTransportSecurity: { maxAgeSeconds: 31_536_000 } });
clientIp(res, req, { trustProxy }) uses the socket address unless you explicitly trust X-Forwarded-For. Set trustProxy: true behind one reverse proxy you control, or the number of chained proxies (trustProxy: 2); the client address is read that many entries from the right, so values a client puts in the header itself are ignored.
Logging, error tracking and shutdown
The library writes no logs of its own; you choose where entries go. With the router, pass requestLog and every route gets an access log and a request id (echoed as X-Request-Id, available as ctx.state.requestId). onException receives unexpected errors (not 4xx HttpErrors, not client aborts) before they are rendered, which is where an error tracker belongs.
import pino from "pino";
import * as Sentry from "@sentry/node";
const logger = pino();
createRouter(app, {
requestLog: { log: structuredLogger(logger) }, // 5xx/aborted -> error, 4xx -> warn, else info
onException: (err, ctx) => Sentry.captureException(err, { tags: { route: ctx.route } }),
});
structuredLogger accepts anything with pino-style info/warn/error(object, message) methods; jsonLineLogger writes JSON lines to stdout with no dependency. Outside the router, wrap individual handlers:
app.get("/files/*", withRequestLog(serveStatic("./files", { prefix: "/files" }), { log: jsonLineLogger }));
// {"time":"…","id":"3f7d…","method":"GET","url":"/files/a.pdf","status":200,"durationMs":5.3,"bytes":35,"aborted":false}
const life = createLifecycle();
app.get("/work", life.track(handler));
await life.listen(app, 3000);
process.once("SIGTERM", async () => {
await life.shutdown({ timeoutMs: 15_000 }); // stop accepting, drain in-flight, then close
process.exit(0);
});
Error tracking
onException(err, ctx) is the contract for error trackers. It is called once per request, with the original error, for anything that is not a 4xx HttpError or a client abort, and before the response is rendered; ctx.route and ctx.state.requestId identify the request. The client still gets the generic 500 body (the message is never leaked), and an exception thrown by the reporter itself is ignored. These guarantees are covered by tests/integration/routerObservability.int.test.ts.
createRouter(app, {
requestLog: { log: structuredLogger(logger) },
onException: (err, ctx) =>
Sentry.captureException(err, { tags: { route: ctx.route }, extra: { requestId: ctx.state.requestId } }),
});
Production notes
- Graceful shutdown. Wrap routes with
createLifecycle().track(...)and callshutdown({ timeoutMs })onSIGTERM, so in-flight requests finish before the process exits. - Health route. A cheap route such as
api.get("/health", ...)(seeexamples/router-app.ts) gives monitoring something to call. - Client addresses. Set
trustProxyto the number of trusted proxies in front of the app (truefor one) soctx.state.ipandrateLimitsee the real client; leave it off otherwise. - Logs and errors. Pass
requestLog(withjsonLineLoggerorstructuredLogger(pino())) andonExceptionto the router. - Configuration. The library reads no environment variables; you pass every option in code.
WebSockets
app.ws(
"/chat",
jsonWebSocket<{ name: string }, { text: string }>({
validate: (v) => MessageSchema.parse(v),
open: (ws) => ws.subscribe("room"),
onMessage: (ws, msg) => publishJson(app, "room", { text: msg.text }),
}),
);
Invalid JSON, binary frames and handler errors are reported to the client (or your onError) instead of crashing.
Without the router
app.post(
"/echo",
withResponder(async (respond, req, res) => {
const body = await readJson(res, req, { maxBytes: 64 * 1024 });
respond.json(body, { status: 201 });
}),
);
withResponder installs the abort guard, reads the headers it needs up front, and renders thrown errors like the router does (onError to customise). registerGlobalCors(app, config) applies CORS to every route registered after it.
Architecture
uws-akwaaba is a library: every module is a function or factory that you call from your own uWebSockets.js app, and nothing runs on import. The layout:
src/
index.ts public entry: re-exports only
router.ts createRouter, compose, Context
router/middleware.ts timeout, authenticate, limit, csrf
responder.ts createResponder, withResponder, withSafeResponder
body.ts body readers with limits, validation and typed errors
multipart.ts streaming multipart/form-data state machine
multipart/ header parsing, FileSink (disk writes), public types
static.ts serveStatic with conditional/range requests
auth-register.ts rule-based auth registrar
auth/ types, TTL cache, rule matching, strategies
rate-limit.ts fixed-window limiter, store, route wrapper
request-log.ts request ids and access logging
lifecycle.ts graceful shutdown
websocket.ts JSON WebSocket behaviour
errors.ts HttpError and friends
cors.ts, cors-register.ts, cookies.ts, signed-cookies.ts, csrf.ts,
security-headers.ts, query.ts, http.ts, types.ts
utils/ abort fan-out, request snapshots, deferBody, client IP,
compression, range parsing, MIME types, file helpers
examples/ runnable servers, one per feature (not part of the package)
docker/ optional isolated environment for the checks and examples
tests/ unit suites mirroring src/, plus tests/integration which
runs everything against a real uWS server on a random port
Three small mechanisms carry most of the uWS-specific safety:
utils/abort.tsowns the singleonAbortedregistration uWS allows per response and fans it out, so readers, the responder and the parser never displace each other.utils/request-snapshot.tscopies a request (all headers, URL, method, query, params) so it can be used afterawait.utils/defer-body.tscaptures the body at request start and pauses the socket until a reader asks for it.
Development
git clone https://github.com/DERRICK-TORKORNOO/uws-akwaaba.git
cd uws-akwaaba
npm ci
npm test # unit + integration tests
npm run test:coverage # with coverage thresholds (what CI runs)
npm run lint # eslint
npm run format:check # prettier
npm run typecheck # tsc
npm run build # ESM + CJS + .d.ts into dist/
Run an example (see package.json for the full list; set PORT or TEMP_DIR to change the port or upload directory, as listed in examples/.env.example):
npm run dev:example-router
A devcontainer configuration is included for VS Code and Codespaces, and examples/docker can run the checks and examples in an isolated environment.
See CONTRIBUTING.md for the workflow and CHANGELOG.md for release notes.
License
MIT © Derrick Mensah Torkornoo
Contents
| Size | Path |
|---|---|
| 362 B | .devcontainer/devcontainer.json |
| 837 B | .github/dependabot.yml |
| 3.4 kB | .github/workflows/ci.yml |
| 2 kB | .github/workflows/release.yml |
| 96 B | .gitignore |
| 72 B | .npmignore · binary |
| 45 B | .prettierignore · binary |
| 74 B | .prettierrc.json |
| 8.2 kB | CHANGELOG.md |
| 2.1 kB | CONTRIBUTING.md |
| 1.1 kB | LICENSE |
| 19.9 kB | README.md |
| 723 B | eslint.config.js |
| 309 B | examples/.env.example · binary |
| 1.6 kB | examples/auth-basic.ts |
| 1.4 kB | examples/auth-cache.ts |
| 3.2 kB | examples/auth-mixed.ts |
| 2.2 kB | examples/auth-policies.ts |
| 4.2 kB | examples/auth-token-schemes.ts |
| 1.5 kB | examples/body_parser.ts |
| 3.1 kB | examples/cookies.ts |
| 1.6 kB | examples/cors-global.ts |
| 4.2 kB | examples/cors-variant.ts |
| 798 B | examples/docker/Dockerfile |
| 65 B | examples/docker/Dockerfile.dockerignore · binary |
| 634 B | examples/docker/README.md |
| 809 B | examples/docker/docker-compose.yml |
| 556 B | examples/env.ts |
| 3.2 kB | examples/http-codes.ts |
| 4.9 kB | examples/router-app.ts |
| 6.7 kB | examples/server.ts |
| 3.5 kB | examples/upload_multipart.ts |
| 163 kB | package-lock.json |
| 6.7 kB | package.json |
| 9.8 kB | src/auth-register.ts |
| 1.2 kB | src/auth/cache.ts |
| 3.5 kB | src/auth/rules.ts |
| 5.2 kB | src/auth/strategies.ts |
| 2.5 kB | src/auth/types.ts |
| 7.3 kB | src/body.ts |
| 4.1 kB | src/cookies.ts |
| 3.4 kB | src/cors-register.ts |
| 2.9 kB | src/cors.ts |
| 574 B | src/csrf.ts |
| 2.6 kB | src/errors.ts |
| 2.7 kB | src/http.ts |
| 4 kB | src/index.ts |
| 4.8 kB | src/lifecycle.ts |
| 16.3 kB | src/multipart.ts |
| 2 kB | src/multipart/file-sink.ts |
| 1.6 kB | src/multipart/helpers.ts |
| 2.4 kB | src/multipart/parsing.ts |
| 3.3 kB | src/multipart/types.ts |
| 3.2 kB | src/query.ts |
| 4.6 kB | src/rate-limit.ts |
| 5.6 kB | src/request-log.ts |
| 13 kB | src/responder.ts |
| 8.4 kB | src/router.ts |
| 5.1 kB | src/router/middleware.ts |
| 2.4 kB | src/security-headers.ts |
| 1.7 kB | src/signed-cookies.ts |
| 7.9 kB | src/static.ts |
| 3.4 kB | src/types.ts |
| 1.6 kB | src/utils/abort.ts |
| 3.8 kB | src/utils/client-ip.ts |
| 1.8 kB | src/utils/compression.ts |
| 1.6 kB | src/utils/defer-body.ts |
| 1.3 kB | src/utils/mime.ts |
| 409 B | src/utils/normalizer.ts |
| 3.9 kB | src/utils/opt-files.ts |
| 1.1 kB | src/utils/range.ts |
| 2.5 kB | src/utils/request-snapshot.ts |
| 3.4 kB | src/websocket.ts |
| 1.7 kB | tests/auth/cache.test.ts |
| 840 B | tests/auth/csrf.test.ts |
| 11.8 kB | tests/auth/registerGlobalAuth.test.ts |
| 3 kB | tests/auth/rules.test.ts |
| 3.9 kB | tests/auth/strategies.test.ts |
| 3.3 kB | tests/body/abort.test.ts |
| 2.1 kB | tests/body/deferBody.test.ts |
| 2.5 kB | tests/body/errors.test.ts |
| 3.4 kB | tests/body/readJson.flow.test.ts |
| 2 kB | tests/body/readText.test.ts |
| 1.6 kB | tests/body/urlencoded.test.ts |
| 2.7 kB | tests/body/validate.test.ts |
| 2 kB | tests/cookies/buildCookieHeaders.test.ts |
| 921 B | tests/cookies/cookies.test.ts |
| 1.5 kB | tests/cookies/parseCookieHeader.test.ts |
| 1.8 kB | tests/cookies/serializeCookie.test.ts |
| 1.5 kB | tests/cookies/signedCookies.test.ts |
| 1.6 kB | tests/cors/createCors.test.ts |
| 3.6 kB | tests/cors/preflight.test.ts |
| 4.6 kB | tests/cors/registerGlobalCors.test.ts |
| 985 B | tests/exports.test.ts |
| 5.2 kB | tests/file-ops/opt-files.test.ts |
| 1.9 kB | tests/http/errors.test.ts |
| 1.6 kB | tests/http/lifecycle.test.ts |
| 1.7 kB | tests/http/query.test.ts |
| 1.7 kB | tests/http/range.test.ts |
| 1.2 kB | tests/http/reasonPhrase.test.ts |
| 3.1 kB | tests/http/requestLog.test.ts |
| 2.1 kB | tests/http/requestSnapshot.test.ts |
| 1.5 kB | tests/http/resolveSafePath.test.ts |
| 2.1 kB | tests/http/securityHeaders.test.ts |
| 1.7 kB | tests/http/structuredLogger.test.ts |
| 2.8 kB | tests/http/websocket.test.ts |
| 3.2 kB | tests/integration/auth.int.test.ts |
| 2.1 kB | tests/integration/body.int.test.ts |
| 2.7 kB | tests/integration/lifecycle.int.test.ts |
| 2.4 kB | tests/integration/multipart.int.test.ts |
| 711 B | tests/integration/rateLimit.int.test.ts |
| 1.8 kB | tests/integration/requestLog.int.test.ts |
| 3.1 kB | tests/integration/responder.int.test.ts |
| 4.4 kB | tests/integration/router.int.test.ts |
| 3.6 kB | tests/integration/routerMiddleware.int.test.ts |
| 3.6 kB | tests/integration/routerObservability.int.test.ts |
| 5.1 kB | tests/integration/static.int.test.ts |
| 1.9 kB | tests/integration/websocket.int.test.ts |
| 2.4 kB | tests/multipart/fileSink.test.ts |
| 12.5 kB | tests/multipart/parseMultipart.test.ts |
| 3.5 kB | tests/multipart/parsing.test.ts |
| 6.4 kB | tests/rate-limit/rateLimit.test.ts |
| 1.5 kB | tests/responder/asyncSafety.test.ts |
| 4 kB | tests/responder/compression.test.ts |
| 4.8 kB | tests/responder/createResponder.test.ts |
| 2.1 kB | tests/responder/etag.test.ts |
| 3.7 kB | tests/responder/handlerErrors.test.ts |
| 2.7 kB | tests/responder/moreResponses.test.ts |
| 1.8 kB | tests/responder/withResponder.integration.test.ts |
| 2 kB | tests/router/compose.test.ts |
| 905 B | tests/utils/mock-app.ts |
| 1.2 kB | tests/utils/multipart.ts |
| 625 B | tests/utils/server.ts |
| 1 kB | tests/utils/strict-req.ts |
| 2.4 kB | tests/utils/uws-mocks-2.ts |
| 1.8 kB | tests/utils/uws-mocks.ts |
| 463 B | tsconfig.json |
| 1.2 kB | tsup.config.ts |
| 452 B | vitest.config.ts |
Dependencies
None found in the software bill of materials for this release.
computed 2026-11-02 09:34 UTC · analyzer 0.1.0Releases
| Version | Date | Scan | Changed | Notes |
|---|---|---|---|---|
| v1.0.0 | 2026-11-02 | pass | — | Initial release of uws-boost Lightweight TypeScript web framework and toolkit for building HTTP APIs on uWebSockets.js Features: - Router with middleware support - Body parsing (JSON, text, URL-encoded) - Multipart file upload handling - Static file serving - Authentication (basic, token, policies) - CORS support - Cookie management - Rate limiting - Security headers - Request logging - WebSocket support - Lifecycle management |
Machine-readable at https://x402git.com/api/v/derrick-torkornoo/uws-boost/releases. Entries cannot be deleted by the creator.
Order
GET v1.0.0 · $9 · new releases $5
The resource endpoint answers 402 with the price and the exact bytes to sign; the same request carrying PAYMENT-SIGNATURE returns a signed download URL. Access is granted only after settlement returns a transaction hash. A person can do the same thing with a browser wallet on the product page.
# the 402, with the price and the exact bytes to sign
curl -si https://x402git.com/api/r/derrick-torkornoo/uws-boost
# what your wallet already owns, and what the next fetch would cost it
curl -s https://x402git.com/api/v/derrick-torkornoo/uws-boost \
-H "X-Wallet-Signature: 0xYOURADDRESS.<nonce>.<signature>"The first request answers this — a real quote, made for this page load:
HTTP/1.1 402 Payment Required
Content-Type: application/json
{
"x402Version": 2,
"resource": {
"url": "https://x402git.com/api/r/derrick-torkornoo/uws-boost",
"description": "derrick-torkornoo/uws-boost v1.0.0 — release. Zero-dependency, high-performance HTTP toolkit and router for uWebSockets.js with native TypeScript support, validation, and request parsing. Security scan passed; signed download, 5-minute URL.",
"mimeType": "application/zip",
"serviceName": "derrick-torkornoo/uws-boost",
"tags": [
"pack",
"source",
"tests",
"examples",
"docs"
]
},
"accepts": [
{
"scheme": "exact",
"network": "eip155:8453",
"amount": "9000000",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0xDbd32F7565FFdb901Ea48281777aD03d35bB4b60",
"maxTimeoutSeconds": 300,
"extra": {
"name": "USD Coin",
"version": "2"
},
"maxAmountRequired": "9000000",
"resource": "https://x402git.com/api/r/derrick-torkornoo/uws-boost",
"description": "derrick-torkornoo/uws-boost v1.0.0 — release. Zero-dependency, high-performance HTTP toolkit and router for uWebSockets.js with native TypeScript support, validation, and request parsing. Security scan passed; signed download, 5-minute URL.",
"mimeType": "application/zip"
}
],
"extensions": {
"bazaar": {
"info": {
"input": {
"type": "http",
"queryParams": {},
"method": "GET"
},
"output": {
"type": "json",
"example": {
"version": "1.0.0",
"artifact_sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"download_url": "https://storage.example/derrick-torkornoo/uws-boost/1.0.0.zip?signed=…",
"expires_at": "2026-09-16T12:05:00.000Z",
"version_endpoint": "https://x402git.com/api/r/derrick-torkornoo/uws-boost/v/1.0.0",
"manifest_url": "https://x402git.com/api/label/derrick-torkornoo/uws-boost",
"all_versions": false
}
}
},
"schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"input": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "http"
},
"method": {
"type": "string",
"enum": [
"GET"
]
},
"queryParams": {
"type": "object",
"properties": {}
}
},
"required": [
"type",
"method"
],
"additionalProperties": false
},
"output": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"example": {
"type": "object",
"properties": {
"version": {
"type": "string",
"description": "Semantic version of the release served."
},
"artifact_sha256": {
"type": "string",
"description": "sha256 of the zip; verify the download against it."
},
"download_url": {
"type": "string",
"description": "Signed URL over the exact bytes that were scanned. Valid five minutes."
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"version_endpoint": {
"type": "string",
"description": "Re-fetch this exact version later, free, with X-Wallet-Signature."
},
"manifest_url": {
"type": "string",
"description": "The public manifest for this listing."
},
"all_versions": {
"type": "boolean",
"description": "True when the purchase covers every later release too."
}
},
"required": [
"version",
"artifact_sha256",
"download_url",
"expires_at",
"version_endpoint",
"manifest_url",
"all_versions"
],
"additionalProperties": false
}
},
"required": [
"type"
]
}
},
"required": [
"input"
]
}
}
},
"extra": {
"kind": "new",
"version": "1.0.0",
"manifest_url": "https://x402git.com/api/label/derrick-torkornoo/uws-boost",
"scan_badge_url": "https://x402git.com/api/label/derrick-torkornoo/uws-boost#scan",
"update_price_micro": "5000000",
"quote_id": "q_b4ed3cfe5eef2593267e142e163d3811",
"valid_before": "2026-11-07T12:54:38.062Z",
"instructions": "This is an x402 paywall, not an error. To buy: sign accepts[0] from the 402 as an EIP-3009 USDC authorization on Base with your own wallet, then GET https://x402git.com/api/r/derrick-torkornoo/uws-boost again with the payment in the PAYMENT-SIGNATURE header and extra.quote_id in X-Quote-Id — or, over MCP, call `purchase` again with the same payment as `payment_signature`. The full procedure is at https://x402git.com/.well-known/agent-skills/buy-a-repo/SKILL.md; the same tools are an MCP server at https://x402git.com/api/mcp. No wallet? A person can buy at https://x402git.com/derrick-torkornoo/uws-boost, and the free manifest at https://x402git.com/api/label/derrick-torkornoo/uws-boost shows what is inside before anyone pays.",
"listing_url": "https://x402git.com/derrick-torkornoo/uws-boost",
"skill_url": "https://x402git.com/.well-known/agent-skills/buy-a-repo/SKILL.md",
"mcp_url": "https://x402git.com/api/mcp"
}
}- Resource
- https://x402git.com/api/r/derrick-torkornoo/uws-boost
- Manifest
- https://x402git.com/api/label/derrick-torkornoo/uws-boost
- Version
- https://x402git.com/api/v/derrick-torkornoo/uws-boost
- Artifact sha256
- a3d8eab13ee22ef1c37169fcb696649f9f7f31ffe7ed5b9ad08e55620bd29992
Later releases cost $5, and never more than the update price in force when you bought. One charge per update, whatever the release cadence.
Sold by derrick-torkornoo. Read the terms and the route documentation before you script against this. Base URL https://x402git.com.