npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vxil/sdk

v0.7.0

Published

Typed client for the Vxil REST API (notifications, auth, jobs, files, cms, comments, webhooks, realtime, orgs, rate-limits).

Readme

@vxil/sdk

Typed JavaScript/TypeScript client for the Vxil REST API — backend building blocks (auth, cms, files, payments integration, notifications, jobs, realtime, vector search, AI, and more) you enable in one line.

npm install @vxil/sdk
import { Vxil } from '@vxil/sdk';

const vx = new Vxil({ apiKey: process.env.VXIL_API_KEY! });

await vx.users.upsert({ id: 'u_1', email: '[email protected]' });
await vx.notifications.send({ user_id: 'u_1', template: 'welcome', data: { app_name: 'MyApp' } });
const { items } = await vx.from('tasks').query({ filter: { status: 'open' } });
  • Zero dependencies. Runs anywhere fetch exists: Node ≥ 18, browsers, edge runtimes, and React Native / Expo (Hermes) — the SDK uses none of the WHATWG URL / URLSearchParams surface React Native only partially provides.
  • Defaults to https://api.vxil.com; pass baseUrl to target another environment.
  • Every feature the tenant has enabled is available as a typed namespace; generate a project-exact client with npx @vxil/cli gen.
  • Every non-2xx response throws a VxilError carrying the structured error envelope (status, code, message, hint, fixUrl, requestId, and retryAfter in seconds when the server sent Retry-After).

Server mode and end-user mode

A server key is a secret: keep it in a server route handler and never ship it in a browser or app bundle. To call Vxil from a browser or a phone directly, use a thin-client key (the end_user_required class — it refuses any request without a valid end-user session) together with the signed-in user's session token:

const vx = new Vxil({
  apiKey: PUBLIC_VXIL_KEY,        // thin-client key: reads + owner-scoped writes only
  endUserToken: session.token,    // from vx.auth.signIn / your sign-in flow
});
// reads and writes on owner-scoped resources are confined to this user
const { items } = await vx.from('meals').query({ limit: 20 });

vx.asEndUser(token) returns a client for another session with everything else inherited; nothing in the SDK caches a token.

Retries, timeouts and request hooks

All three are off by default — with none of them set the client is a single fetch per call, exactly as before.

const vx = new Vxil({
  apiKey,
  timeoutMs: 10_000,                 // per attempt; aborts the request AND its body read
  retry: { attempts: 2 },            // up to 3 requests in total
  hooks: {
    beforeRequest: (req) => ({ 'x-request-id': crypto.randomUUID() }),
    afterResponse: ({ request, response, durationMs }) => log(request.method, request.url, response.status, durationMs),
    onRetry: ({ request, delayMs, status, error }) => log('retry', request.url, delayMs, status ?? error),
  },
});

| Option | Default | Meaning | | --- | --- | --- | | retry.attempts | 0 (off) | Retries after the first attempt. | | retry.retryOn | [429, 502, 503, 504] | Response statuses that trigger a retry. | | retry.backoffMs | 250 | First delay; doubles per retry, with jitter in [½, 1] of the computed delay. | | retry.maxBackoffMs | 10_000 | Longest wait between attempts. A Retry-After beyond it ends the loop instead of waiting. | | retry.respectRetryAfter | true | Use the response's Retry-After (seconds or HTTP-date) as the delay when present. | | retry.retryOnNetworkError | true | Also retry when fetch itself fails (DNS, reset, a timeoutMs timeout). | | timeoutMs | none | Per-attempt timeout via AbortController; throws VxilError { status: 0, code: 'request_timeout' }. | | hooks.beforeRequest | — | Runs before every attempt; may return headers to add for that attempt. | | hooks.afterResponse | — | Runs after every response (retried or final) with the response and its duration. | | hooks.onRetry | — | Runs right before the client sleeps for a retry. |

Rules that keep retries safe:

  • Only idempotent requests are ever retried: GET, HEAD, PUT, DELETE, and a POST only when the call carries an Idempotency-Key (the { idempotencyKey } option on the money routes — payments.credits.consume, notifications.send, …). A bare POST or a PATCH is never retried, whatever retry says.
  • Hooks receive a frozen request descriptor (method, url, headers, attempt) that never includes the credential headers, and they cannot set them either; rotate a session with vx.asEndUser(token).
  • A thrown hook aborts the call. The body of a response a hook sees has already been read; inspect status and headers.

Errors

import { VxilError } from '@vxil/sdk';

try {
  await vx.payments.credits.consume({ user_id, credit_type: 'tokens', amount: 5 }, { idempotencyKey });
} catch (e) {
  if (e instanceof VxilError && e.status === 429) {
    showToast(`Try again in ${Math.ceil(e.retryAfter ?? 30)}s`);
  }
}

Changelog

0.4.1 — 2026-09-13

  • Documentation only: JSDoc no longer cites internal repository paths; points at the public guide instead. No runtime change.

0.4.0 — 2026-09-11

  • React-Native-clean: every query string is built without URLSearchParams (React Native's polyfill throws on .set before 0.81); wire bytes unchanged.
  • VxilError.retryAfter (seconds) parsed from Retry-After.
  • Opt-in retry, timeoutMs and hooks options on the client (see above). No behaviour changes unless set.

0.3.0

  • Agent inner-loop wave: structured output, usage, @vxil/react companions.

Docs: vxil.com/docs/guide · Dashboard: vxil.com/dashboard · Terms: vxil.com/terms

MIT © techmaker.io