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

@lp-labs/react-request-builder

v1.0.0

Published

Typed HTTP request modeling, URL generation, and opt-in abortable fetch integration with a controlled React editor.

Readme

@lp-labs/react-request-builder

Package version: 1.0.0. Requires React ^18.2.0 || ^19.0.0 as its only runtime peer. ESM and CommonJS named exports are provided.

npm install @lp-labs/react-request-builder react

A typed HTTP request model, URL and RequestInit generator, controlled React editor, and opt-in abortable fetch helper. Rendering or editing never sends a network request.

Install and render

import { RequestBuilder, createEmptyRequest } from "@lp-labs/react-request-builder";
import { useState } from "react";
import "@lp-labs/react-request-builder/style.css";

function Composer() {
  const [request, setRequest] = useState(createEmptyRequest());
  return <RequestBuilder value={request} onChange={setRequest} />;
}

The editor is controlled and emits a new RequestDefinition for each edit. Query parameters and headers can be disabled or removed. className adds a wrapper class; the stylesheet is optional. The built-in preview validates but never fetches.

Complete props and exported types

RequestBuilderProps has required value: RequestDefinition and onChange: (value: RequestDefinition) => void, plus optional className?: string (no added class by default). There is no defaultValue, internal request store, send button, or network callback. Feed each change back to value.

All runtime exports are named: RequestBuilder, createEmptyRequest, buildRequest, sendRequest, and RequestBuilderError. Type-only exports:

type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
interface RequestPair { name: string; value: string; enabled?: boolean }
interface RequestDefinition {
  method: HttpMethod;
  url: string;
  query: RequestPair[];
  headers: RequestPair[];
  body: string;
}
interface BuiltRequest { url: string; init: RequestInit }
interface RequestErrorDetails {
  kind: "validation" | "network" | "http";
  status?: number;
}

createEmptyRequest(): RequestDefinition creates a fresh { method: "GET", url: "https://api.example.com", query: [], headers: [], body: "" }. enabled defaults to enabled unless exactly false. buildRequest(request): BuiltRequest does not mutate the definition; it appends repeated query/header names using native URLSearchParams/Headers behavior.

Build or explicitly send

import {
  buildRequest, sendRequest,
  type RequestDefinition
} from "@lp-labs/react-request-builder";

const request: RequestDefinition = {
  method: "GET",
  url: "https://api.example.com/items?sort=recent",
  query: [{ name: "tag", value: "design" }],
  headers: [{ name: "accept", value: "application/json" }],
  body: ""
};

const built = buildRequest(request); // { url, init }
const controller = new AbortController();
const response = await sendRequest(request, { signal: controller.signal });
const result = await response.json(); // response parsing remains the caller's choice

RequestDefinition has method, absolute url, query and headers arrays of { name, value, enabled? }, and a string body. Supported methods are GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS. Enabled non-empty query names are appended with URLSearchParams, preserving existing query entries. Enabled named headers are validated through the platform Headers API. A non-empty body gets a default JSON content type only when none is already present; GET and HEAD bodies are rejected. Only HTTP(S) URLs without embedded credentials are accepted.

buildRequest is pure and throws RequestBuilderError with kind: "validation" for invalid input. sendRequest performs fetch only when explicitly called; it accepts an optional abort signal and injectable fetch implementation for testing. It returns successful Response objects without parsing them. Non-2xx responses throw with kind: "http" and a status; network failures throw with kind: "network". Abort errors are passed through. Errors do not include response bodies or request header values, and the package never logs secrets.

The full send signature is sendRequest(request: RequestDefinition, options?: { signal?: AbortSignal; fetch?: typeof fetch }): Promise<Response>. Options default to {}, using globalThis.fetch and no cancellation signal. Missing fetch rejects with a network error. RequestBuilderError(message: string, details: RequestErrorDetails) extends Error, sets name "RequestBuilderError", and exposes readonly kind and optional status. A rejected fetch is passed through unchanged if the supplied signal is aborted; otherwise it becomes a generic network error. Successful response bodies must still be consumed/closed by the application; non-success response bodies are not exposed by the error.

For cancellation, keep the controller until work is done and call controller.abort() when the owning view unmounts or the user cancels. There is no automatic unmount cancellation, timeout, retry, or request concurrency limit. Catch the returned promise to handle abort/network/HTTP failures.

Accessibility and scope

Inputs and actions have labels, visible keyboard focus, and validation alerts. Customize .lp-request and .lp-request__* or use a custom stylesheet. This package deliberately does not implement authentication storage, retries, response parsing, request signing, code snippet generation, or a request history. Review requests and apply your own application security and CORS policies before sending.

URL, Headers, AbortSignal, RequestInit, and Response are platform APIs; use a modern browser (and TypeScript ES/DOM declarations), or a compatible server host for helpers. Node ambient types are not required. The root module also exports a React component, so React must resolve even for helper-only imports. No globals are accessed for network work until helpers/rendering run, and import never fetches. Use the application's own React renderer. Large pair lists render in full and large bodies stay in memory; no virtualization or performance certification is provided. JSON content type is a default only: body text is not JSON-parsed or schema-validated.

Project

License

MIT.

Support

If this library is useful to you, consider supporting its maintenance with a donation via PayPal.

Author

Created by Libin Prasanth. Connect on LinkedIn for updates and discussion.