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

@izagood/avcs-server

v0.7.0

Published

Self-hostable multi-repo server for the avcs protocol — a transport-agnostic protocol engine with SPI seams, plus a stdlib http binding.

Readme

avcs-server

CI npm node license

A self-hostable, multi-repo server for the avcs protocol — and, for anyone building on top of it, a transport-agnostic protocol engine with SPI seams.

The avcs conformance suite is the definition of done here: a protocol level is "supported" exactly when the suite passes against a running instance. CI runs it on every commit, so the green badge above is the compatibility claim.

Quick start

Run a server (no config, no registration step):

npx @izagood/avcs-server
# avcs-server listening at http://0.0.0.0:8420  (data: ./data)

Point a client at it. A repo lives at /<org>/<repo> and exists as soon as something is pushed:

avcs remote add origin http://localhost:8420/acme/web
avcs push origin                                          # or: avcs sync origin
avcs clone http://localhost:8420/acme/web ./checkout

Configuration

The CLI is configured entirely by environment:

| Variable | Default | Meaning | |---|---|---| | AVCS_SERVER_DATA | ./data | Data root — one object store per <org>/<repo> | | PORT | 8420 | Listen port | | HOST | 0.0.0.0 | Bind address | | AVCS_SERVER_GATED | unset | 1 ⇒ writes require a valid AVCS-Sig by a resolvable member |

The default deployment is open (writes unsigned, reads public), which fits a trusted network. Anything else should set AVCS_SERVER_GATED=1, whose member directory is core-native: member:<keyId> refs pointing at Membership objects already in the store. Read tokens, custom key directories and product hooks are for embedders — see Embedding.

Protocol support

Every level below is verified by the avcs conformance suite in CI, with zero skips. Extensions sit outside the cumulative level ladder (avcs docs/26 §11) — they are measured only when advertised and never change a level's result.

| Level | Endpoints | Status | |---|---|---| | core | GET /have · GET /objects/:oid · POST /objects | ✅ conformance-verified | | sync | GET /sync (incremental cursor) · POST /objects/batch · POST /objects/fetch | ✅ conformance-verified | | governance | GET /refs · POST /finalize (head CAS) | ✅ conformance-verified | | queue | POST /integrate · GET /integrations/:ticketId · GET /events (long-poll) | ✅ conformance-verified | | reduced (extension) | GET /reduced · GET /reduced/blob/:oid — derived state for clients that do not replicate | ✅ conformance-verified |

GET /version advertises the capabilities actually composed in, and GET /healthz answers outside any repo prefix. To re-run the suite against your own instance, from a checkout of the avcs repo:

AVCS_CONFORMANCE_URL=http://localhost:8420/acme/web npm run conformance

The judgement plane (finalize / integrate) is delegated to the avcs library's Repo: a queue verdict must be a pure function of objects + Protection, and a second implementation of that function is exactly how two servers drift apart.

The derived-state plane (GET /reduced, docs/26 §6-4) is delegated the same way, to Repo.materialize, so a client that does not replicate — a web UI, a bot, another language — reads exactly what a replica would compute: statuses, conflicts, head ops, treeHash, and the path → blob-oid tree map (blob bytes come from the ordinary GET /objects/:oid; merge results that exist in no store come from GET /reduced/blob/:oid). The answer is not an authority — replicas prefer their own reduce. ETag / If-None-Match make polling free.

Embedding

This package is the protocol and nothing else. Everything a hosted product adds on top — accounts, quotas, metering, webhooks, custom storage — enters through SPI seams instead of a fork, so the protocol implementation stays in one place and cannot drift:

import { startAvcsServer } from "@izagood/avcs-server";

await startAvcsServer({
  dataDir: "./data",
  gated: true,                     // writes require an AVCS-Sig by a resolvable member
  readAccess: "token",             // reads require a bearer token (or a member signature)
  identity: myAccountSystem,       // IdentityProvider: keys, revocation, read tokens
  hooks: {                         // product lifecycle around every write
    beforeWrite: (ev) => quota.check(ev),      // veto: 402 / 403 / 429 (+ retry-after)
    afterWrite: (ev) => meterAndNotify(ev),    // best-effort: metering, webhooks, audit
  },
  storageFor: (repo, dir) => myBackend(repo),  // StorageBackend: default is the library's ObjectStore
  judgeFor: (repo, dir) => myJudge(repo),      // JudgementBackend: return null to not serve the plane
  reduceFor: (repo, dir) => myReducer(repo),   // ReductionBackend: return null to not serve /reduced
});

| Export | What it gives you | |---|---| | @izagood/avcs-server | startAvcsServer(opts) — the stdlib http server, batteries included | | @izagood/avcs-server/engine | RepoEngine — every endpoint as (raw request parts) → { status, body } | | @izagood/avcs-server/spi | The seam types: StorageBackend, JudgementBackend, ReductionBackend, IdentityProvider, Hooks |

The engine has no node:http and no framework in it, so binding it to Fastify, Express or a serverless handler means reimplementing src/server.ts — about 100 lines of URL parsing and body collection — and none of the protocol.

Capability flags follow composition honestly: no judge ⇒ integrate: false and a 404, no reducer ⇒ reduced: false and a 404 — which the protocol defines as "fall back", not "error". Auth verification is the library's verifyAuth (docs/26 §7); this server only wires the directory, and credentials are scope-checked per repo so a signature captured for one tenant is refused on another.

What this is (and is not)

avcs-server is the deployable middle of the avcs world: more than the reference startHub embedded in the library (single-repo, meant for tests and embedding), and deliberately less than a hosted product — no web UI, no SSO, no CI/CD orchestration, no billing. It stores objects, answers the protocol, and stays small enough to read.

It is an independent implementation, written from the protocol documents (26 — Server protocol, 24 — Canonical interop) and the published @izagood/avcs library. Object identity, the canonicalization gate and group-committed durability all come from the library — this repo adds multi-repo routing, persistence layout and the HTTP surface, and re-derives none of the invariants.

Development

Requires Node ≥ 22.6 (TypeScript runs directly via type stripping — no build step for dev).

git clone https://github.com/izagood/avcs-server.git && cd avcs-server
npm ci
npm test          # unit + level tests
npm run typecheck
npm start         # AVCS_SERVER_DATA=./data PORT=8420 by default

Commits follow Conventional Commitsfeat: and fix: on main publish a release automatically. Issues and PRs are welcome at izagood/avcs-server; protocol questions belong in the avcs repo.

License

Apache-2.0