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

@visgate_ai/client

v0.3.5

Published

JavaScript/TypeScript client for Visgate API — unified vision AI gateway (Fal, Replicate, Runway, RunPod).

Readme

@visgate_ai/client

JavaScript/TypeScript SDK for the Visgate API — one client for image and video generation across Fal, Replicate, Runway, and RunPod deployments.

Works in Node.js (18+), browsers, and with React, Vite, Next.js, and vanilla JS.

Install

npm install @visgate_ai/client

Quick Start

import { Client } from "@visgate_ai/client";

const client = new Client(); // reads VISGATE_API_KEY from env (Node)

const result = await client.generate("a sunset over Istanbul");
console.log(result.imageUrl, result.cost, result.provider);

client.close();

With explicit API key:

const client = new Client({ apiKey: "vg-..." });
const result = await client.generate("a sunset", { model: "fal-ai/flux/schnell" });
console.log(result.imageUrl);

Features

  • One client, multi-provider. Fal, Replicate, Runway, and RunPod deployments behind a single API.
  • Managed and BYOK modes. Use Visgate-managed keys or bring your own.
  • Promise-based API. All methods return Promises; use async/await or .then().
  • Automatic retries. Transient errors (429, 5xx) are retried with exponential backoff.
  • Typed exceptions. Catch AuthenticationError, RateLimitError, ProviderError, etc.
  • TypeScript. Full type definitions included.
  • Framework-agnostic. Use in vanilla JS, React, Vite, Next.js.
  • Async generation. Video/image async mode with client.requests.get() for status polling; usage and billing resources.

Authentication

Node.js: Set VISGATE_API_KEY in the environment or pass apiKey in options.

export VISGATE_API_KEY="vg-..."

Browser / Vite: Pass apiKey in options (or use import.meta.env.VITE_VISGATE_API_KEY in Vite and pass it to the client).

const client = new Client({ apiKey: "vg-..." });

Production / proxy (recommended for browser apps)

Do not put your Visgate API key in the client. Use a server-side proxy that adds the key:

const client = new Client({ proxyUrl: "/api/visgate" });
// No apiKey needed — the proxy adds Authorization on the server

Set VISGATE_API_KEY on the server. This repo includes a ready-made proxy package: server-proxy/ (published as @visgate_ai/server-proxy on npm). See server-proxy/README.md for setup; or implement your own forward that injects the key.

Session-based auth (getToken): When your app has a session token (e.g. Firebase ID token), pass a getToken function so the client sends a fresh Bearer token on each request; the proxy forwards it to the API:

const client = new Client({
  proxyUrl: "/api/visgate",
  getToken: async () => (await auth.currentUser?.getIdToken()) ?? "",
});

The proxy must forward the client's Authorization: Bearer header (e.g. @visgate_ai/server-proxy does this via keyFromRequest). If you use httpOnly cookies, the token is never in the client; your proxy reads the cookie and adds Bearer on the server — in that case do not use getToken; use Client({ proxyUrl: "/api/visgate" }) and ensure requests send credentials so the cookie is sent.

BYOK (Bring Your Own Key)

const client = new Client({
  apiKey: "vg-...",
  falKey: "fal_...",
  replicateKey: "r8_...",
  runwayKey: "rw_...",
  runpodKey: "rpa_...",
});

API Reference

Image Generation

// Quick generation (unified POST /generate)
const result = await client.generate("a cat in space", { model: "fal-ai/flux/schnell" });
console.log(result.status, result.imageUrl, result.cost);

// Full control (POST /images/generate) — matches API ImageGenerateRequest
const result = await client.images.generate("fal-ai/flux/schnell", "a cat in space", {
  width: 1024,
  height: 1024,
  numImages: 1,
  negativePrompt: null,
  seed: null,
  imageUrl: null,           // optional: input image for img2img
  preferCache: true,       // use cache (exact or semantic match)
  maxLatencyMs: null,      // optional: max acceptable latency (ms)
  webhookUrl: null,        // optional: callback URL when done
  callbackId: null,        // optional: id in callback payload
});
// result: id, status, images, model, provider, cost, cacheHit, cacheSource?, latencyMs, savedAmount?, marginPercent?, createdAt

Video Generation

Video generation can take several minutes. To avoid 502 when the request takes longer than proxy/Cloudflare timeout, use async mode (preferAsync: true): the API returns 202 immediately, then poll client.requests.get(requestId) until completed.

Use VIDEO_MODEL_PRESETS for provider model IDs (Fal, Replicate, Runway), or pass a model string (e.g. fal-ai/veo3, replicate/lucataco/cogvideox-5b, runway/gen4_turbo). For image-to-video, set imageUrl or imageFile in options.

import { Client, VIDEO_MODEL_PRESETS } from "@visgate_ai/client";

const client = new Client({ proxyUrl: "/api/visgate", timeout: 300_000 });

// Sync (wait for result; may hit proxy timeout on long videos)
const syncResult = await client.videos.generate(VIDEO_MODEL_PRESETS.fal, "waves on a beach", {
  durationSeconds: 6,
  skipGcsUpload: true,
});
console.log(syncResult.videoUrl, syncResult.cacheHit, syncResult.cost);

// Async (recommended): returns 202, poll client.requests.get(requestId)
const result = await client.videos.generate("fal-ai/veo3", "waves on a beach", {
  durationSeconds: 6,
  skipGcsUpload: true,   // faster; return provider URL directly
  preferAsync: true,     // avoids 502 — returns 202, poll client.requests.get(requestId)
  imageUrl: null,        // optional: input image for img2vid (or use imageFile)
  webhookUrl: null,      // optional: callback URL when done
  callbackId: null,      // optional: id in callback payload
  params: {},            // optional: extra provider params
});
if (result.status === "accepted") {
  let status = await client.requests.get(result.requestId);
  while (status.status === "pending" || status.status === "processing") {
    await new Promise((r) => setTimeout(r, 3000));
    status = await client.requests.get(result.requestId);
  }
  console.log(status.status, status.outputUrl);
} else {
  console.log(result.videoUrl, result.cacheHit, result.status);
}

On the server, set the proxy route’s maxDuration (e.g. 300 seconds) so the request is not cut off — see server-proxy/README.md.

Async request status (Requests)

After starting an async generation (video or image with preferAsync: true), poll the request status until completion:

const status = await client.requests.get(result.requestId);
// status: requestId, status ("pending" | "processing" | "completed" | "failed"),
//         mediaType, provider, model, outputUrl, errorMessage, createdAt, completedAt

Model Discovery

const resp = await client.models.list({ provider: "fal", mediaType: "image", limit: 20 });
for (const m of resp.models) console.log(m.id, m.name);

const model = await client.models.get("fal-ai/flux/schnell");

Usage and Billing

const usage = await client.usage.get("month");
console.log(usage.totalRequests, usage.totalBilledCost, usage.cacheHitRate, usage.avgLatency, usage.history);

const logs = await client.usage.logs({ limit: 50 });
const dashboard = await client.usage.dashboard("week");

// Track download event (POST /usage/downloads)
await client.usage.trackDownload("request-id", "https://...", { mediaType: "image" });

Billing

const stats = await client.billing.getStats();       // public stats
const info = await client.billing.getInfo();         // org billing info (tier, balance, etc.)
const pricing = await client.billing.getPricing();  // model pricing list
await client.billing.checkout(10, "https://...", { customerEmail: "..." });
await client.billing.updateSubscription("starter");

Provider Management

const keys = await client.providers.listKeys();
const balances = await client.providers.balances();

Deployments (RunPod BYOK)

// Create deployment from HuggingFace model
const created = await client.deployments.create({
  hfModelId: "stabilityai/stable-diffusion-xl-base-1.0",
  gpuTier: "medium",
  task: "text2img",
});

// List deployments and select one
const list = await client.deployments.list();
const dep = list.deployments[0];

// Get current status/details
const detail = await client.deployments.get(dep.deploymentId);
console.log(detail.status, detail.endpointUrl);

// Run inference on ready deployment
const run = await client.deployments.run(dep.deploymentId, {
  prompt: "cinematic cat portrait",
});
console.log(run);

// Optional helpers
const logs = await client.deployments.getLogs(dep.deploymentId);
const cost = await client.deployments.getCost(dep.deploymentId);
const gpus = await client.deployments.listGpus();

Health Check

const health = await client.health();
console.log(health.status);

Error Handling

import { Client, AuthenticationError, RateLimitError, ProviderError, ValidationError, VisgateError } from "@visgate_ai/client";

const client = new Client({ apiKey: "vg-..." });

try {
  const result = await client.generate("a sunset");
} catch (err) {
  if (err instanceof AuthenticationError) console.error("Invalid API key");
  else if (err instanceof RateLimitError) console.error("Rate limit", err.retryAfter);
  else if (err instanceof ProviderError) console.error("Provider error", err.provider);
  else if (err instanceof ValidationError) console.error("Validation", err.field);
  else if (err instanceof VisgateError) console.error(err.message, err.errorCode);
}

Configuration

| Option | Default | Description | | ------------ | --------------------------- | ------------------------------ | | apiKey | process.env.VISGATE_API_KEY | Visgate API key (optional when using proxyUrl) | | proxyUrl | — | Server proxy URL; when set, no key or BYOK is sent | | baseUrl | https://visgateai.com/api/v1 | API base URL | | timeout | 120000 (ms) | Request timeout | | maxRetries | 2 | Retries for 429 and 5xx | | falKey | — | Fal BYOK key | | replicateKey | — | Replicate BYOK key | | runwayKey | — | Runway BYOK key | | runpodKey | — | RunPod BYOK key (X-Runpod-Key) |

AsyncClient

For API parity with the Python SDK, AsyncClient is also exported; it has the same interface as Client (all methods return Promises).

import { AsyncClient } from "@visgate_ai/client";

const client = new AsyncClient();
const result = await client.generate("a sunset");

Repository structure

  • src/ — @visgate_ai/client (client library): generate, images, videos, models, requests (async status), usage, providers, deployments, billing
  • server-proxy/@visgate_ai/server-proxy: server-side proxy for Next.js and other Node runtimes. Install with npm install @visgate_ai/server-proxy or use locally from this repo.
  • examples/ — Next.js, vanilla, and Vite examples

License

MIT — see LICENSE.