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

@runablehq/runkit

v0.1.1

Published

The toolchain behind Runable app templates

Readme

@runablehq/runkit

The toolchain behind Runable app templates. Generated apps depend on this package instead of carrying platform lint config, convention rules, and tool versions in their own tree.

Commands

runkit lint checks structural conventions with konsistent, then lints with oxlint. It stops after konsistent if conventions fail, so the output stays short.

runkit lint --fix runs oxlint with --fix and skips konsistent, which has no autofix. A convention error should not block the rewrites oxlint can apply on its own.

What the app still has to provide

The app keeps an .oxlintrc.json at its root:

{
  "extends": ["./node_modules/@runablehq/runkit/oxlintrc.json"],
  "ignorePatterns": ["dist/**", "dist-electron/**", ".expo/**", "packages/web/public/runable.js"]
}

Both keys are required, for different reasons.

extends is what makes the shared config work at all. oxlint resolves overrides.files against the config that does the extending, so the globs in oxlintrc.json only match when they are pulled in from the app root. Pointing --config straight at this package instead would resolve every glob against node_modules, match nothing, and report success while enforcing none of the overrides.

ignorePatterns does not inherit through extends, so it has to be repeated here. Drop it and oxlint starts reporting on build output and vendored files.

jsPlugins behaves the opposite way. It resolves against the file that declares it, so oxlintrc.json points at this package's own lint-rules/ and needs nothing from the app.

Lint rules

lint-rules/ holds the custom oxlint plugin, registered under the template namespace:

  • asset-imports: web static assets belong in packages/web/public/, referenced by URL path.
  • protected-files: files under a __ path segment are template-managed and must match the hashes in the app's .runable/protected-files.json.

Both resolve paths against process.cwd(), because the rules ship inside node_modules and their own location says nothing about the app being linted. runkit walks up from the working directory to the nearest parent holding .runable/ and runs both tools from there, so the two agree on what the app root is no matter where the command was typed.

The rules are declared by the platform rather than the app: an app has no lint-rules/ of its own to edit, and no place to register another. This is a default, not a sandbox — an app that rewrites its .oxlintrc.json or edits the installed package can still opt out. protected-files covers the app's own __ files; keeping the toolchain itself honest is the image build's job, not this rule's.

To add a rule, create a file in lint-rules/, register it in lint-rules/index.mjs, and enable it in oxlintrc.json under template/.

Tool versions

oxlint and konsistent are pinned exactly. They decide what every generated app is held to, so upgrading either is a deliberate change to this package, not something an app can drift into. The versions here are independent of the ones the Runable monorepo uses on itself.