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

@fairway-kit/server

v0.2.0

Published

Dev kit backend for local agent-backed apps: durable, resumable agent chat over Node (SQLite), implementing the Agent Chat Protocol

Readme

@fairway-kit/server

The Node/TypeScript backend for fairway, a dev kit for building local, agent-backed applications with durable, resumable chat. Implements the Agent Chat Protocol and depends on @fairway-kit/protocol for the shared event types and fold. Pair it with @fairway-kit/client for an all-Node (Node + React) stack, or use the fairway-kit Python package instead — the wire protocol is identical.

import http from "node:http";
import { createAgentChat, EchoRunner } from "@fairway-kit/server";

const chat = createAgentChat({ dbUrl: "./chat.db", runner: EchoRunner });
await chat.start();          // opens the store, runs the startup orphan sweep
await chat.listen(8500);     // or: http.createServer(chat.handler).listen(8500)

Mount into an existing server instead — the handler is framework-agnostic node:http (Express req/res are node req/res):

app.use(async (req, res, next) => {
  if (!(await chat.handler(req, res))) next();
});

Runners

A runner is any async (ctx, emit) => TurnResult — the integration seam. createAgentChat invokes it; it never dictates how one is built, so you can plug in any agent. Runners, the toolkit for building them, and the bundled adapters live in @fairway-kit/agent. EchoRunner (re-exported here for convenience) exercises the whole path with no credentials.

import { createAgentChat } from "@fairway-kit/server";
import { claudeCodeRunner } from "@fairway-kit/agent/claude-code";

const chat = createAgentChat({
  dbUrl: "./chat.db",
  runner: claudeCodeRunner({ model: "claude-opus-4-8", auth: "api" }),
});

See @fairway-kit/agent for the Runner contract, the runnerFromStream pump for writing your own adapter in ~30 lines, and the permission-gate helpers.

Storage

SQLite by default (zero extra dependencies, via better-sqlite3). Postgres and MySQL are drop-in via the database URL — install the driver you use:

createAgentChat({ dbUrl: "postgresql://user:pass@host/db", runner });  // needs `pg`
createAgentChat({ dbUrl: "mysql://user:pass@host/db", runner });       // needs `mysql2`

fairway is single-writer by design — one process, one logical writer serialized by an in-process lock. The database is a storage choice, not a way to run multiple processes: the live job registry, SSE fan-out, and permission-gate futures all live in process memory. This is a dev kit for local agent-backed apps, not production multi-tenant chat infrastructure.

Attachments

Uploads land on local disk (independent of the database), default next to a SQLite file or ./fairway-attachments for a networked database. Files are served back as forced downloads with X-Content-Type-Options: nosniff, confined to the attachments directory. Pass attachmentsDir: null to disable uploads.

Full docs and a complete example app live in the repository.