React SDK (@hyperyai/sdk)
Drop-in React authentication and billing components — sign-in, user profile, conditional rendering, hooks, and mode-aware funds popups for any app that authenticates through the Hypery gateway.
@hyperyai/sdk is a drop-in React/Next.js library for signing users in through the
Hypery gateway and reacting to billing state. The API is intentionally Clerk-like:
wrap your app in one provider, then use <SignedIn> / <SignedOut>, <UserButton>,
useUser(), and friends.
SignIn, SignUp, AuthModal, UserButton, UserProfile, WorkspaceSwitcher.
SignedIn, SignedOut, Protect, RedirectToSignIn.
useUser, useAuth, useWallet, useError, useMemberships.
RestrictionModal + alerts that pop up when a request hits a billing limit.
Installation
Install the package from npm. It ships compiled JavaScript plus type declarations, so no extra transpilation step is required.
npm install @hyperyai/sdkpnpm add @hyperyai/sdkyarn add @hyperyai/sdkSetup
Wrap your app once in HyperyProvider. Every component and hook reads from it.
// app/layout.tsx (Next.js App Router)
import { HyperyProvider } from '@hyperyai/sdk';
export default function RootLayout({ children }) {
return (
<html>
<body>
<HyperyProvider
config={{
clientId: process.env.NEXT_PUBLIC_OAUTH_CLIENT_ID!,
redirectUri: process.env.NEXT_PUBLIC_REDIRECT_URI!, // e.g. https://yourapp.com/callback
gatewayUrl: process.env.NEXT_PUBLIC_AUTH_URL!, // the Hypery gateway, e.g. https://hypery.ai
scopes: ['read', 'write', 'ai:chat', 'billing:read'],
storage: 'localStorage',
}}
>
{children}
</HyperyProvider>
</body>
</html>
);
}The gateway issues 1-hour access tokens plus a refresh token. The provider
refreshes silently in the background, so you generally never touch tokens
directly — use useAuth().getAccessToken() when you need one for a fetch.
The full component gallery below is rendered from the auth-demo example app
(in hyperyai/hypery-examples):

Authentication components
SignInForm
An embedded email/password + social login card. Use it when you want sign-in to live inline on a page rather than behind a modal or redirect.

import { SignInForm } from '@hyperyai/sdk';
<SignInForm
showSocial // Continue with Google / GitHub
showEmailPassword
title="Welcome back"
description="Sign in to continue"
onSuccess={(user) => router.push('/dashboard')}
onError={(err) => toast.error(err.message)}
/>AuthModal
A controlled modal for sign-in / sign-up — ideal for a "Sign in" button in a navbar. Supports custom branding (logo, app name, primary color).

import { AuthModal } from '@hyperyai/sdk';
const [open, setOpen] = useState(false);
<button onClick={() => setOpen(true)}>Sign in</button>
<AuthModal
isOpen={open}
onClose={() => setOpen(false)}
initialMode="signin" // or "signup"
showSocial
showEmailPassword
branding={{ appName: 'Acme', primaryColor: '#06b6d4' }}
onSuccess={() => setOpen(false)}
/>SignIn / SignUp / AuthButton
Drop-in buttons that start the sign-in / sign-up flow (modal or redirect). Three
visual variants: primary, secondary, outline. AuthButton is the lower-level
button both are built on.
import { SignIn, SignUp } from '@hyperyai/sdk';
<SignIn buttonText="Try Sign In" variant="primary" />
<SignUp buttonText="Try Sign Up" variant="secondary" />UserButton / UserProfile
UserButton is an avatar + dropdown (profile, billing, sign out); UserProfile is
an inline profile card. Both render only when the user is authenticated — signed
out, they show a placeholder.
import { UserButton, UserProfile } from '@hyperyai/sdk';
<UserButton showUserInfo size="md" /> // size: 'sm' | 'md' | 'lg'
<UserProfile />WorkspaceSwitcher
A dropdown for users who belong to multiple teams / workspaces. Reads from
useMemberships() and switches the active workspace used for billing and scoping.
import { WorkspaceSwitcher } from '@hyperyai/sdk';
<WorkspaceSwitcher
onChange={(workspace) => console.log('active:', workspace.slug)}
/>Conditional rendering
Render-gate components — they have no UI of their own; they show or hide children based on auth state.
import { SignedIn, SignedOut, Protect, RedirectToSignIn } from '@hyperyai/sdk';
<SignedIn><Dashboard /></SignedIn>
<SignedOut><SignIn /></SignedOut>
{/* Require a scope/permission, with a fallback */}
<Protect scope="billing:read" fallback={<p>No access</p>}>
<BillingPanel />
</Protect>
{/* Force a redirect to sign-in when signed out */}
<SignedOut><RedirectToSignIn /></SignedOut>Hooks
import { useUser, useAuth, useError, useWallet, useMemberships } from '@hyperyai/sdk';
const { user, isLoading } = useUser();
const { isAuthenticated, login, logout, getAccessToken } = useAuth();
// Structured gateway errors (spending limit / insufficient credits / payment method)
const { error, setError, clearError, isBillingRestriction } = useError();
// Wallet state + 1-click funding (see Billing components)
const { wallet, addFunds, addPaymentMethod } = useWallet();
// The user's teams + workspaces (for a workspace switcher)
const { data } = useMemberships();Billing components
These render on a consumer site when a request hits a billing limit. They are mode-aware (prepaid vs. metered) and read live wallet state from the gateway.
These components apply only to the credit-wallet modes (metered / prepaid).
In vag_passthrough (the default) there is no wallet — usage is metered to
Stripe directly by the Vercel AI Gateway — so useWallet() reports
mode: 'vag_passthrough' with a null balance and the funds popups do not apply.
See Billing & Credits.
In metered mode the popup offers "Add a payment method" (Stripe-hosted Checkout — no Elements), after which usage is auto-billed. In prepaid mode it offers true 1-click "Add $X" that charges the saved card in place. See Billing & Credits for how the mode is chosen.
<RestrictionModal />— pops up onINSUFFICIENT_CREDITS,PAYMENT_METHOD_REQUIRED, orSPENDING_LIMIT_EXCEEDED.<SpendingLimitAlert />,<InsufficientCreditsAlert />— inline alert variants for the same conditions.<ErrorBoundary />— catches render errors and surfaces a friendly fallback.
import { RestrictionModal, useError, useAuth } from '@hyperyai/sdk';
const { error, clearError } = useError();
const { getAccessToken } = useAuth();
<RestrictionModal
error={error}
gatewayUrl={process.env.NEXT_PUBLIC_AUTH_URL!}
getAccessToken={getAccessToken}
onClose={clearError}
onRetry={retryRequest}
/>The matching error codes are parsed for you by useError() / parseError():
Screenshots above are generated from the auth-demo example app
(in hyperyai/hypery-examples, /examples). To regenerate, run the demo and
re-capture into the SDK's docs/screenshots/.



