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

@identikey/component-kit

v0.2.0

Published

Contract-first (oRPC) full-stack slices + Svelte 5 components for any Web-standard host. Framework-neutral by default; Elysia + Identikey auth are optional.

Readme

@identikey/component-kit

Contract-first (oRPC) full-stack slices + Svelte 5 components for any Web-standard host. Bring your own backend and your own auth — the kit mounts into your server as a plain (Request) => Response handler and reads your users through a neutral auth port. Elysia and IdentiKey auth are optional, batteries-included fast paths, not requirements.

Status: v0.1.x. The contract-first surface (oRPC router, fetch adapter, typed client, SSE event iterators) is the default path and is proven in a production host (negotiated, a SvelteKit app with its own session auth). The single reference component is GpuControlCard — dumb, prop-only, and skinnable. More components will follow the same pattern.

Why this exists

The kit is top-of-funnel for IdentiKey self-sovereign, key-based auth and the IdentiKey key-managed proxy: adopt the components at zero commitment with your existing stack, meet IdentiKey as the one-switch auth upgrade, graduate to managed keys when you want them. Open on the interface axis, opinionated on the default axis — on purpose.

Read docs/VISION.md for the funnel model and ADR 0001 for the auth posture (neutral port, IdentiKey flagship, capability negotiation).

What it is

Something between a framework and middleware. Each "component" is a contract-first slice:

  • A valibot + oRPC contract — the single source of truth both ends derive from
  • Server handlers (implement(contract)) over a provider port you implement — compile-time checked against the contract, no HTTP framework baked in
  • A rune-backed controller that drives the contract-typed client + a resumable event stream into one reactive object
  • A Svelte 5 component (dumb, props-only, skinnable) that renders it

The host mounts one catch-all route and implements two small ports (AuthPort, GpuProvider). In exchange it gets: end-to-end typed RPC, a resumable typed event stream, and ready-to-render components — while keeping its own auth, audit logging, and error semantics.

Host integration (bring-your-own-backend)

Proven wiring, from the negotiated reference integration:

1. Implement the ports and build the handler

// src/lib/server/kit.ts
import {
  createGpuRouter,
  createKitFetchHandler,
  memoryBus,
  type AuthPort,
  type GpuProvider
} from '@identikey/component-kit/server';

const auth: AuthPort = {
  // Read YOUR session (cookie, JWT, whatever) from the raw Request.
  resolve: async (request) => /* { user, session } | null */,
  isAdmin: (user) => /* your admin rule */,
  describe: () => ({ kind: 'my-session', methods: ['token'] })
};

const provider: GpuProvider = {
  /* your RunPod / Lambda / in-house impl. Mutations receive the acting
     user (GpuActor) so your audit trail survives. Throw ORPCError with
     data.code ('gpu_busy', ...) to keep your failure UX. */
};

export const bus = memoryBus(); // publish to it from workers/schedulers too
const router = createGpuRouter({ provider, bus });
export const handleKitRequest = createKitFetchHandler(router, {
  auth,
  prefix: '/api/kit'
});

2. Mount on one catch-all route

// src/routes/api/kit/[...rest]/+server.ts  (SvelteKit; any Web-standard host works)
import { handleKitRequest } from '$lib/server/kit';
import type { RequestHandler } from './$types';

const handle: RequestHandler = async ({ request }) =>
  (await handleKitRequest(request)) ?? new Response('Not Found', { status: 404 });

export const GET = handle;
export const POST = handle;
export const DELETE = handle;

3. Wire the UI with the contract-typed client

<script lang="ts">
  import { createKitClient, createGpuController } from '@identikey/component-kit/client';
  import { GpuControlCard } from '@identikey/component-kit/components';

  const client = createKitClient({ url: '/api/kit' });
  const gpu = createGpuController({
    client,
    isAdmin: () => page.data.user?.isAdmin ?? false,
    pollMetricsMs: 5000 // optional: keep uptime/cost ticking between events
  });

  $effect(() => {
    gpu.start();
    return () => gpu.stop();
  });
</script>

<GpuControlCard
  metrics={gpu.metrics}
  pods={gpu.pods}
  isAdmin={gpu.isAdmin}
  mutating={gpu.mutating}
  mutationError={gpu.mutationError}
  podsLoading={gpu.podsLoading}
  podsError={gpu.podsError}
  pendingPodIds={gpu.pendingPodIds}
  autoShutdown={gpu.autoShutdown}
  autoShutdownSaving={gpu.autoShutdownSaving}
  autoShutdownError={gpu.autoShutdownError}
  onAction={gpu.onAction}
  onAdopt={gpu.onAdopt}
  onTerminate={gpu.onTerminate}
  onRefresh={gpu.onRefresh}
  onReconcile={gpu.onReconcile}
  onDismissError={gpu.onDismissError}
  onSaveAutoShutdown={gpu.onSaveAutoShutdown}
/>

Types hold end-to-end: the client is typed from the contract (ContractRouterClient<GpuContract>), not from the server or its framework, and implement(contract) compile-checks every handler. The guarantee doesn't evaporate when a host serves the routes from its own stack — that's the point.

Why dumb components

Components take only props + callbacks. The controller, not the component, owns the data lifecycle. This means:

  • Components test in isolation (no fetch mocking)
  • Hosts can swap the controller for their own state without forking the UI
  • The same component works whether you wire it with runes, stores, or TanStack Query

Skinning

Components render with plain, scoped-CSS markup by default — zero host deps. A host with its own design system overrides the look without forking the component, by passing optional skinning props:

  • Button / Checkbox — inject your own primitives. They must satisfy KitButtonProps / KitCheckboxProps (exported from /components); a thin wrapper around shadcn-svelte's Button/Checkbox is usually a few lines.
  • chrome — a Snippet<[header, content]> that wraps the card shell, so you can render the header + body inside your own Card (e.g. shadcn Card.Root > Card.Header / Card.Content).
<GpuControlCard {...gpu} Button={MyButton} Checkbox={MyCheckbox}>
  {#snippet chrome(header, content)}
    <Card.Root>
      <Card.Header>{@render header()}</Card.Header>
      <Card.Content>{@render content()}</Card.Content>
    </Card.Root>
  {/snippet}
</GpuControlCard>

The metrics list, drift rows, error alert, and auto-shutdown form still use the kit's scoped CSS — inject more hooks here as real hosts need them.

Auth: neutral port, IdentiKey flagship

Any host implements the floor:

interface AuthPort {
  resolve(request: Request): { user, session } | null | Promise<...>;
  isAdmin?(user): boolean;
  describe(): { kind: string; methods: ('oauth'|'passkey'|'token'|'signing')[] };
}

describe() is capability negotiation: components progressively enhance — passkey/signing affordances light up only when the active provider advertises them. The IdentiKey flagship provider (in progress, component-kit-on6) implements the floor and extends past it: passkey/WebAuthn ceremonies, OAuth, per-request key-signing (proof-of-key, not a cookie check), and proxy hooks. See ADR 0001.

If a provider verifies signatures over the request body, resolve() must not consume the body stream the handler needs — verify over headers + a body hash, or clone the request.

Event bus

Events ride the same contract as the RPC calls: client.events({ topics }) returns a typed async iterator (oRPC event iterator over SSE). Reconnects resume via Last-Event-ID from a ring buffer (default 256 envelopes); each event's meta carries the monotonic id. Topic filtering supports wildcards (gpu.session.*).

Bus interface is host-swappable:

import type { EventBus } from '@identikey/component-kit/server';
const bus: EventBus = /* your Redis-backed impl */;
createGpuRouter({ provider, bus });

The bridge is load-bearing. The kit only publishes session events for mutations that flow through its own router. Transitions your host initiates out-of-band — auto-shutdown, health-check failures, background jobs — reach clients only if you publish them: bridge your internal state broadcasts onto the bus as gpu.metrics snapshots (see the host integration example). A host that skips the bridge gets a card frozen on stale state between manual refreshes; pollMetricsMs on the controller is a mitigation, not a substitute.

See docs/operating-constraints.md for the memoryBus single-instance constraint, the multi-instance EventBus story, and the semver / contract-compatibility policy (what's frozen vs. free to change).

Authorization model

Enforced by oRPC middleware reading the per-request context the adapter builds from your AuthPort:

| Procedure | Requires | |---|---| | metrics, listPods, events | signed-in user | | start, stop, restart | signed-in user | | terminate, adopt, getAutoShutdown, saveAutoShutdown | admin |

Admin is whatever AuthPort.isAdmin(user) returns. Mutations pass the acting user through to your provider for audit logging.

The optional Elysia fast path

Greenfield hosts that want zero boilerplate can mount the kit's own Elysia app (with the IdentiKey provider, CSRF guard, and Eden client) via the @identikey/component-kit/elysia entry — createKit({ auth: identikey({...}), gpu: { provider } }) and one catch-all. Elysia, Eden, and @simplewebauthn/server are optional peers: hosts on the contract-first path install none of them.

Package layout

src/
  contracts/             valibot schemas + the oRPC contract router (SSOT)
  server/
    router.ts            implement(contract) → handlers over GpuProvider + bus
    adapters/fetch.ts    (Request) => Response — bring-your-own-backend
    adapters/elysia.ts   optional turnkey mount
    auth/                AuthPort context/middleware; Identikey Elysia provider
    providers/gpu.ts     GpuProvider port (host implements)
    bus/memory.ts        in-process event bus with ring-buffer replay
  client/
    createKitClient.ts   contract-typed oRPC client
    gpu.svelte.ts        createGpuController() — rune-backed state for GpuControlCard
    events.svelte.ts     raw EventSource fallback
    auth.ts              oauthStart, signInWithPasskey, logout
  components/
    GpuControlCard.svelte, KitButton, KitCheckbox, skin.ts

Exported subpaths: /server, /client, /components, /contracts, and the optional /elysia.

Tests

bun run check    # tsc --noEmit
bun run test     # vitest run

Tests cover the contract round-trip (client ⇄ fetch adapter in-process), auth gating, actor threading, event replay/resume, bus behaviour, sessions, and compile-time contract conformance.

Consuming locally

Until the npm publish pipeline lands (component-kit-6u5), hosts consume the source tree directly:

// host package.json
"@identikey/component-kit": "file:../relative/path/to/component-kit"

Two things make the symlinked-directory dep safe (learned the hard way):

  1. Align svelte versions between this repo and the host. TypeScript realpath-resolves the symlinked source, so a version skew means two svelte copies and "two different types named Snippet" errors under svelte-check.
  2. In the host's Vite config, add the kit to ssr.noExternal (it ships .svelte source) and dedupe the shared peers: resolve: { dedupe: ['svelte', 'valibot'] }.

A packed tarball (bun pm packfile:...tgz) also works and avoids the symlink caveats, but bun caches tarballs by filename — bump the version on every repack.

Not yet

  • npm publish (component-kit-6u5) — blocks any consumer that deploys from a repo image (relative paths don't resolve in CI/prod builds)
  • IdentiKey flagship provider on the neutral port (component-kit-on6) — ceremonies currently exist only in the Elysia/Eden legacy path
  • Component-side capability negotiation UI (component-kit-26z)
  • Redis bus adapter (interface is ready; just needs the impl)
  • Per-instance scaling (in-memory user cache + pending-ceremony state)
  • Storybook stories
  • More components beyond GpuControlCard