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

restix

v0.0.3

Published

Type-safe HTTP client builder for CLI tools and backend applications

Readme

restix

restix is a strict, type-safe HTTP client builder designed for CLI tools and backend applications.

It allows you to define your API once as a contract and interact with it safely without rewriting fetch logic, URL builders, or request payload handling.

Design your API → map it → call it safely

No runtime magic. No hidden abstractions. No guessing.


Why restix?

When building CLI tools or backend services, you often need to:

  • Call many HTTP endpoints
  • Inject URL params, query strings, headers, and body data
  • Keep everything type-safe
  • Avoid request boilerplate

restix solves this by:

  • Enforcing exact input types per endpoint
  • Preventing extra or missing fields at compile time
  • Supporting multiple injection strategies
  • Centralizing request logic
  • Staying minimal and predictable

Core Concepts

1. API Contract (Type First)

Your API is defined as a TypeScript interface. Each key represents an endpoint, and its value represents the exact allowed input.

interface API_INTERFACE {
  'GET /packages/cli/name/{name}': {
    name: string
  }

  'POST /packages/cli/create': {
    name: string
    version: string
    developer: string
  }
}

This interface is the single source of truth.


2. API Mapping

Each endpoint must declare how its data is injected.

Supported injection targets:

  • params → URL parameters
  • query → query string
  • body → request body
  • headers → request headers
import { apiMap, type API_MAPS, type GET_API } from 'restix'

const api_maps: API_MAPS<API_INTERFACE> = {
  'GET /packages/cli/name/{name}': {
    map: apiMap<GET_API<API_INTERFACE, 'GET /packages/cli/name/{name}'>>({
      params: ['name']
    }),
    res: 'json'
  },

  'POST /packages/cli/create': {
    map: apiMap<GET_API<API_INTERFACE, 'POST /packages/cli/create'>>({
      body: ['*']
    }),
    res: 'json',
    status: {
      safe: 201
    }
  }
}

'*' means all fields Explicit keys mean only those fields


3. Query Injection Strategies

A) Automatic Query Injection

map: apiMap({
  query: ['q', 'v']
})
api.request('GET /search', {
  q: 'nex',
  v: '1'
})

➡️ ?q=nex&v=1


B) URL-Positioned Query Injection

'GET /packages/cli/search?selam={v}&VERSION={v}'
api.request(
  'GET /packages/cli/search?selam={v}&VERSION={v}',
  {
    q: 'nex',
    v: 'sa'
  }
)

➡️ ?selam=sa&VERSION=sa

This is especially useful for:

  • Legacy APIs
  • Fixed query naming conventions
  • Enterprise-style endpoints

4. Creating the Client

import { NexAPI } from 'restix'

const api = new NexAPI<API_INTERFACE>(
  'http://localhost:5000',
  api_maps
)

With Defaults

const api = new NexAPI<API_INTERFACE>(
  'http://localhost:5000',
  api_maps,
  {
    headers: {
      'User-Agent': 'restix-cli'
    },
    status: {
      404: () => 'Global not found'
    }
  }
)

Defaults are merged, not replaced.


5. Making Requests (Type-Safe)

await api.request('GET /packages/cli/name/{name}', {
  name: 'xnex'
})
await api.request('POST /packages/cli/create', {
  name: 'xnex',
  version: '0.0.1',
  developer: 'Signor P'
})

❌ Compile-time error (extra field):

api.request('GET /packages/cli/name/{name}', {
  name: 'xnex',
  extra: 'nope'
})

❌ Compile-time error (missing field):

api.request('POST /packages/cli/create', {
  name: 'xnex'
})

Status Handling

Each endpoint can define status handlers:

status: {
  safe: 200,
  404: () => 'Not found',
  400: () => 'Bad request'
}

You can also define global status defaults when creating the client.


Key Features

  • ✅ Exact object typing (no extra keys)
  • ✅ Route-based type inference
  • ✅ URL param injection
  • ✅ Automatic & positional query injection
  • ✅ Header & body extraction
  • ✅ Global + local status handling
  • ✅ CLI-friendly (Bun / Node)
  • ✅ No runtime dependencies
  • ✅ No decorators, no reflection

Designed For

  • CLI tools
  • Backend services
  • Automation scripts
  • Internal SDKs
  • API clients
  • Monorepo shared tooling

Not designed for heavy frontend frameworks.


Philosophy

restix follows a contract-first approach:

  • Types are the contract
  • Mapping defines behavior
  • Requests are deterministic
  • Errors are caught at compile time

If TypeScript allows it, restix allows it. If TypeScript rejects it, restix rejects it too.


Status

This project is actively evolving. The API is intentionally minimal and strict.

Ideas, issues, and contributions are welcome.


License

MIT