Skip to content
rhttp.io

Installation & Quick Start

This guide walks you through installing rhttp.io and making your first typed request.

If you already know which factory you need, you can jump directly to the Client Guide or the Server Guide.

Requirements

  • Node.js >= 18.0.0 Works with modern browsers, Bun, Deno, and edge runtimes as well.
  • TypeScript >= 5.0 Optional, but strongly recommended. The package ships with full type definitions.

Install

npm

npm install rhttp.io

pnpm

pnpm add rhttp.io

yarn

yarn add rhttp.io

bun

bun add rhttp.io

Note rhttp.io has optional peer dependencies for the integrations you actually use:

  • react and react-dom — only for the React adapter
  • @tanstack/react-query — only for the React adapter
  • socket.io-client — only for the Realtime layer

These are optional. The core HTTP client works with zero extra dependencies.

Your first request

The simplest entry point is the framework-agnostic factory createHttp().

import { createHttp } from "rhttp.io";
 
// Create a client with a base URL and default headers.
const http = createHttp({
  baseURL: "https://api.example.com",
  defaultHeaders: { "Content-Type": "application/json" },
  timeout: 30_000,
});
 
interface User {
  id: number;
  name: string;
  email: string;
}
 
// Make a typed GET request.
const { data, status, durationMs } = await http.get<User>("/users/42");
 
// `data` is inferred as `User`.
data.id;
data.name;

The returned object is an HttpResponse<T>. It always includes:

  • the parsed data
  • the HTTP status
  • the response headers
  • a unique requestId
  • the wall-clock durationMs

HTTP methods

Every verb returns a Promise<HttpResponse<T>>.

post, put, and patch accept a body before options. delete also accepts a body, which is useful for bulk deletes.

import { createHttp } from "rhttp.io";
 
const http = createHttp({ baseURL: "https://api.example.com" });
 
// GET with query params — params are serialized automatically.
const list = await http.get<User[]>("/users", {
  params: { page: 1, role: "admin", tags: ["a", "b"] },
});
 
// POST with a typed body. The second generic narrows the response type.
interface CreateUserDTO {
  name: string;
  email: string;
}
 
const created = await http.post<CreateUserDTO, User>("/users", {
  name: "Ada Lovelace",
  email: "ada@example.com",
});
 
// PUT / PATCH replace or partially update a resource.
await http.put<User>("/users/42", { name: "Augusta Ada" });
await http.patch<User>("/users/42", { lastLoginAt: new Date().toISOString() });
 
// DELETE — with or without a body.
await http.delete<void>("/users/42");
await http.delete<void>("/users", [1, 2, 3]); // bulk delete via body

Tip params arrays are serialized as repeated keys, for example ?tags=a&tags=b. null and undefined values are skipped automatically, which matches common backend conventions.

Error handling

Non-2xx responses reject with an HttpError. Timeouts throw TimeoutError, and unreachable hosts throw NetworkError. Both extend HttpError, so one instanceof check is enough.

import { createHttp, HttpError } from "rhttp.io";
 
const http = createHttp({
  baseURL: "https://api.example.com",
  timeout: 5_000,
});
 
try {
  await http.get("/flaky-endpoint");
} catch (error) {
  if (error instanceof HttpError) {
    console.error(error.status, error.statusText);
    console.error(error.url, error.requestId, error.durationMs);
    console.error(error.data);
  } else {
    throw error;
  }
}

Warning Always narrow with instanceof HttpError instead of reading error.status directly. A thrown value is not guaranteed to be an HttpError, and TypeScript cannot prove otherwise.

Choose the right factory

For most apps, you will use the environment-specific factories instead of createHttp().

Browser / Client Components

import { createClientHttp } from "rhttp.io/client";
 
const http = createClientHttp({ baseURL: "https://api.example.com" });

This factory enables:

  • credentials: "include"
  • JSON headers
  • CSRF prefetch
  • token auto-injection from localStorage

Server / SSR

import { createServerHttp } from "rhttp.io/server";
 
const http = createServerHttp({ baseURL: "https://api.example.com" });

This factory enables:

  • cookie forwarding
  • tracing
  • production metrics

Note Both factories are documented in depth in their respective guides: Client Configuration and Server Configuration.

Where to go next