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

@restlessai/cli

v0.6.0

Published

AI-powered SDK installer CLI. Scans your project, generates an OpenAPI spec, and wires up the ReadMe SDK.

Downloads

767

Readme

npx api init

Restless makes sure every 🔴 400 Bad Request turns out 🟢 200 Okay.

It's not just another observability platform (although you can use it to see what your users are up to!).

Think of us more as an API success platform. We give humans, AI and you the tools to quickly make successful calls.

Supported stacks

| language | frameworks | | --- | --- | | JavaScript / TypeScript | Express, Fastify, Koa, Hono, NestJS, Next.js (App or Pages Router) | | Python | Flask, Django, FastAPI, Starlette, and anything else speaking WSGI or ASGI | | Ruby | Rails, Sinatra, Hanami, Grape, Roda, and anything else speaking Rack | | Go | net/http, chi, gorilla/mux, Echo, Gin |

A repo can hold more than one. A Django API behind a Next.js frontend is two real APIs, and setup scans for both and asks which you meant rather than picking for you.

If npx api init finds only a language we can't wire yet (a composer.json, Cargo.toml, pom.xml, and so on) it tells you and stops rather than scanning a codebase it can't set up. The call it prints is the fastest way to get your language moved up.

That check only fires when there is nothing supported to find, so a Python API with a package.json for its frontend, or a Node API with Python build scripts, are both unaffected. If it does misjudge your repo - an HTTP framework we don't know by name, or a bare node:http server we couldn't see - skip it and scan anyway:

RESTLESS_SKIP_STACK_CHECK=1 npx api init

What lands in your project

  • .restless/ - your API's OpenAPI spec plus the settings the SDK reads at startup. Commit it with your code. It's configuration, not a build artifact, and it holds no credentials.
  • RESTLESS_KEY in .env - your project's write key. Keep this out of git.

Running inside a coding agent

If you run npx api init inside Claude Code or Codex, it doesn't quietly drive its own AI through your codebase. It prints the setup as instructions for the agent you're already talking to, so the work happens in front of you: you see every diff and can stop or redirect it. Your agent handles reading the code, writing the spec, and wiring the middleware; these commands cover the parts that shouldn't be improvised:

| command | what it does | | ------- | ------------ | | npx api guide [oas\|sdk] | Prints the spec-writing / SDK-wiring instructions | | npx api key | Registers the project and writes RESTLESS_KEY to .env | | npx api register --oas <file> | Records a spec in .restless/settings.json (rejects localhost servers) | | npx api verify --url <url> | Sends one request, confirms the SDK saw it, the log landed, and no owner-id placeholder remains | | npx api login | Prints the URL you open to claim the project |

Re-running is safe: an unchanged key keeps its existing project rather than registering a new one - even when .restless/ is gone, npx api key re-adopts the project this machine first registered the key to, and if the key on disk can't be matched to any known project it mints a fresh key (replacing the .env line) instead of re-registering the old one into a project its logs would never reach. It writes the key straight to .env and never echoes it into the agent's transcript; --inline prints it on stdout instead, but only for humans - under a coding agent it refuses. It also reports whether git ignores that env file (envIgnoredByGit), so the key can't slip into a commit unnoticed.

Not Claude Code or Codex? Those two announce themselves in the environment; everything else we infer from a run whose input and output are both pipes, which is what an agent's shell tool looks like. That's enough to hand over the playbook instead of driving your repo from a hidden sub-agent, but it can't tell us which tool you are - so name yourself and it gets recorded on the project: --agent cursor on any command, or RESTLESS_AGENT=cursor in the environment. Piping on purpose as a human? RESTLESS_INTERACTIVE=1 opts back out.

Running in a plain terminal? Setup asks whether it can use your local agent. Answer "No, other options" to copy that same prompt for an agent elsewhere, set it up by hand with the commands above, book a call, or ask questions first.

Want the guided flow instead, with the CLI doing the work? npx api init --self-drive.

After you've claimed a project

npx api init stays safe to re-run, and it notices what's already there: an API you've mapped is offered back to you instead of being re-scanned, and a project you've already claimed finishes without asking you to claim it a second time.

Changing things afterwards is npx api update, not another init. It edits settings (name, base URL, visibility, request prefix) and refreshes your spec, then pushes both to the dashboard.

Refreshing means whatever it meant the first time, because setup records where your spec came from:

| your spec came from | what "refresh" does | checked automatically | | ------------------- | ------------------- | --------------------- | | a URL | re-fetches that URL | yes | | a file you maintain | re-reads it. We never regenerate over your file | yes | | a command or location you described | runs that again | yes | | your framework's generator | runs it again, then fills gaps from your routes | yes | | our AI reading your routes | reads them again | on request |

Anything with a source to go back to gets checked before update asks you anything, so it opens with whether your spec actually changed:

$ npx api update
  Your spec changed (3 endpoints now)

    + GET /pets/{id}
    + POST /pets

  Update the spec and sync your settings? [Y/n]

Say no and you get the full menu instead.

Nothing touches your spec before you answer, on any path through update: every refresh - re-fetching a URL, replaying a recorded command, regenerating from your routes - is written to a scratch directory and only moved into place once you agree. If it fails, or you say no, the file you already had is exactly as it was.

It checks the dashboard too, which is the other way a spec goes out of date:

$ npx api update
  ! Your dashboard is missing 2 endpoints that your spec has:
    + GET /api/v1/projects/{}/feedback
    + PATCH /api/v1/projects/{}/feedback/{}

  Your local .restless/openapi.json is already up to date.

  Push it to the dashboard? [Y/n]

Those are separate questions. Your local file can be perfectly current while the dashboard serves something from weeks ago, and that's the one you notice, because it's what your docs and AI chat answer from. Comparing needs an authorized session, so if this machine hasn't been authorized yet the check says so instead of guessing.

When there's genuinely nothing to do, it says so and ends:

  ✓ Your spec is unchanged (34 endpoints).
  ✓ Your dashboard is serving this version.

  Press Enter to exit, or s to edit settings.

The exception is a spec our AI wrote from your routes. There's no source to go back to, so re-checking it means reading your whole codebase again from scratch

  • a decision rather than a status check. You'll see what you have and can ask for that explicitly.

If a refresh would remove endpoints from your docs, it says so and asks. Regenerating from your routes is always available as an explicit choice, and it writes to .restless/openapi.json rather than overwriting a spec you wrote yourself - when that changes which file your project points at, the confirm says so before you answer, not afterwards.

update also runs without prompts when you tell it exactly what to do, which is what a coding agent or a CI job needs. Run it inside Claude Code or Codex with no flags and it prints these rather than trying to drive a picker nobody can answer:

npx api update --status --json     # did the spec change? writes nothing
npx api update --refresh --json    # re-run its source, then push spec + settings
npx api update --oas <file|url>    # point at a different spec and push it
npx api update --base-url https://api.acme.com
npx api update --sync              # push settings with no edits

Also --name, --internal / --external, --prefix, and --project <id> to pick one API in a multi-API repo.

--status is the read-only one: no writes, nothing pushed. It answers two separate questions, because they have different answers:

{
  "specChanged": false,
  "dashboard": { "behind": true, "missing": ["GET /api/v1/projects/{}/feedback"] }
}

specChanged is "is my local file stale against its own source". dashboard is "is what Restless serves stale against my local file". It never triggers a browser login, so dashboard.status is unauthorized when this machine has no session yet.

It's deliberately narrower than what the interactive flow checks. A URL or a file it can answer instantly; re-running a recorded command or a framework generator needs an agent, and having a status check spawn one defeats the point of asking first. Those report checkable: false and point at --refresh, which is the explicit "yes, do the expensive thing".

Local edits are saved before anything is pushed, so a sync that can't reach us never discards them: --json reports synced separately from ok and says why. Authorizing a machine needs a browser once; after that the session is reused for 24 hours.

Privacy

  • The setup will use AI, but won't use it without asking first.
  • It uses your local AI, so no code will be sent to our servers.
  • Inside a coding agent, the AI doing the work is the one you're already using, and nothing extra is spawned behind your back.
  • Registering a project records two things about how setup ran: whether you started it yourself or your coding agent did, and which agent did the work (--agent / RESTLESS_AGENT if you set one, otherwise blank unless it's Claude Code or Codex). That's it - no prompts, no code, no file contents.