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

wrangler-studio

v0.1.1

Published

Cloudflare-native admin UI for D1, KV, R2, Durable Objects, and better-auth data

Readme

Add with a coding agent

Open your coding agent in an existing Cloudflare Workers project and paste the prompt below. The agent will inspect the project, mount Wrangler Studio using its existing conventions, add a focused test, and leave you with a reviewable diff. It should not commit, push, deploy, or change production credentials unless you explicitly ask.

Or generate a prompt tailored to the current project:

npx wrangler-studio init

The initializer detects the Worker entry point, framework, package manager, Wrangler configuration, and configured bindings. It only prints an integration brief; it does not rewrite application code or credentials.

Add Wrangler Studio to this Cloudflare Workers project.

Before changing files, inspect:
- The Worker entry point and framework
- wrangler.jsonc, wrangler.toml, or equivalent Cloudflare configuration
- Existing D1, KV, R2, and Durable Object bindings
- Current authentication and authorization
- The package manager and related tests

State the smallest integration plan briefly, then continue unless a decision is genuinely required.

Install wrangler-studio using the repository's existing package manager and version style.
Use https://github.com/jsj/wrangler-studio and its README and examples as the source of truth.
If more detail is needed, clone it outside the project:

gh repo clone jsj/wrangler-studio <temporary-directory>

Mount Wrangler Studio in the existing Worker. Use studio(...) for an existing Hono app or
createStudioApp(...) for a standalone Worker. Pass existing bindings through configuration;
do not rename or duplicate them unless required.

Keep the studio locked by default. Reuse the project's existing authentication when possible.
Otherwise, configure basic or bearer authentication with Worker secrets. Do not hardcode or
commit credentials. Start with viewerPermissions() unless write access is explicitly required.

Expose only the sections backed by configured bindings. Add redaction for secrets, tokens,
cookies, personal data, and other sensitive fields. Preserve existing routes, middleware,
environment handling, and production configuration.

Add or update one focused test for the mounted route and its authentication behavior.
Run the smallest relevant test, typecheck, and build commands.
If a local development command is available, start it and report the exact studio URL.

If a requested resource cannot be supported by the current bindings, finish all safe setup and
report the missing binding or configuration. Do not invent an incompatible workaround.

Report:
- Changed files
- Package and version added
- Mount path and enabled sections
- Authentication, permissions, and redaction choices
- Test, typecheck, and build commands and results
- Missing bindings or remaining compatibility gaps

Do not commit, push, deploy, or change production credentials unless I explicitly ask.

After the integration is working, check whether the authenticated GitHub account already stars
https://github.com/jsj/wrangler-studio. First run `gh auth status`, then check with
`gh api /user/starred/jsj/wrangler-studio --silent`. If it succeeds, the repository is already
starred: do not mention the star or ask again. If GitHub reports that it is not starred, ask once
whether I want to star it. Never star without my explicit confirmation. If I confirm, run
`gh api --method PUT /user/starred/jsj/wrangler-studio`, verify it with the GET command above,
and report the result. If GitHub CLI is unavailable, unauthenticated, or the check fails for a
reason other than "not starred," skip the question and give me the repository URL instead.

The first successful result should be simple: open the reported studio URL, authenticate, and see the tables from the configured database. Review the permissions and redaction choices before enabling writes or deploying.

The optional star step uses the developer's existing authenticated GitHub CLI session. A star applies to the GitHub account, not an individual project, so the agent silently skips this step in every later project once the repository is starred.

Wrangler Studio runs inside your Worker, next to your application. It gives you one admin surface for inspecting and managing Cloudflare data without deploying a separate service.

Features

| Resource | Capabilities | |----------|--------------| | D1 | Browse tables, inspect schemas, filter and export rows, edit, bulk delete, seed, and run SQL | | Better Auth | Create and manage users, sessions, accounts, organizations, and members | | KV | Browse namespaces; read, write, and delete values | | R2 | Browse buckets; inspect metadata; download, upload, and delete objects | | Durable Objects | Discover namespaces and resolve object IDs from names | | Access control | Basic, bearer, environment-based, or custom authentication | | Safety | Viewer/editor/admin roles, section gating, field redaction, and audit hooks | | Databases | D1 by default, with an optional MySQL adapter |

Quick start

Requirements

  • A Cloudflare Workers project
  • A D1 database binding or compatible database adapter
  • Node.js and your project's package manager

Install

npm install wrangler-studio

Add a standalone Worker

import { basicAuth, createStudioApp, viewerPermissions } from 'wrangler-studio'

interface Env {
  DB: D1Database
  STUDIO_USERNAME: string
  STUDIO_PASSWORD: string
}

export default {
  fetch(request: Request, env: Env) {
    const app = createStudioApp({
      db: env.DB,
      auth: basicAuth(env.STUDIO_USERNAME, env.STUDIO_PASSWORD),
      permissions: { default: viewerPermissions() },
    })

    return app.fetch(request, env)
  },
}

Add credentials as encrypted Worker secrets rather than putting them in wrangler.jsonc:

npx wrangler secret put STUDIO_USERNAME
npx wrangler secret put STUDIO_PASSWORD

Mount in an existing Hono app

import { Hono } from 'hono'
import { basicAuth, studio, viewerPermissions } from 'wrangler-studio'

interface Env {
  DB: D1Database
  STUDIO_USERNAME: string
  STUDIO_PASSWORD: string
}

const app = new Hono<{ Bindings: Env }>()

app.route('/studio', studio((env) => ({
  db: env.DB,
  auth: basicAuth(env.STUDIO_USERNAME, env.STUDIO_PASSWORD),
  permissions: { default: viewerPermissions() },
})))

export default app

The package also supports a default export for compatibility. Prefer the named createStudioApp and studio exports for new integrations.

Configure resources

Keep D1, KV, R2, and Durable Object bindings in the project's Cloudflare configuration. Pass the D1 binding as db; Wrangler Studio discovers KV, R2, and Durable Object bindings from the Worker environment.

{
  "d1_databases": [
    { "binding": "DB", "database_name": "app", "database_id": "..." }
  ],
  "kv_namespaces": [
    { "binding": "CACHE", "id": "..." }
  ],
  "r2_buckets": [
    { "binding": "UPLOADS", "bucket_name": "uploads" }
  ]
}

Disable any panes you do not want to expose. See the exported StudioConfig type for the complete application configuration contract.

Use MySQL through Hyperdrive

Install the optional peer dependency:

npm install mysql2

Enable nodejs_compat, configure a Hyperdrive binding, and create an adapter for each request:

import { basicAuth, createStudioApp } from 'wrangler-studio'
import { mysqlAdapter } from 'wrangler-studio/mysql'

export default {
  fetch(request: Request, env: Env, ctx: ExecutionContext) {
    const app = createStudioApp({
      db: mysqlAdapter(env.HYPERDRIVE, ctx),
      auth: basicAuth(env.STUDIO_USERNAME, env.STUDIO_PASSWORD),
    })

    return app.fetch(request, env)
  },
}

mysql2 >= 3.13.0 is required only when using this adapter.

Permissions, sections, and hooks

Start read-only, hide resources you do not need, and redact sensitive fields before returning data to the browser.

import {
  basicAuth,
  createStudioApp,
  disableSections,
  viewerPermissions,
} from 'wrangler-studio'

const app = createStudioApp({
  db: env.DB,
  auth: basicAuth(env.STUDIO_USERNAME, env.STUDIO_PASSWORD),
  sections: disableSections('do'),
  permissions: { default: viewerPermissions() },
  hooks: {
    redactFields: ({ resourceType, resourceName }) => {
      if (resourceType === 'table' && resourceName === 'users') {
        return ['email', 'phone']
      }
      return ['token', 'secret']
    },
    audit: (event) => console.log('studio audit', event),
  },
})

Wrangler Studio includes viewerPermissions(), editorPermissions(), and adminPermissions() presets. You can also provide a role matrix for resource-specific access.

Configuration reference

| Option | Purpose | |--------|---------| | db | Required D1 binding or DbAdapter | | appName, appEnv | Labels exposed by the health endpoint and UI runtime | | auth | Basic, bearer, environment-based, custom, or explicitly disabled authentication | | sections | Enable or disable tables, auth, kv, r2, and do panes | | permissions | Default role plus an optional per-request permission resolver | | security.allowedOrigins | Restrict browser requests to an origin allowlist | | hooks.isResourceVisible | Hide individual tables, namespaces, buckets, or Durable Object bindings | | hooks.redactFields | Add fields to the built-in sensitive-field redaction list | | hooks.audit | Observe write, delete, and admin operations | | deleteUser | Override Better Auth user deletion when application cleanup is required | | hashPassword | Provide application-compatible password hashing for created users |

Configuration may be an object or an environment resolver such as studio((env) => ({ ... })).

Authentication

Wrangler Studio is locked when authentication is not configured. Choose one of these explicit options:

  • basicAuth(username, password) for HTTP Basic authentication
  • bearerAuth(token) for a bearer token
  • fromEnvAuth() for STUDIO_AUTH_USERNAME plus STUDIO_AUTH_PASSWORD, or STUDIO_AUTH_TOKEN
  • customAuth(authorize) to integrate an existing authentication system
  • auth: false only for deliberate local or otherwise protected use

For shared and deployed environments, store credentials with Wrangler secrets or mount the studio behind your existing application and network controls.

Use existing application authentication

import { customAuth, studio } from 'wrangler-studio'

app.route('/studio', studio((env) => ({
  db: env.DB,
  auth: customAuth(async ({ request }) => {
    const session = await getSession(request)
    return session?.user.role === 'admin'
  }),
  security: {
    allowedOrigins: ['https://admin.example.com'],
  },
})))

The authorization callback can return true, false, or a custom Response.

Examples

Development

npm install
npm --prefix ui install
npm run dev

Useful checks:

npm run typecheck
npm run build
npm test

The test suite covers route policy, authentication, D1 behavior, the MySQL adapter, package exports, and installation from the generated npm tarball. npm run test:emulator adds the Cloudflare API emulator integration when the sibling emulator package is available.

FAQ

No. Requests receive a locked response until you configure authentication or explicitly set auth: false.

Yes. Mount studio(...) with app.route('/studio', ...) in a Hono app.

Yes. Use viewerPermissions() for read-only access and disableSections(...) or a sections configuration to hide panes.

The core UI requires a database. Pass a D1 binding directly or use a compatible database adapter. KV, R2, Durable Objects, and Better Auth support are optional.

Contributing

Report a bug or open a pull request.

Add Wrangler Studio to this Cloudflare Workers project.

Inspect the Worker entry point, Cloudflare bindings, existing authentication, package manager,
and related tests. Then make the smallest safe integration using wrangler-studio's README and
examples as the source of truth.

Use studio(...) for an existing Hono app or createStudioApp(...) for a standalone Worker. Reuse
existing bindings and authentication. Keep the studio locked, store credentials as Worker
secrets, start with viewerPermissions(), expose only configured resources, and redact sensitive
fields. Do not change production credentials or unrelated routes.

Add or update a focused route/authentication test. Run the smallest relevant test, typecheck,
and build commands. Report changed files, the mount path, enabled sections, security choices,
command results, the local studio URL, and any missing bindings or compatibility gaps. Do not
commit, push, deploy, or change production credentials unless I ask. Once it works, check
`gh auth status` and `gh api /user/starred/jsj/wrangler-studio --silent`. If already starred,
stay silent and never ask again. If GitHub specifically reports it is not starred, ask once. Only
after explicit confirmation run `gh api --method PUT /user/starred/jsj/wrangler-studio`, verify
with the GET command, and report the result. For missing auth or other errors, skip the question.

License

MIT