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

@unoverse-platform/base

v0.3.16

Published

The Unoverse YAML runtime: node manifests, rx definitions, and the platform surface a node sees

Readme

@unoverse-platform/base

The node runtime. Everything needed to run a node, split out so a box that only runs nodes doesn't need the whole server.

src/manifests/   YAML nodes: reading them, and performing them
src/template/    the expression sandbox, and Handlebars
src/platform/    what a node can see: execution context, redis, the plugin API
src/plugins/     finding, installing and loading node packages

Why this package exists

A node used to be a TypeScript package installed from npm into a running universe. That worked, and it cost three things.

Security

Installed code can do anything the process can. Read the environment, open a socket, post a credential somewhere. Nothing about "it came from npm" prevents that, so the only real control was trusting whoever published it.

A YAML node cannot execute. There is no code in it to run, which means the question changes from do we trust the author to what is this allowed to reach. That question has an answer written down: allowedHosts in the node's package.yaml names every host it may call, and the runtime refuses the rest.

So a node from someone you have never met is safe to accept, because the worst it can do is call a host it declared in writing.

Flexibility

One runtime serves every vendor. Adding an integration means writing YAML, not publishing a package, so a universe can gain a node without a release, a build or a deploy.

Capabilities compound. AWS request signing was written once, in about 200 lines; DynamoDB, S3 and Bedrock followed as YAML, and Textract and Comprehend now need nothing new at all. Every node written afterwards inherits retries, pagination, batching and job polling for free, because they live here rather than in each node.

Speed

No SDK weight, no install step, no per-node build. A node is text that is read and performed. Two AWS packages that were 2,700 lines of TypeScript across four SDK clients are now 1,150 lines of YAML over 200 lines of shared code.

The rule that holds it together

YAML can only name capabilities that already exist here. It can say "sign this with AWS SigV4" because that is implemented. It cannot say "run this code", because there is nowhere to put code. nodes/_schema/api.schema.json is the list, and a test fails if anything in it has no implementation, so the two cannot drift apart.

How a node works

A node used to be a TypeScript package published to npm. Now it's YAML describing an API call, and the code in here makes that call.

- name: query
  method: POST
  url: "return 'https://dynamodb.' + credentials.awsCredential.region + '.amazonaws.com/'"
  auth: { scheme: awsSigV4, service: dynamodb }
  headers: { X-Amz-Target: DynamoDB_20120810.Query }
  transport: json
  encoding: dynamodbJson

Every one of those keys names something implemented here. awsSigV4 signs the request, json reads the reply, dynamodbJson converts values to DynamoDB's type tags.

YAML can only name what already exists. There's nowhere to put code, which is what makes a manifest safe to accept from someone else.

Capabilities

nodes/_schema/api.schema.json is the list. A test walks every value in it and fails if anything has no implementation here, so the schema can't drift ahead of the code.

| | | |---|---| | auth | bearer basic apiKeyHeader apiKeyQuery oauth2ClientCredentials awsSigV4 | | transport | json text xml headers binary sse | | encoding | dynamodbJson binary | | loops | paginate (cursor / page / offset), chunk, poll | | other | state, presign, toolExchange, narrate |

Adding one means implementing it here first, then adding the value to the schema.

Adding a dependency

One question: does it make requests for a particular vendor?

| | example | verdict | |---|---|---| | generic algorithm or format | @smithy/signature-v4, fast-xml-parser, @aws-sdk/util-dynamodb | fine | | vendor client | @openai/agents, @aws-sdk/client-dynamodb, @pinecone-database/pinecone | no |

A vendor client can't help anyway. This package is one piece of code serving every node, so a DynamoDB client is useless to a Textract manifest. You'd need one per vendor, plus a branch to choose between them, which is the adapter-per-vendor pattern manifests replaced.

For scale: src/manifests/runtime/aws.ts is 221 lines and covers signing, presigning and type tags for all of AWS. It replaced four SDK clients and about 2,700 lines of TypeScript across two node packages.

Two cases that come up:

  • @aws-sdk/util-dynamodb has a vendor's name and still belongs. It makes no calls and holds no client. It's a data format, like XML, that one vendor happened to invent. It also can't move into YAML, because the conversion recurses and the sandbox has no way to define a function that calls itself.
  • The OpenAI Agents SDK was deliberately removed. What it gives you is a loop, not a capability, and OpenAIAgent runs that loop from api/toolExchange.yaml. Adding it back recreates the drift where each model family hand-wires its own harness.

Installing: two paths

Manifests are data. Install writes a database row and flips a flag. No npm, no download, nothing runs. Developers can publish manifests freely because YAML can't execute. What bounds one is allowedHosts in its package.yaml, so it can only call hosts someone approved in writing.

Code packages are code. Install runs npm install, which can execute, so it's bounded by provenance in src/plugins/install.ts:

  • the scope must be @unoverse-platform/
  • the version must really be a version. npm reads name@spec, where the spec may be a URL, git ref or file path, so @unoverse-platform/x@https://evil.example/p.tgz would pass a name-only check and install code from anywhere.
  • execFile, not exec, so arguments never reach a shell

Code packages are legacy and shrinking. Manifests are the direction.

Notes

  • primeTemplating() is a no-op kept for its callers. It used to await a dynamic import.
  • src/template/ holds the security boundary. SafeExpression is the sandbox every expression runs in, and the Handlebars resolver registers the helpers manifests use (eq, toJSON, filter, contains). Neither may be replaced with a direct call to Handlebars or a hand-rolled evaluator.
  • Nothing here may import by source URL. A path in a string can't be type-checked, so it breaks at run time while the build stays green. There's a test enforcing it.