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

@econ-v1/app-sdk

v5.26.1

Published

TypeScript SDK for building Node mini-app plugins (Bun runtime) on the Lightning-powered marketplace daemon

Readme

@econ-v1/app-sdk

Status: 1.0.0-experimental — API surface is frozen pending validation by at least two first-party packages. Breaking changes between 1.0.0-experimental.* releases are possible. Pin to an exact version in production.

TypeScript / Bun SDK for building Node-App plugins for the Node Lightning-powered marketplace daemon. Apps run as separate Bun processes and talk to the host over a Unix-domain socket using a JSON-newline protocol.

What it gives you

  • An abstract NodeApp class — extend it, declare metadata, and implement the hooks you need.
  • A declarative route() helper — register HTTP handlers with built-in scope checks (defense-in-depth on top of the host's manifest enforcement).
  • invokeCapability() — call any capability registered with the host's capability router.
  • publishEvent() — publish namespaced domain events to the host event bus.
  • host.{trace,debug,info,warn,error} — file-backed structured logging.

Quick start

bun add @econ-v1/[email protected]
import { NodeApp, runNodeApp, type AppRequest, type AppResponse } from "@econ-v1/app-sdk";

class MyApp extends NodeApp {
  readonly metadata = {
    name: "my-app",
    version: "0.1.0",
    author: "Me",
    description: "Hello-world Node-App",
    capabilities: ["http_handler"],
  };

  async init() {
    this.route("GET", "/hello", { requiredPermissions: [] }, async () =>
      this.json({ hello: "world" }),
    );
  }
}

runNodeApp(new MyApp());

The host launches the Bun process, supplies a Unix socket via the NODE_APP_SOCKET environment variable, and routes proxied HTTP requests, events, and capability calls over the socket.

Building for production

@econ-v1/app-sdk is itself a shared dependency in the Node deb (installed once at /usr/lib/node/shared/node_modules/@econ-v1/app-sdk), so it's not bundled into your app's dist/index.js. The build pipeline handles this automatically — you don't have to do anything special.

Your app's other deps land in one of three buckets:

| Where | When | |---|---| | Bundled into dist/index.js (default) | Pure-JS deps; tree-shaken + minified | | Shared at /usr/lib/node/shared/node_modules/ | Dep is in the curated SHARED_EXTERNALS list (LLM SDKs, this SDK) | | Private at <your-app>/node_modules/ | You opt in via manifest.json#nodeApp.privateRuntime (native bindings, version overrides) |

Opt into a private dep by editing your manifest.json:

{
  "name": "my-app",
  "version": "0.1.0",
  "entrypoint": "dist/index.js",
  "nodeApp": {
    "privateRuntime": ["better-sqlite3"]
  }
}

Use privateRuntime only for packages with native bindings or version conflicts with the shared tree — each entry adds its full installed size to your app. See the canonical reference at docs/app-development/12-typescript-dependencies.md for the full bundling and resolution model.

Build command

# Inside the node monorepo:
bash infra/scripts/build-bun-app.sh modules/my-app dist/build-aarch64/builtin-apps/my-app

# As a downstream app (after publishing):
bunx @econ-v1/app-sdk build .

Defense-in-depth scope checks

this.route(
  "POST",
  "/admin/**",
  { requiredPermissions: ["payments:write"] },
  async (req) => this.json({ ok: true }),
);

The host already enforces endpoint_policies from your manifest before the request reaches the app — route() re-checks request.caller.granted_permissions as a second line of defense.

Calling host capabilities

import { invokeCapability } from "@econ-v1/app-sdk";

const response = await invokeCapability({
  id: crypto.randomUUID(),
  capability: "core.storage.get",
  payload: { key: "user_pref" },
});

Publishing events

import { publishEvent } from "@econ-v1/app-sdk";

publishEvent("my-app.user_created", { userId: 42 });

Event names must be namespaced with the app name (my-app.*); the host rejects un-namespaced events.

ABI compatibility

The TypeScript SDK targets Node Host API v1 over IPC. The wire format is independently versioned but tracks the same semantics as the C ABI used by native (Rust / Go / C / Zig) apps. See core/host-abi-v1/include/node-host-api-v1.h for the C surface.

License

Licensed under either of

  • Apache License, Version 2.0
  • MIT License

at your option.