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

asset-oven

v0.2.0

Published

Lazy, content-hashed asset middleware for Bun — local asset paths in server-rendered HTML just work.

Readme

asset-oven is a lazy, content-hashed asset middleware for Bun — local asset paths written straight into server-rendered HTML just work, no bundler config, no manifest, no build step to remember to run.

import { Hono } from "hono";
import { builder } from "asset-oven/hono";

const app = new Hono();
app.use(builder({ root: import.meta.dir, publicPath: "/assets" }));

app.get("/", (c) => c.html(`<script src="/client.ts" type="module"></script>`));

export default app;

On the first request that renders /client.ts, asset-oven bundles it with Bun.build, content-hashes the output, rewrites the tag to /assets/client-a1b2c3d4.js, and serves it with a long-lived immutable cache header — all inline in the response, no separate build command.

Install

bun add asset-oven

Pick the adapter for your server:

// Hono
import { builder } from "asset-oven/hono";
app.use(builder({ root: import.meta.dir, publicPath: "/assets" }));
// plain Bun.serve
import { withAssets } from "asset-oven/bun";
const fetch = withAssets(myFetchHandler, {
	root: import.meta.dir,
	publicPath: "/assets",
});
Bun.serve({ fetch });

Then just reference assets by their on-disk path in your HTML — <script src="/client.ts">, <link rel="stylesheet" href="/styles.css">, <img src="/logo.png"> — and asset-oven handles the rest.

Features

  • Zero-config asset paths 📝 — write src="/client.ts" in your JSX/HTML like it's a static file; no imports, no manifest to look up.
  • Lazy build + hash + cache ⚡ — assets are built on first request, not ahead of time; concurrent requests for the same not-yet-built asset are deduped into a single build.
  • Nested assets just resolve 🔗 — a JS import of an image or a CSS url() background produces its own hashed URL automatically, via Bun.build's own dependency graph.
  • Real static-file serving 📦 — Range requests, HEAD, and immutable long-lived caching headers, so video/audio scrubbing and CDN caching work correctly.
  • Two thin adapters 🔌 — a Hono middleware (asset-oven/hono) and a plain Bun.serve fetch wrapper (asset-oven/bun), both backed by the same framework-agnostic AssetBuilder core.
  • Sensible defaults, fully overridable ⚙️ — cache-retry timing defaults off NODE_ENV, and the raw Bun.build config (minify, sourcemap, plugins, define, etc.) can be passed straight through.

Configuration

AssetBuilderOptions, accepted by both adapters and the AssetBuilder core:

| Option | Default | Description | | ------------------ | -------------------------------------- | ------------------------------------------------------------------------------------- | | root | process.cwd() | Directory local asset paths are resolved against. | | publicPath | "" | Prefix prepended to every hashed asset URL. | | cacheDir | a random os.tmpdir() subdir | Output directory for built/copied assets; wiped on boot. | | build | {} | Merged into every Bun.build call — e.g. minify, sourcemap, plugins, define. | | negativeCacheTtl | 60000ms in production, else 5000ms | How long a failed/missing asset lookup is cached before retry. |

Examples & source

Full runnable examples (Hono, plain Bun.serve, and nested-asset resolution) live in the GitHub repo.

License

MIT