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

@whop/template-kit

v0.3.0

Published

Data and server layer for building Whop templates on the Whop REST API

Downloads

452

Readme

@whop/template-kit

The data + server layer for building Whop templates — deployable *.whop.app apps whose every screen is backed by the Whop public REST API.

It gives you one typed API contract (WhopAPI), React hooks to read it, a same-origin server proxy that keeps the company API key out of the browser, and a preview bridge so the exact same UI can render with fixtures in a catalog. The reference implementation is the neobank template.

Install

pnpm add @whop/template-kit

Peer dependency: react@^19.

Quick start

A template is a TanStack Start app with three pieces of wiring.

1. Declare which endpoints your app may call (src/api-manifest.ts) — select them by name; the kit owns the paths and copy:

import { selectManifest } from "@whop/template-kit";

export const MANIFEST = selectManifest([
  "getAccount",
  "listPayouts",
  "createPayout",
]);

This is your allowlist: only the endpoints you name are proxied. (You can still hand-write an EndpointManifest if you need a path the catalog doesn't cover.)

2. Mount the proxy route (src/routes/api.$.ts) — this is the only place the app talks to api.whop.com:

import { createFileRoute } from "@tanstack/react-router";
import { createApiProxy } from "@whop/template-kit/server";
import { MANIFEST } from "../api-manifest";

export const Route = createFileRoute("/api/$")({
  server: { handlers: createApiProxy(MANIFEST) },
});

3. Provide the API and read it in components:

import { WhopAPIProvider, resolveAPI, useWhopAPI, useEndpoint } from "@whop/template-kit";

function App() {
  // resolveAPI() returns the real HTTP client, or the preview bridge when embedded with ?whop_preview=1
  return (
    <WhopAPIProvider endpoints={resolveAPI()}>
      <Balance />
    </WhopAPIProvider>
  );
}

function Balance() {
  const { getAccount } = useWhopAPI();
  const { data, isLoading, error } = useEndpoint(getAccount);
  if (isLoading) return null;
  if (error) return <p>{error.message}</p>;
  return <p>{data.total_usd}</p>;
}

That's it — no fetch, no URLs, no API key. You call typed methods on WhopAPI; the kit handles transport.

Security model

  • The company API key is never in the browser or your app's JS. The client calls same-origin /api/* with no key; your proxy forwards to api.whop.com with no Authorization header; Whop's hosting layer injects Authorization: Bearer <company key> at the edge on the outbound hop.
  • The proxy is unauthenticated by default. Anyone who can reach the app URL gets the account's data back. For anything beyond a public demo, gate /api/* on the visitor's Whop identity/membership before forwarding.
  • The manifest is an allowlist. Only declared paths are proxied, and traversal (..) is rejected before any upstream fetch.
  • Money-out is scope-ceilinged. The injected key strips money-out scopes, so POST /transfers and POST /payouts return 403.

Preview mode

The same components render two ways because they only ever talk to a WhopAPI object handed in through WhopAPIProvider:

  • Deployed app: resolveAPI()httpAPI → real REST via your /api/* proxy.
  • Catalog preview: when embedded with ?whop_preview=1, resolveAPI() returns createPreviewAPI() — a proxy that answers every call over postMessage from the parent frame. The parent supplies fixtures, so the preview is credential-free.

No fixtures ship in this package or in a deployed template — a deploy is real-data-only by construction.

API

  • WhopAPI — the typed endpoint contract (account, financial activity, cards, transfers, payouts, swaps, metrics, reports, products, plans, memberships, reviews, payments, checkout configurations).
  • selectManifest / WHOP_ENDPOINTS — build your allowlist by endpoint name from the kit's canonical catalog (paths + copy included).
  • WhopAPIProvider / useWhopAPI / useEndpoint — provide the API and read a single call ({ data, isLoading, error, refresh }).
  • httpAPI / resolveAPI / createPreviewAPI — the real, resolved, and preview implementations of WhopAPI. httpAPI wraps the official @whop/sdk pointed at your /api proxy — same client, no key in the browser — and lazy-loads it on first call so it never weighs down your initial bundle.
  • useRealtimeChannel / useRealtimeRefresh — subscribe a component to a realtime channel.
  • @whop/template-kit/servercreateApiProxy, proxyConfigFromManifest, createRealtimeRoute, createWebhookRoute, verifyWhopWebhook, publishRealtime.
  • format / currency — display helpers for balances and amounts.

Links

Local development

whop apps dev mints a short-lived credential, but the Cloudflare dev runtime doesn't inherit the CLI's environment — give the worker its own vars in a gitignored .dev.vars next to your wrangler.jsonc:

WHOP_API_KEY=<an API key for your business>
WHOP_DEV_ACCOUNT_ID=biz_XXXXXXXXXXXX

When WHOP_API_KEY is present the proxy attaches it to upstream calls (in the hosted runtime the variable never exists — the edge injects the key instead), and WHOP_DEV_ACCOUNT_ID points getAccount at your business when the credential is a user token. Your template then runs locally against real data.