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

orly-repl

v0.1.0

Published

Interactive orlyscript REPL: type expressions and definitions, evaluated live against a running orlyi

Readme

orly-repl

An interactive orlyscript REPL against a running orlyi (#535). Type an expression, see its value; define a function, call it in the next entry; write through a POV and read it back — without hand-writing package files.

On npm as orly-repl (#540): npx orly-repl --package-dir ... anywhere orlyc and the server's package directory are reachable (see below — the docker image's repl mode is the zero-setup path).

$ orly-repl --package-dir /path/to/packages
orly-repl: connected to ws://127.0.0.1:8082/
pov 3f0e... (private, new); :help for help
orly> 1 + 2;
3
orly> double = (x * 2) where { x = given::(int); };
defined double
orly> double(.x: 21);
42
orly> (true) effecting { new <['k', 1]> <- 7; };
true
orly> *<['k', 1]>::(int);
7

How it works

There is no eval statement in the wire protocol, so the REPL drives the same loop a package author would, invisibly: every entry is folded into a synthetic package (repl_<pid>), compiled with orlyc, copied into the server's package directory, and installed at the next version number (a newer install re-points the unversioned name; old versions are deliberately never uninstalled, since uninstalling any version unregisters the whole name). Expressions are wrapped as a generated nullary method and called against the session's POV. Compile errors print the orlyc/g++ diagnostics and leave your definitions untouched.

The consequences of that design:

  • orlyc must be runnable from the REPL's host (ORLYC / --orlyc; default orlyc on PATH). Multi-word commands work, e.g. ORLYC="docker exec orly orlyc".
  • The server's package directory must be writable at the same path the server sees it (ORLY_PACKAGE_DIR / --package-dir).
  • Statements end with ;; entries may span lines (the prompt switches to ... until brackets balance and a ; closes the statement).

Configuration

| Flag | Env | Default | Meaning | | --- | --- | --- | --- | | --url | ORLY_URL | ws://127.0.0.1:8082/ | orlyi WebSocket url | | --package-dir | ORLY_PACKAGE_DIR | (required) | the server's package directory | | --orlyc | ORLYC | orlyc | orlyc command (may be multi-word) | | --pov <id> | | | join an existing pov instead of creating one | | --shared | | private | create a shared pov (updates promote globally) |

Commands at the prompt: :help, :defs, :drop <name>, :src (show the synthetic package source), :pov, :quit.

Against the docker image

The image ships orlyc but the compile/install loop needs a package directory both sides can see, so start the container with one mounted at an identical path, and run orlyc inside the container:

mkdir -p /tmp/orly-repl/packages && touch /tmp/orly-repl/packages/__orly__
docker run -d --name orly -p 8082:8082 -v /tmp/orly-repl:/tmp/orly-repl \
  ghcr.io/orlyatomics/orly --package_dir=/tmp/orly-repl/packages
npx tsc && node dist/index.js \
  --package-dir /tmp/orly-repl/packages \
  --orlyc "docker exec orly orlyc"

(Compiled .so paths land in the shared mount, so the container-side orlyc and the host-side REPL agree on where everything is.)

Building and joining agents

orly-repl --pov <id> ... attaches to a POV your agents (e.g. via clients/mcp) are already writing — the REPL then reads and writes the same live state, which makes it a debugger for agent shared memory.

Build: npm install && npx tsc. Smoke test (needs a built tree, see the repo README): npm run smoke.