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

@mochabug/adaptkit

v2.0.0-beta.19

Published

Create, build, emulate, and publish Mochabug Adapt apps

Downloads

1,450

Readme

@mochabug/adaptkit

Adaptkit is the Node.js 24 CLI for creating, extending, emulating, and publishing Mochabug Adapt apps.

Node.js 24 or newer is required on the development machine, including for init. The CLI rejects older Node versions before creating project files.

npm install --global @mochabug/adaptkit@latest
adaptkit init

Commands

adaptkit init [options]
adaptkit add [options]
adaptkit skill [--dir <project>]
adaptkit emulator setup
adaptkit emulator [--tag <tag>] [--no-open]
adaptkit emulator stop
adaptkit emulator logs
adaptkit emulate [--dir <project>] [--upload dist/upload.json]
adaptkit publish [--dir <project>] [--upload dist/upload.json] [--staging] [-c <client>]
adaptkit version patch
adaptkit version minor
adaptkit version major

init and add accept every scaffold choice directly. Supplied values bypass the wizard; an interactive terminal prompts only for missing choices. With --no-interactive or non-TTY stdin, missing required choices are errors. Invalid choices, names, folders, and program selections fail before files or dependencies change.

adaptkit init --dir ./my_app --name my_app --vertex greeting \
  --capabilities browser configurator --endpoints http --api connect \
  --frontend react --ssg --no-interactive

adaptkit add --dir ./my_app --name worker --capabilities external \
  --endpoints tcp --executor-program new --no-interactive

adaptkit add --dir ./my_app --name transform --capabilities none \
  --executor-program 1 --no-interactive

| Option | Applies to | | --- | --- | | --dir <directory> | Both commands; defaults to . | | --name <name> | App name for init, vertex name for add | | --vertex <name> | init first vertex | | --capabilities <values...> | browser, configurator, cron, external, or none alone | | --endpoints <values...> | Full executor set: http, tcp, datagram; required for Browser/External, forbidden otherwise | | --api http\|connect | Required for Configurator or executor HTTP; forbidden without HTTP roles | | --frontend typescript\|react | Required for Browser/Configurator, forbidden otherwise | | --ssg / --no-ssg | Explicit choice required for browser pages, forbidden otherwise | | --folder <path> | add; defaults to src/<name> | | --executor-program <number\|new> | add; required without interactive input | | --configurator-program <number\|new> | add with Configurator; required without interactive input, forbidden otherwise | | --no-interactive | Both commands; fail on missing choices without prompting, even in a terminal |

Browser requires http in the executor endpoint set. Datagrams require External. Connect is an API protocol over HTTP, not another executor endpoint. For example, --capabilities external configurator --endpoints tcp --api connect generates a TCP executor and a separate Connect configurator; it adds no executor HTTP service or executor proto.

Program numbers are one-based indices in the corresponding runtime.json array. new appends a program using js_1.0, Node 24 compatibility, 64 MB memory, 30 seconds wall time, and 100 ms CPU time. Existing definitions and array order are preserved. add is entirely local.

When Connect RPC is selected for the first time, add creates the Buf configuration and validated role-specific sample proto files, installs any missing local project dependencies, updates the build commands once, and generates the TypeScript. Later Connect vertices reuse that setup.

Agent skills

init installs the bundled adapt-app and adapt-emulator skills automatically. Install or refresh them in an existing project without running init:

adaptkit skill
adaptkit skill --dir ./my_app

Both commands install in .agents/skills at the nearest Git checkout root. Outside Git, they use the directory containing the nearest manifest.json. skill defaults to the current directory and also works from project subdirectories or a Git checkout root containing multiple apps. Each run replaces those two skill directories with the bundled files, including references. Claude Code gets a relative symlink for each skill in .claude/skills, pointing to the shared copy in .agents/skills. Claude Code explicitly supports symlinked project skill folders. If the system cannot create symlinks, Adaptkit installs copies in .claude/skills and refreshes both locations on each run. Other skills and instruction files remain unchanged.

Skills can be installed before an app exists. For an uninitialized app directory, adapt-app asks the user about the app and vertex structure, then runs adaptkit init before writing app code or configuration. App READMEs are public-facing instructions for non-technical users; keep developer setup and implementation details in separate documentation when needed.

Adaptkit updates

Interactive commands check npm for Adaptkit updates in a detached background process, at most once a day. A small notice after the command shows the current and available versions plus the appropriate install command for a global, project-local, or npx installation. Long commands can show a fresh result; short commands use it on the next invocation. Notices appear at most once a day for each available version. Updates always follow npm’s latest tag, regardless of the installed version’s suffix. No beta or other release channels are used.

Checks never delay commands for network access, and offline/cache failures stay silent. CI and non-interactive output skip both checking and notices. Set NO_UPDATE_NOTIFIER=1 or pass --no-update-check to opt out. Updates are installed only when you run the suggested command. Output uses the same subtle colors as Adapt Builder and respects NO_COLOR and redirected output.

Local emulator

Install Docker Desktop (or Docker Engine on Linux) and mkcert. On macOS, brew install mkcert nss also enables Firefox trust-store support. Start Docker, then run:

adaptkit emulator setup    # once per user; rerun to renew certificates
npm run emulator          # start in the background, wait until ready, open browser
npm run emulate           # build and upload
npm run emulator:logs     # follow logs; Ctrl+C leaves the emulator running
npm run emulator:stop     # stop and discard temporary state

Setup explains and installs local certificate trust using mkcert. It may ask for an administrator password or OS approval so the browser can trust app and configurator pages on *.emulator.localhost. Run Adaptkit as your normal user, without sudo. Certificates are private to your user under ~/.config/adaptkit/emulator/certs; only the server key/certificate and public CA certificate are mounted read-only into Docker. The CA private key stays with mkcert. Restart your browser after setup, and restart a running emulator after renewing certificates. Setup uses your installed tools and does not install Docker or mkcert or change Docker socket permissions.

The emulator image is about 1 GB. The Adapt runtime itself is only tens of megabytes; most of the size comes from FileForge's PDF and image-processing dependencies. When starting a new session, the default mochabug/adapt-emulator:latest always checks Docker Hub for updates, reusing cached layers. Version tags are immutable and are pulled only when missing locally:

npm run emulator -- --tag 1.0.6
# Equivalently: adaptkit emulator --tag 1.0.6

Startup waits for the emulator’s ready signal and checks that its local page responds before opening http://localhost:51001 in your browser. Use adaptkit emulator --no-open to skip opening a browser (also skipped in CI). The container keeps running after the command exits or the terminal closes. A startup failure or timeout points to adaptkit emulator logs. Ports 51001–51003 TCP and 51003 UDP are bound to localhost. Repeated starts report already running and preserve the current session, without pulling or restarting it, and reopen the ready emulator in your browser. Stop first to change tags or refresh latest.

adaptkit emulator stop shuts down services and removes the container, discarding uploaded apps, configuration, and run state while keeping the downloaded image. Repeated stops succeed with already stopped. One container named adapt-emulator is shared across projects in the selected Docker context. Adaptkit only manages containers bearing its own label; a conflicting name gets an actionable error. Unexpectedly exited containers retain their logs until the next start or stop. npm run emulate uploads to the running emulator; it does not start Docker.

If Docker is missing, install it and reopen your terminal. If the daemon is not ready, start Docker Desktop or your Docker Engine service and check your Docker context. On Linux, follow Docker's user-access setup if socket access is denied; do not run the whole workflow with sudo. Startup checks Docker and certificate access before downloading the image. Docker's original pull/start errors remain visible, including occupied ports, blocked certificate-directory sharing, unavailable tags, connectivity, and disk space.

Generated projects

init creates a project that builds without an adapt.config.ts:

manifest.json
runtime.json
README.md
package.json
tsconfig.json             # solution with separate environments
tsconfig.runtime.json
tsconfig.browser.json
tsconfig.tools.json
buf.yaml                  # when Connect RPC is selected
buf.gen.yaml              # when Connect RPC is selected
buf.lock                  # generated when Connect RPC is selected
proto/
  <app>/<vertex>/
    exec/exec.proto          # package <app>.<vertex>.exec
    config/config.proto      # package <app>.<vertex>.config
src/
  gen/<app>/<vertex>/         # generated when Connect RPC is selected
    exec/exec_pb.ts
    config/config_pb.ts
  <vertex>/
    vertex.json
    metadata.json
    executor.ts
    configurator.ts       # when selected
    ui/                   # for Browser or Configurator
      api.ts              # typed API objects and real requests
      api.mock.ts         # local mock responses
      styles.css          # linked from each HTML head
      <role>.html
      <role>.main.ts      # .tsx for React
      <role>.ssg.ts       # .tsx for React; only with SSG
      <role>.App.tsx      # React only; shared by rendering and hydration

The generated project explicitly installs npm's latest tag for the Adapt toolchain and application dependencies, with Node declarations kept on major 24. Scaffold installs explicitly include development dependencies and executable links, even if npm is configured to omit them. Initialization checks the local adapt-builder executable before reporting success. npm output and errors stream directly to stdout.

The generated README.md is a starter for public app documentation. Replace its placeholders with the app's purpose, setup and usage instructions, data use, connected services, limitations, and support information before publication.

The root TypeScript config references three independent projects:

| Config | Sources | Types | | --- | --- | --- | | tsconfig.runtime.json | Runtime entries and their imports | Builder runtime (includes Node 24), TypeScript DOM | | tsconfig.browser.json | UI and UI shared code; excludes SSG and tests | TypeScript DOM and vite/client, no Node | | tsconfig.tools.json | Local config, SSG, tests, and scripts | Node, DOM and Vite |

These are self-contained project configs, copied by Adaptkit. The root owns common compiler options and excludes SSG/tests from application projects; the browser and runtime configs inherit those exclusions. Tools explicitly reset exclude so local SSG/tests are included. Put shared overrides in the root and environment-only settings in the relevant leaf. Arrays such as types and include replace inherited arrays. For Vitest globals, set the tools config's types to ["node", "vite/client", "vitest/globals"]; install Vitest when adding tests. DOM declarations supply types; DOM-dependent tests also need the test runner's DOM environment.

The backend uses standard DOM declarations for Fetch types required by Connect RPC. These declarations also support server rendering; they do not provide browser globals such as window or document at runtime. Keep browser API use in browser code. Generated projects install the latest Node 24 typings to match their node24 runtime profile.

Native handler and environment types are imported from @mochabug/adapt-builder/runtime. Shared protobuf and utility code stays neutral and is checked in each environment that imports it. The builder checks all three projects with strict application checking and skipLibCheck: true by default. Dependency declarations still supply application types but are not checked themselves. Environment configs store TypeScript's caches in node_modules/.cache/typescript, with no root .tsbuildinfo files or dedicated Git ignore rule. Native outbound calls use env.service.http(url, options) or http(url, options) from mb:http; write the body through the returned exchange. See the builder's outbound examples for configured bindings, direct URLs, and transport options.

Native outbound modules each have one named export:

import { http } from 'mb:http';
import { connect } from 'mb:connect';
import { datagram } from 'mb:datagram';

Call these from an active handler. connect opens a raw TCP connection; datagram opens an RFC 9221 QUIC DATAGRAM session. Connect RPC remains an HTTP operation. Handler and socket types come from @mochabug/adapt-builder/runtime.

Useful scripts are ready immediately:

npm run build
npm run build:staging
npm run build:emulate
npm run dev
npm run emulate
npm run publish
npm run publish:staging
npm run add

Connect projects also provide npm run generate for locked protobuf generation and npm run protobuf:update for explicitly refreshing Buf dependencies. Normal build and dev commands generate sources without changing buf.lock.

Browser code imports executorApi or configuratorApi from ui/api.ts and calls methods such as await executorApi.greet({ name: "Adapt" }). api.ts selects api.mock.ts once during local development. Connect uses the generated service types for both its real client and its in-memory mock transport; mock handlers satisfy ServiceImpl<typeof Service>. Plain HTTP declares an Api interface in api.ts, which the mock imports with import type. Neither needs another API file or custom builder configuration. All artifact builds exclude the mocks.

External HTTP routers advertise HTTP/3 by default. Browser vertices always have one executor HTTP entrypoint. Browser and External capabilities share that entrypoint and its <VertexName>ExecService; they do not create duplicate hosts or services. Configurators use a separate <VertexName>ConfigService. Executor and configurator services are always emitted into separate proto files and generated modules. Their package and folder namespace is only <app>.<vertex>.exec or <app>.<vertex>.config—there is no framework root or API-version directory. Both roles use the minimal GreetRequest and GreetResponse message names. Connect registrations expose Connect, gRPC, and gRPC-Web, validate requests with Protovalidate, and use the role-specific browser client from ui/api.ts. Browser clients explicitly use the Connect transport; the runtime selects Connect, gRPC-Web, or gRPC for each incoming client. A Connect scaffold does not add a duplicate conventional API route; non-Connect browser paths serve the frontend. The HTTP API example uses /greet. Raw TCP and datagram handlers use the builder's runtime contracts directly.

Generated HTTP and Connect operation routes require Adapt bearer authorization. Browser and configurator page shells remain public for initialization. Add new operation routes to the protected paths. External-only HTTP routers protect all routes by default. Raw TCP and datagram scaffolds close connections until you implement protocol authorization.

Generated proto comments call out the transport boundary: browser clients do not support client- or bidirectional-streaming RPCs. An External-only executor keeps full gRPC enabled over HTTP/2, including the complete streaming surface; the HTTP/3 alternative-service advertisement does not replace HTTP/2.

Environments

npm run dev is local Vite development: mode development, with api.mock.ts. Production, hosted staging, and emulation are full artifact builds using mode production and real APIs. CDN/destination differences never select mocks. The generated scripts keep the build and destination aligned:

| Workflow | Browser CDN | Upload service | Authentication | | --- | --- | --- | --- | | npm run publish | https://cdn.mochabug.com/adapt/plugins | https://adapt.mochabugapis.com | OAuth over HTTPS | | npm run publish:staging | https://cdn-dev.mochabug.com/adapt/plugins | https://adapt-dev.mochabugapis.com | OAuth over HTTPS | | npm run emulate | https://localhost:51002 | http://localhost:51001 | none |

adaptkit publish --staging selects the staging authorization, audience, account, and upload services. Each workflow owns its destination and transport. Production and staging require verified TLS; emulation uses the local HTTP API without authentication. There are no endpoint or insecure-TLS overrides.

Publishing opens your browser for sign-in and always prints a link you can open manually. If the browser launcher fails, Adaptkit reports the error and keeps waiting for sign-in through that link. Sign-in allows 10 minutes; the browser launcher allows 60 seconds, and the token exchange allows 2 minutes. OAuth and network errors are reported in the terminal. Press Ctrl+C to cancel and close the local callback listener.

Staging publishing accepts the optional -c, --client <id> OAuth client override. Choose a custom staging organization when building, using Adapt Builder's -o:

npm run build:staging -- -o YOUR_ORGANIZATION_ID
adaptkit publish --staging -c YOUR_CLIENT_ID

Adapt Builder 2.0.0-beta.5 or newer records the build organization in upload.json. Adaptkit reads that staging organization, applies it to the manifest in memory before validation, and sends it in the upload's start message. Source manifests are never rewritten. Adaptkit has no organization override option.

Both tools' overrides are optional and only allowed with --staging. Omitting the builder's -o uses the manifest organization; omitting -c uses the default OAuth client. Older artifacts without an organization use the source manifest. Production and emulation reject artifacts whose organization differs from it.

Publishing streams protobuf messages over gRPC/HTTP/2 to /mochabugapis.adapt.plugins.v1.PluginService/UploadPlugin on the shared API origin. Mochabug's public Connect handler serves this RPC alongside the REST API.

Program grouping

runtime.json partitions vertices into executor and configurator programs. Every definition owns its RuntimeSpec and resource limits. Vertices in the same definition share one emitted program; choosing “Create a new program” isolates the new vertex.

{
  "executors": [
    {
      "vertices": ["receive", "transform"],
      "runtime": {
        "runtime": "js_1.0",
        "jsCompatibility": "node24"
      },
      "maxMemoryMb": 64,
      "wallTimeSec": 30,
      "cpuTimeMs": 100
    }
  ],
  "configurators": []
}

Runtime sources export named handlers such as internal_http, external_http, external_connect, and external_datagram. Internal ingress is HTTP-only. The builder generates the final <vertex>_<internal|external>_<protocol> program exports.

DATAGRAM handlers use RFC 9221 QUIC DATAGRAM ingress through external_datagram.datagram(socket, env, ctx). Returning from a TCP or datagram handler ends that session; await its receive/send loop.

Browser and resources

Each ui/<role>.html is a native Vite 8 HTML entry. Its .main module, imports, CSS, framework plugins, and assets use the standard Vite pipeline. The completed HTML is private under assets/browser/<vertex>/<role>/index.html; public browser output and public/ files are emitted under cdn/browser/.

Static rendering is opt-in during init and add. When selected, Adaptkit creates a matching SSG module for every generated browser page. Plain TypeScript pages use ui/<role>.ssg.ts. React pages use ui/<role>.ssg.tsx, render <App /> with renderToString, and bootstrap the result with hydrateRoot; React pages without SSG continue to use createRoot. Every SSG default export returns the HTML inserted at the single <!-- adapt:ssg --> marker, following Adapt Builder's .ssg discovery convention. Each role has its own parameterless renderer: export default function render(): string. The executor and configurator own their markup; there is no role dispatcher. Plain TypeScript pages without SSG put that markup directly in HTML.

All pages link styles.css from their HTML head. Its prefers-color-scheme media query chooses light/dark CSS from the embedding frame's color-scheme, before JavaScript executes. This is identical for static and client-rendered pages; there are no theme messages or server substitutions. Electron hosts use nativeTheme.themeSource application-wide with the same app CSS.

Each browser entry calls init({ resize: true }) once. The SDK reports immediately and as content changes; the parent decides whether to apply those reports. Set resize: false for viewport-height layouts such as height: 100vh. Theme support is independent of resize reporting.

Runtime JSON imports are bundled by default. .txt, .bin, and .wasm imports are copied as relative program modules. Advanced projects can add adapt.config.ts to use ordinary Rolldown module types/plugins and Vite options while retaining Adapt-owned entrypoint, target, and output layout.

Upload artifact

npm run build writes dist/upload.json. It contains only build-owned upload information: the target environment, CDN/assets prefixes, program modules, and executor/configurator entrypoints with their runtime descriptors. All paths are relative to the project directory containing manifest.json.

The command and artifact environments must match: normal publish accepts only production, publish --staging accepts only staging, and emulate accepts only emulation. Adaptkit checks this before authentication or RPC setup.

publish and emulate:

  1. read that descriptor before authentication or RPC setup;
  2. read manifest.json and every src/**/vertex.json from the selected project;
  3. normalize vertex references and Protovalidate the manifest, vertices, metadata, and completed StartUpload contract;
  4. upload the exact declared program modules, files below the declared CDN/assets prefixes, and source-owned README/logo/config/metadata files.

Adaptkit never infers program entrypoints or legacy bundle names and never rebuilds the app. Vertex metadata JSON is encoded to protobuf bytes while streaming. -d, --dir selects the project root; --upload overrides the descriptor path relative to that root.

All upload entrypoints resize raster logos in memory: app logos to 80×80 pixels and vertex logos to 40×40, with a centered crop and the original image format. A source shared by both roles uses 80×80. SVGs are sent unchanged. Processed logos must fit the 25,600-byte upload limit; errors identify the file. Source files, logo references, and built programs remain unchanged.

Publish and emulation print only their meaningful phases—artifact validation, hosted authentication when applicable, and transfer—followed by one ✓ completion line. Failures use one ✗ diagnostic without dumping a stack trace; Commander owns standard option and usage errors.

The upload primitives are also exported for tests and integrations:

import { readUploadArtifact, sendArtifact } from "@mochabug/adaptkit/upload";

const artifact = await readUploadArtifact({
  root: ".",
  upload: "dist/upload.json",
  expectedEnvironment: "production"
});

License

Apache-2.0