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

@braydev/venus

v2.0.1

Published

A lightweight, type-safe networking library focused on clean and predictable API calls.

Readme

🪐 Venus

🚀 New in v2.0.0

  • Smart Parsing: Automatically detects if the response is JSON or Text (perfect for RSS/XML).
  • Multi-Format Support: Added support for blob, formData, and arrayBuffer.
  • Query Params: New params option to handle URL query strings safely.
  • Enhanced DX: Full JSDoc documentation for better IntelliSense in VS Code.

🚀 v2.0.0 Improvements

  • Unified API options across all methods: headers, timeout, signal, params, responseType, retry.
  • Richer error contract with errorCode and optional status.
  • Configurable retry policy with backoff for transient failures (408, 429, 5xx).
  • Lightweight hooks: beforeRequest and afterResponse.
  • RSS/Atom helper with normalized feed parsing via getRss.
  • RSS modes: strict (default) and lenient for non-standard XML feeds.

Networking, without the friction.

Venus is a modern, lightweight networking library for JavaScript and TypeScript that makes working with APIs feel effortless.

No bloated configs.
No fragile patterns.
No surprises.

Venus turns network requests into a calm, predictable experience by refining fetch into a clean, type-safe, and resilient API. You focus on your app — Venus handles the edge cases.

✨ Why Venus?

  • Clean syntax that stays out of your way
  • Type-safe by default, from request to response
  • Built-in resilience (timeouts, predictable errors)
  • Consistent results, no matter how a request fails
  • Zero dependencies, powered by native Web APIs

Venus doesn’t try to do everything.
It does one thing exceptionally well:
making network requests simple, elegant, and reliable.


🚀 Quick Start

Get up and running with Venus in minutes.

1. Configure the base URL

Set your API base URL once at your app’s entry point (e.g. main.ts or index.ts).

import { venusConfig } from "@braydev/venus";

venusConfig.setBaseURL("https://api.yourdomain.com");

2. Make your first request

Venus always returns a predictable response object — no try/catch required.

import { get, getRss, send } from "@braydev/venus";

// Fetching data
const { data, ok, error, errorCode } = await get<User>("/profile", {
  timeout: 8000,
  params: { include: ["roles", "permissions"] },
  paramsArrayFormat: "repeat",
});

if (ok) {
  console.log(data.name);
} else {
  console.error(errorCode, error);
}

// Sending data
const newUser = { name: "Brayan", role: "Developer" };
const result = await send("/users", newUser, {
  timeout: 10000,
  retry: {
    attempts: 2,
    backoffMs: 200,
  },
});

// Fetching and parsing RSS/Atom feed
const feedResult = await getRss("https://hnrss.org/frontpage", {
  timeout: 8000,
  retry: true,
  rssMode: "strict",
});

if (feedResult.ok) {
  console.log(feedResult.data.title);
  console.log(feedResult.data.items[0]?.title);
}

// --- New in v1.2.0: Powerful Query Params & Smart Parsing ---

// Effortless filtering with the 'params' option
const { data: news } = await get("/latest", {
  params: { category: "tech", limit: 5 },
  responseType: "auto",
});

/**
 * Smart Response Detection:
 * Venus automatically detects if 'news' should be a JavaScript Object (JSON)
 * or a raw String (RSS/XML/HTML). No extra configuration required.
 */
if (typeof news === "string") {
  console.log("RSS/XML content detected:", news);
} else {
  console.log("JSON API object detected:", news);
}

That’s it. No boilerplate. No guesswork. Just clean network calls.


📦 API Methods

| Method | Function | Description | | :----------- | :------------------------------------ | :---------------------------------------------------- | | get | get<T>(path, options?) | Fetch resources with parser/timeout/retry controls. | | getRss | getRss(path, options?) | Fetch and parse RSS/Atom feeds to normalized objects. | | send | send<T>(path, body, options?) | Create resources (POST) with validated body. | | update | update<T>(path, body, options?) | Replace resources entirely (PUT). | | updateOnly | updateOnly<T>(path, body, options?) | Update resources partially (PATCH). | | remove | remove<T>(path, options?) | Delete resources with 204 handling. |

Response Contract

type VenusResponse<T> = {
  data: T | null;
  ok: boolean;
  error: string | null;
  status?: number;
  errorCode:
    | "HTTP_ERROR"
    | "TIMEOUT"
    | "ABORTED"
    | "NETWORK_ERROR"
    | "PARSING_ERROR"
    | "INVALID_BODY"
    | "RETRY_EXHAUSTED"
    | "UNKNOWN_ERROR"
    | null;
};

Common Options

{
  headers?: HeadersInit;
  timeout?: number;
  signal?: AbortSignal;
  params?: Record<string, unknown>;
  paramsArrayFormat?: "repeat" | "comma" | "brackets" | "indices";
  responseType?: "auto" | "json" | "text" | "blob" | "formData" | "arrayBuffer";
  retry?: boolean | number | {
    attempts?: number;
    backoffMs?: number;
    maxBackoffMs?: number;
    retryOn?: number[];
  };
  hooks?: {
    beforeRequest?: (ctx) => void | RequestInit | Promise<void | RequestInit>;
    afterResponse?: (ctx) => void | Promise<void>;
  };
}

RSS and Atom

Venus can consume feeds without manual XML parsing:

import { getRss } from "@braydev/venus";

const feed = await getRss("https://example.com/rss.xml", {
  timeout: 7000,
  rssMode: "strict", // strict | lenient
});

if (feed.ok) {
  for (const item of feed.data.items) {
    console.log(item.title, item.link);
  }
}

RSS Modes

  • strict (default): fails if XML is not valid RSS/Atom structure.
  • lenient: does best-effort normalization for custom/non-standard XML feeds.
const strictFeed = await getRss("https://example.com/feed.xml", {
  rssMode: "strict",
});

const lenientFeed = await getRss("https://example.com/custom-xml", {
  rssMode: "lenient",
});

Frontend Example (SPA)

import { getRss } from "@braydev/venus";

export async function loadNews() {
  const result = await getRss("https://hnrss.org/frontpage", {
    timeout: 6000,
    retry: true,
    rssMode: "strict",
  });

  if (!result.ok) {
    throw new Error(result.error ?? "Feed error");
  }

  return result.data.items.slice(0, 10);
}

Backend Example (Node/SSR)

import { getRss } from "@braydev/venus";

export async function fetchTechFeed() {
  const result = await getRss("https://example.com/custom-feed", {
    timeout: 8000,
    retry: { attempts: 2, backoffMs: 200 },
    rssMode: "lenient",
  });

  if (!result.ok) {
    return { items: [], source: "fallback", error: result.error };
  }

  return {
    source: result.data.title,
    items: result.data.items.map((item) => ({
      title: item.title,
      link: item.link,
      publishedAt: item.pubDate,
    })),
  };
}

Changelog

A changelog is the file where you record what changed in each version (features, fixes, breaking changes). It helps users trust updates and migrate faster.

  • Convention: keep one section per version (## 1.3.0, ## 1.2.1, etc.)
  • Include: Added, Changed, Fixed, Breaking (if any)
  • Follow SemVer (major.minor.patch)

🧪 Testing

Venus is fully tested with Vitest.
Run the test suite with:

npm test

📄 License

MIT © code-braydev