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

@homeflare/alchemy

v0.4.0

Published

Custom Alchemy providers for Cloudflare, Proxmox, OpenBao, Forgejo and Talos.

Downloads

1,640

Readme

@homeflare/alchemy

Custom Alchemy providers for gaps the vendor SDK leaves.

bun add @homeflare/alchemy [email protected] [email protected] \
        @effect/[email protected] [email protected] [email protected]

Every one of those is required, and you also need an overrides block — see Peers below. The install succeeds without them and the import throws.

Why a custom provider at all. When Alchemy has no property for something, the alternative is a runbook step a human runs once — and a plan can never show a missing runbook step. Covering the gap with a resource means the drift is visible in plan like everything else.

R2BucketLock

An R2 bucket's lock rules, declared rather than applied by hand. A lock rule is a retention floor: while a rule covers an object, no API call, no lifecycle rule and no credential can delete it.

import { R2BucketLock } from '@homeflare/alchemy';
import { providers } from '@homeflare/alchemy/cloudflare';

export class BackupLock extends R2BucketLock('backup-lock', {
  bucketName: 'my-backups',
  jurisdiction: 'default',
  rules: [{ id: 'keep-30d', enabled: true, condition: { type: 'Age', maxAgeSeconds: 2_592_000 } }],
}) {}

Add the provider layer to your stack:

import { providers } from '@homeflare/alchemy/cloudflare';
// …then provide `providers()` alongside Cloudflare.providers()

Website.Astro / Website.Vite

House flags on Alchemy's own stacks — the two this estate actually ships.

import { astroWebsite, viteWebsite } from '@homeflare/alchemy/cloudflare';

const site = yield * astroWebsite('subnetcalc', { rootDir });
const app = yield * viteWebsite('aimto', { rootDir: webRoot });

⛔ Astro needs disable_nodejs_process_v2 — workerd process-v2 makes every page return [object Object]. Vite / TanStack Start does not. Alchemy injects @alchemy.run/frontend-frameworks/astro; do not add @astrojs/cloudflare.

⛔ Not Nextjs. Website.Nextjs hashes source and plans as create against a live Worker. Adopt that shape with Worker, not a helper here.

⚠️ The rule set is REPLACE, not merge. The API PUTs the whole set, so a rule omitted from rules is a rule deleted. That is the same shape as the Cloudflare API itself.

Deletion is refused by design. Removing a lock is removing a retention floor, which is the one operation this resource exists to make hard. It retains on destroy.

Credentials

CLOUDFLARE_API_TOKEN is read from the environment at call time, never at module scope.

Mint a short-lived, scoped token — do not reuse a long-lived one, and never a Global API Key. An empty value fails closed with a message saying so, because an empty render is a denied grant rather than a missing file, and Bearer + nothing 401s in a way that reads like a bad credential.

Peers — and one override you need

bun add @homeflare/alchemy [email protected] [email protected] \
        @effect/[email protected] [email protected] [email protected]

⚠️ Peers, not dependencies: Alchemy's resource registry and Effect's context both break if two copies load in one process.

Add this to your package.json, or the install works and the import throws:

{
  "overrides": {
    "effect": "4.0.0-rc.115",
    "@effect/platform-node": "4.0.0-rc.115",
    "@effect/platform-node-shared": "4.0.0-rc.115",
    "@effect/platform-bun": "4.0.0-rc.115",
    "rolldown": "1.2.8"
  }
}

🔴 Why, measured 2026-09-16 on 0.1.0 and re-checked 2026-09-17 against Alchemy 78. Effect's rc line is not semver-compatible with itself. Alchemy 78's peer is effect >= 4.0.0-rc.115; an unlocked @effect/platform-node-shared still floats to the next rc and breaks at import. Pin the whole set.

| what resolves | what happens | | ------------------------------------------------------------- | ------------------------------------------------------ | | Alchemy 77 + effect → rc.115 (measured 2026-09-16) | TypeError: Config.string is not a function at import | | @effect/platform-node-shared newer than the pinned effect | Cannot find module 'effect/ByteSize' | | rolldown → 1.2.9 via vite's ~1.2.6 (measured 2026-09-16) | GET …/rolldown-1.2.9.tgz - 404 at bun add | | no mime (measured 2026-09-17 against Alchemy 78) | Cannot find package 'mime' from cloudflare-runtime |

Alchemy 78 adapted to rc.115 — that first row is why we used to pin 112, not a reason to stay there. The override is still the only thing that holds the set together.

⚠️ @effect/platform-node is required, not optional: Alchemy's module graph reaches Cloudflare/Workers/WorkerBridge → @effect/platform-node/NodeServices even when you only import the Proxmox subpath.

⚠️ So is mime. Alchemy 78's @alchemy.run/cloudflare-runtime imported it without declaring it (measured 2026-09-17). 79 declares it; the peer stays so a consumer that followed the 78 README does not drop a required line.

⚠️ So is cloudflare. It was marked optional in 0.1.1, which claimed the /cloudflare subpath would degrade without it — measured 2026-09-16, the subpath does not load at all: Cannot find package 'cloudflare'. An optional peer should mean a feature is absent, not that an import fails.

License

MIT © Timothy Schneider