Get started with Usagekit
Use the metering runtime on its own, or add views, hooks and a UI that fits your product.
Install the runtime
Link to Install the runtimeChoose the layer you need. The four public runtime packages are available on npm at 0.5.0. The React and registry workspaces are currently available from the repository checkout.
npm install @usagekit/core @usagekit/store @usagekit/meter @usagekit/providersStart with the runtime. Add UI when you need it.
A backend-only integration needs no React, registry or CSS dependencies.
Runtime packages
Link to Runtime packages- @usagekit/core on npmThe exact Meter contract, quantities and money.
- @usagekit/store on npmAtomic accounting commands and the in-memory Store.
- @usagekit/meter on npmAdmission, reservations, settlement and recovery.
- @usagekit/providers on npmProvider catalog, price tables and receipts.
Custom Stores and Meters upgrading to 0.5.0 should follow docs/MIGRATING-0.5.md in the checkout.
Storage adapters
Link to Storage adaptersThe Meter validates input and resolves policy; it never writes rows itself. Its Store executes each accounting command atomically and re-checks everything that depends on concurrent state inside that command: operation state and version, lease ownership, budget headroom including outstanding reservations, and command replay identity. Expected rejections come back as typed outcomes, not exceptions.
In the durable adapters, everything one command writes commits or rolls back together: the operation with its receipts and measurements, budget usage, the idempotency journal, alert crossings and the event history that readers page from. There are no callback locks and no external writes inside the transaction.
- Commands on an operation carry
expectedVersion: reserve creates version 1, and dispatch intent and settlement each bump it. A stale version is aversion_conflict, never a silent overwrite. - An identical command returns its stored result with
replayed: trueand writes nothing new. The same command id with a different payload is a conflict, and reserve deduplicates by operation id. - Money is a bigint in ten-thousandths of a cent, and quantities are integers with an explicit scale. Nothing passes through floating point.
Adapters
- In-memory
- On npm
createMemoryStore({ clock, budgets })- From
@usagekit/store. The reference rules, for tests and demos. Not durable; the sample on the home page runs on it. - SQLite
- Repository, not on npm
createSqliteStore({ path, clock })- Workspace
packages/store-sqlite. WAL journal,synchronous = FULLand oneBEGIN IMMEDIATEtransaction per command. It backs the local server,usagekit serve; a restart keeps operations, receipts, command replays, reservations and expired leases. - Cloudflare Durable Objects
- Repository, not on npm
createDurableObjectStore({ storage: ctx.storage, clock })- Workspace
packages/store-d1. Every command runs insidestorage.transactionSyncon SQLite-backed Durable Object storage. Route all principals of a namespace to one object withgetByName(namespace): shared budgets need one serial authority. It does not write to D1. - Postgres
- Your repository
import type { Store } from "@usagekit/store"- Implement the Store on your own schema. bisibility runs usagekit this way: its own Store on Prisma, with hand-written SQL migrations, running alongside its existing billing and tested with usagekit's conformance suite. A shared Prisma package for usagekit is planned.
- Any transactional database
- Your repository
import type { Store } from "@usagekit/store"- Implement the interface and prove it with the conformance suite below.
Conformance suite
@usagekit/store/conformance on npm exports runStoreConformance and runStoreScalingConformance. Both run in vitest, so add vitest 5 and fast-check 4 as dev dependencies. The same suite runs unchanged against the in-memory Store, the embedded Meter, SQLite, the remote Meter over HTTP and the Cloudflare adapter.
Capabilities state what an adapter guarantees: durable, rollingWindows, maxMoneyUnits and maxQuantityScale. A capability you declare false is reported as skipped, never as passed.
import { runStoreConformance } from "@usagekit/store/conformance";
// Illustrative: resolves { store, clock, budgets, close, restart }.
import { createPostgresFixture } from "./postgres-fixture.js";
// The values the SQLite adapter declares. Declare what yours guarantees.
runStoreConformance(createPostgresFixture, {
durable: true, // restart() must reopen the same database
rollingWindows: false, // reported as a skipped guarantee
maxMoneyUnits: 2n ** 63n - 1n,
maxQuantityScale: 18,
});
For SQL adapters, runStoreScalingConformance reads statement and row counters. With 5,000 stored operations, reserve, dispatch intent and settle must do exactly the work they do on an empty ledger: on SQLite, 25 statements, 8 rows read and 12 changed.
React checkout setup
Link to React checkout setupReact is not publicly installable from npm yet.
@usagekit/react, @usagekit/views and the registry are private workspaces. Use the checkout flow below.
From the repository root, with Node 22.23.1 and npm 10.9.3, install and build the local workspaces. This links the React and view packages locally; it does not publish them.
nvm use
npm ci
npm run build
npm run registry:build
To review the complete New York and Base UI dashboards with an in-memory Meter and a sample budget writer, prepare the local showcases:
node packages/registry/consumers/prepare.mjs
# Run one of the Vite commands printed by the script.
These showcases use local fixtures and make no provider calls. To consume the UI workspaces in another application, follow docs/CONSUMING.md in the checkout for the local package source and peer dependencies.
Run the local server
Link to Run the local serverusagekit serve runs a single-owner server on 127.0.0.1:4242: a SQLite ledger, an encrypted key vault, the API proxy and the dashboard. The first start asks for a vault passphrase and prints the bearer token once. It runs from the checkout; the server, proxy and CLI are not on npm.
# Terminal 1, from the repository root after the checkout build:
export PATH="$PWD/node_modules/.bin:$PATH"
usagekit serve
# Terminal 2: the token printed once by the first start, then a key and a limit.
export PATH="$PWD/node_modules/.bin:$PATH"
read -rs USAGEKIT_TOKEN && export USAGEKIT_TOKEN
read -rs PROVIDER_KEY && export PROVIDER_KEY
usagekit provider add serpapi --connection c1 --secret-env PROVIDER_KEY
unset PROVIDER_KEY
usagekit budget set --id agent --scope connection --connection c1 \
--limit 500:requests --alert 80
Agents call providers through the proxy with the local token. The vault injects the provider key. Metered calls reserve budget before dispatch; a blocking budget answers 429 with allowance_exceeded when there is no headroom. An Idempotency-Key admits one call; a repeat returns 409. Known free operations and configured passthrough calls are counted without spend enforcement.
curl --fail-with-body \
-H "Authorization: Bearer $USAGEKIT_TOKEN" \
-H "Idempotency-Key: search-job-001" \
"http://127.0.0.1:4242/proxy/c1/search.json?q=example&engine=google"
Open http://127.0.0.1:4242/ and enter the token to see usage, budgets, exceptions and connections. Only calls through the proxy are metered. Tokens, vault recovery and restart behaviour are in docs/LOCAL-SERVER.md and docs/PROXY.md in the checkout.
Headless hooks
Link to Headless hooksWrap related panels in one MeterProvider. Equal reads share a cache. Keys include Meter identity, verified access and query input, so a scope or account change isolates the rendered state. The TypeScript samples on this page are illustrative.
import { MeterProvider, useUsageSummary } from "@usagekit/react";
// meter, verifiedAccess and verifiedScope come from your host.
<MeterProvider meter={meter} access={verifiedAccess}>
<Overview />
</MeterProvider>
function Overview() {
const { data, state, error, refresh } = useUsageSummary({
scope: verifiedScope,
from: "2026-10-01T00:00:00.000Z",
to: "2026-11-01T00:00:00.000Z",
units: ["requests", "tokens", "customer_cents"],
});
return renderYourDesign({ data, state, error, refresh });
}
Read hooks
- useUsageView
- useUsageSummary
- useBudgetsView
- useDefinedBudgets
- useHeaderStatus
- useCoverageView
- useExceptionsView
Read hooks expose data, state, error, refresh() and refreshing. useBudgetEditor and useBudgetMutation handle administrative editing through a host-supplied writer.
Pure loaders in @usagekit/views also run without React. Exact amount models contain text, unit and certainty. Keep their decimal text intact rather than converting it to a JavaScript number.
Copyable components
Link to Copyable componentsBoth Radix/New York and Base UI contain these blocks. They use your application's semantic tokens and primitives; they do not bring a second theme.
- measurement-card
- An exact figure, with certainty.
- usage-summary-cards
- Complete totals for each unit.
- cost-summary-card
- Provider costs by funding source.
- usage-table
- Usage detail and cursor pagination.
- budget-card
- Usage, reservations and headroom.
- budget-editor
- Edit a trusted budget definition.
- budget-manager-panel
- Browse, create and reload budgets.
- header-status
- Compact status across your app.
- coverage-summary
- Tracked and untracked coverage.
- exceptions-list
- Work that needs evidence or recovery.
- usage-filters
- Controlled scope and period choices.
- connection-list
- Funding, plan and tags per connection.
- provider-card
- Connection status, freshness and actions.
- provider-connect-form
- Connect and test through your host port.
- provider-source-selector
- Own keys or platform funding.
- provider-rate-editor
- Exact prices with provenance.
- provider-chain-editor
- Priority, enablement and fallback order.
- provider-balance-card
- Balance authority and data freshness.
- provider-allocation-editor
- Own and hosted limits across app and API.
- provider-manager-panel
- Compose the provider management workflow.
# In the Usagekit checkout:
npm run registry:build
# In your configured consumer app, with local UI packages available:
R=/absolute/path/to/usagekit/packages/registry/dist
npx shadcn add $R/r/radix/budget-manager-panel.json
npx shadcn add $R/r/base/usage-summary-cards.json
Run these commands from a configured consumer with the local UI packages available as described in docs/CONSUMING.md. shadcn installs into @/components/usagekit/; copied blocks reference your @/components/ui/* primitives. These commands alone do not make unpublished UI packages available.
Budget status shows used and reserved amounts separately. Measurement cards distinguish measured, estimated, unknown and unavailable values. A forbidden or failed read must not display stale figures.
Budget editing
Link to Budget editingSupply an existing Budget or a host-authored template to useBudgetEditor. The draft contains exact decimal strings for the limit, optional hard limit and alert quantities. The trusted scope, unit and window come from your host.
Supply your host writer through MeterProvider and keep it stable across renders.
import type { BudgetWriter } from "@usagekit/react";
const budgetWriter: BudgetWriter = {
save: saveAuthorizedBudget,
reconcile: reconcileAuthorizedBudget,
};
<MeterProvider
meter={meter}
access={verifiedAccess}
budgetWriter={budgetWriter}
>
{children}
</MeterProvider>
A UI permission flag is not server authorization.
Your server must independently authorize, validate and persist each save with a version check.
- Conflicts keep the draft.
- An ambiguous save freezes duplicate writes until reconciliation confirms the result.
- There is no automatic write retry, budget deletion or wallet mutation.
Provider management
Link to Provider managementProvider hooks and blocks use a separate ProviderManagementPort supplied by your application. They expose stored connection evidence, balances, request quotes and allocations. Reads never implicitly test credentials or call a provider.
Provider hooks
- useProviderConnections
- useProviderConnection
- useProviderBalance
- useProviderProjection
- useProviderAllocations
- useProviderAction
- useBudgetProjection
import {
ProviderManagementProvider,
useProviderConnections,
} from "@usagekit/react";
// Stable host adapter and identity verified by your application.
<ProviderManagementProvider port={providerPort} binding={verifiedBinding}>
<Connections />
</ProviderManagementProvider>
function Connections() {
const { data, state, refresh } = useProviderConnections();
return renderConnections({ data, state, refresh });
}
The verified binding contains scopeKey, principalKey and authRevision. Management is disabled by default. Your server must authorize every action independently, check revisions and persist the command result.
useProviderAction supports explicit actions and reconciliation. Credential material travels separately from the content-free command, stays out of read snapshots, and is not automatically retried. A pending or ambiguous operation prevents duplicate writes.
useProviderProjection quotes one proposed request. useBudgetProjection models budget exhaustion from trusted input. Quotes, forecasts and balances keep their certainty, freshness and authority explicit.
Architecture and ownership
Link to Architecture and ownershipEach layer builds on the layers before it.
Runtime
The Meter contract, exact quantities, atomic accounting, admission and receipts.
Views
Pure authorized models of usage, costs, budgets, coverage and exceptions.
React
Shared reads, explicit states and host-owned administrative mutations.
Registry
Copyable blocks composed into your application's pages.
Your host owns authentication, verified access, routes, provider credentials, persistence and customer balance authority. Query scope is not authorization. Provider cost and customer charge are distinct values.
For the full contract and integration mechanics, read these files in the source checkout:
- docs/PLAN.md
- docs/UI.md
- docs/BILLING-IMPORTS.md
- docs/LOCAL-SERVER.md
bisibility uses Usagekit for metering. Its React UI adoption is still in progress.
Visit bisibility