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

@lastshotlabs/slingshot-runtime-node

v0.0.2

Published

Node.js runtime implementation for Slingshot

Readme


title: Human Guide description: Human-maintained guidance for @lastshotlabs/slingshot-runtime-node

@lastshotlabs/slingshot-runtime-node is the Node.js runtime implementation for Slingshot. Pass the return value of nodeRuntime() to defineApp({ runtime }) in your app.config.ts.

What It Provides

  • passwordargon2 (peer dep) for argon2id hashing and constant-time verification
  • sqlitebetter-sqlite3 (peer dep) opened in WAL mode with synchronous API
  • server@hono/node-server (peer dep) wrapping Node http.Server; TLS via opts.tls; WebSocket via ws peer dep
  • fsnode:fs/promises with ENOENT-safe readFile and access-based exists
  • globfast-glob (peer dep) with dot: false by default

Minimum Setup

import { defineApp } from '@lastshotlabs/slingshot';
import { nodeRuntime } from '@lastshotlabs/slingshot-runtime-node';

export default defineApp({
  runtime: nodeRuntime(),
  port: 3000,
});

Peer Dependencies

All peer deps are loaded lazily via dynamic import() at first use, not at module import time. Missing deps surface at the first call to the affected capability.

| Capability | Peer dep | | ---------- | ------------------- | | password | argon2 | | sqlite | better-sqlite3 | | server | @hono/node-server | | websocket | ws | | glob | fast-glob |

Operational Notes

  • readFile() returns null on ENOENT. All other errors (EACCES, EISDIR, etc.) are re-thrown — they are not silently swallowed. fs.exists() uses fs.access and returns false for any error, including permission errors, so it does not distinguish ENOENT from EACCES.
  • SQLite databases are opened in WAL mode (PRAGMA journal_mode = WAL). Run your application's migration step before any reads or writes. The runtime does not run migrations itself.
  • better-sqlite3 is a native CJS addon and is loaded via createRequire (not dynamic import()) so it works correctly in Node ESM where bare require is unavailable.
  • password.hash() defaults to argon2id. The hash output includes the algorithm identifier so it is forward-compatible if the algorithm default changes.
  • WebSocket upgrade uses a pending-upgrade map keyed by sec-websocket-key. Upgrades that are not completed within the timeout period have their socket destroyed automatically. The timeout defaults to 30 s and is configurable via upgradeTimeoutMs in the server options.
  • server.publish(channel, message) broadcasts only to open (readyState === 1) sockets; closed sockets in a channel are silently skipped.
  • TLS is supported via opts.tls.key and opts.tls.cert. Pass PEM strings or Buffer values.

Gotchas

  • connection.port must be a number, not a string. Env-var values need explicit coercion: port: Number(process.env.PORT).
  • glob.scan() returns paths relative to cwd, not absolute. Join with cwd when you need absolute paths for subsequent file operations.
  • stop(true) calls server.closeAllConnections() (Node 18.2+ API) to force-close active connections. Pass false (or no argument) if you want graceful drain.
  • argon2.verify() returns false rather than throwing for malformed hash strings.

Key Files

  • src/index.ts