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

ashby-sandbox

v0.1.0

Published

Local Ashby API sandbox: a coherent, seeded fake ATS serving Ashby's real API surface. Point ashby-ts, MCP servers, or integration tests at it — no customer account needed.

Readme

ashby-sandbox

A local, fake Ashby API you can develop against without a customer account.

Ashby has no self-serve sandbox: the data endpoints need a customer API key, the MCP beta connects through a customer user's OAuth to live recruiting data, and partner sandboxes are granted only after partner-program approval. Even customers have no safe place to point integration tests or rehearse agent behavior — write endpoints hit the production ATS. This serves Ashby's real API surface on localhost instead.

bunx ashby-sandbox
# ashby-sandbox listening on http://localhost:3690 (seed 1)
#   world: 8 jobs · 120 candidates · 134 applications · 14 users
#   endpoints: 28 stateful · 145 spec-example stubs

Point any Ashby client at it, for example ashby-ts:

import { Ashby } from "ashby-ts";

const ashby = new Ashby({ apiKey: "anything", baseUrl: "http://localhost:3690" });

for await (const app of ashby.application.list({ jobId })) {
  // a coherent pipeline, not random noise
}

Or curl it exactly like api.ashbyhq.com:

curl -s -u any-key: http://localhost:3690/job.list -d '{}' | jq '.results[].title'

Why not a generic OpenAPI mocker

Prism and friends can mock Ashby's spec, but they generate schema-random data: applications pointing at jobs that don't exist, candidates with no applications, pagination that never pages. Anything doing real work against an ATS (an agent analyzing a pipeline, an integration syncing candidates) needs the joins to hold. The sandbox generates a coherent org: jobs with interview plans and stages, candidates with applications, applications with stage history, feedback from real users, offers for late-stage candidates. Every id resolves.

  • Seeded and deterministic. --seed 42 produces the same org every run. CI can assert against it.
  • Stateful core. The 28 endpoints of the recruiting loop actually work: application.changeStage moves the candidate, writes history, and shows up in the next incremental sync. candidate.create, application.create, notes, and source changes all mutate the world.
  • Real envelope semantics. success/results envelopes, cursor pagination with nextCursor/moreDataAvailable, and syncToken incremental sync that returns only what changed since your last token, exactly the flow Ashby's sync guide describes.
  • Spec-example stubs for the rest. The other 145 endpoints return the success examples from Ashby's own published OpenAPI spec, not invented data. Six endpoints without spec examples return empty results. Endpoints that aren't in the spec 404.
  • Auth behaves like the real thing. Missing Basic auth is a 401. Any key is accepted (it's a sandbox), and apiKey.info says so.

Usage

ashby-sandbox [--port 3690] [--seed 1]

GET / describes the running sandbox: seed, world counts, and which endpoints are stateful vs stubbed.

Programmatic use (integration tests):

import { createSandbox } from "ashby-sandbox";

const sandbox = await createSandbox({ port: 0, seed: 42, quiet: true });
// sandbox.url -> http://localhost:<port>
await sandbox.close();

This package's own test suite runs the published ashby-ts client against the sandbox: pagination, incremental sync, stage changes, and error envelopes are all exercised through a real client.

Example: a pipeline health report

examples/pipeline-report.ts is the direct use case end to end: per-job totals, a stage-conversion funnel, median time in stage, and stuck candidates, computed from history joins with ashby-ts.

bun run report

With no configuration it reports on an in-process sandbox. The same script runs against a live org (ASHBY_API_KEY=...) or any running sandbox (ASHBY_BASE_URL=...), because there is nothing sandbox-specific in the analysis — that's the point.

The world

One fake company (a ~14-person recruiting org), 8 jobs across 6 departments, ~120 candidates, ~134 applications distributed across a 5-stage pipeline with realistic skew toward early stages, plus archived and hired outcomes, interview feedback with scores, candidate notes, and pending offers. Timestamps span the 90 days before a fixed base date, so the world is fully reproducible.

How it's built

Generated from the same vendored copy of Ashby's OpenAPI spec that generates ashby-ts: the spec defines the client on one side and the fake server on the other, and the client's test suite meets the sandbox in the middle. Stub responses are extracted from the spec's own examples at build time (bun run extract-examples).

Zero runtime dependencies; the server is node:http. Works in Node 18+ and Bun.

Notes

  • This is a development tool, not an emulator. Core-loop behavior is faithful (envelopes, pagination, sync, the common filters); long-tail endpoint behavior and validation are not. When your integration graduates to a real Ashby org, expect the real API to be stricter.
  • Not affiliated with Ashby.

MIT