Package Exports
- @geenius/adapters
- @geenius/adapters/convex
- @geenius/adapters/react
- @geenius/adapters/react-css
- @geenius/adapters/shared
- @geenius/adapters/solidjs
- @geenius/adapters/solidjs-css
Readme
@geenius/adapters
The architectural lynchpin of the Geenius ecosystem — a unified adapter layer that makes backend services interchangeable with a one-file swap.
Overview
@geenius/adapters defines standard interfaces for six infrastructure domains and provides concrete implementations for each. Any frontend component talks exclusively to an adapter interface — never to a database or service directly.
This is what makes "swap Convex for Supabase" a single-file change instead of a months-long rewrite.
Adapter Domains
| Domain | Interface | Providers |
|---|---|---|
| DB | DbAdapter |
localStorage, Convex, Supabase, Neon, MongoDB |
| Auth | AuthAdapter |
localStorage, Better Auth, Convex Auth, Clerk, Supabase Auth |
| Payments | PaymentsAdapter |
localStorage, Stripe, noop |
| AI | AiAdapter |
localStorage, OpenAI, Anthropic, Gemini, Ollama, CF AI Gateway, Vercel AI SDK |
| File Storage | FileStorageAdapter |
localStorage, R2, S3, Uploadthing, Supabase Storage, Convex Storage, Minio |
| Admin | AdminAdapter |
localStorage |
Installation
pnpm add @geenius/adaptersSub-package Exports
import { configureAdapters, createConvexDbAdapter } from '@geenius/adapters' // shared (default)
import { AdapterProvider, useDb, useAuth, useAi } from '@geenius/adapters/react' // React hooks
import { AdapterProvider, createDb, createAuth } from '@geenius/adapters/solidjs' // SolidJS primitives
import { adapterTables } from '@geenius/adapters/convex' // Convex schema
import { AdaptersPage, AdapterCard } from '@geenius/adapters/react-css' // Styled React components
import { AdaptersPage, AdapterCard } from '@geenius/adapters/solidjs-css' // Styled SolidJS componentsQuick Start
1. Configure adapters at app startup
import { configureAdapters } from '@geenius/adapters'
import { createConvexDbAdapter } from '@geenius/adapters'
// Call once before rendering
configureAdapters({
db: { provider: 'convex' },
auth: { provider: 'better-auth' },
ai: { provider: 'openai', apiKey: process.env.OPENAI_API_KEY },
storage: { provider: 'r2' },
payments: { provider: 'stripe' },
})2. Wrap your app with AdapterProvider (React)
import { AdapterProvider } from '@geenius/adapters/react'
import { createBetterAuthAdapter } from '@geenius/adapters'
import { createConvexDbAdapter } from '@geenius/adapters'
export function App() {
return (
<AdapterProvider
adapters={{
db: createConvexDbAdapter({ client: convex, functions: myFns }),
auth: createBetterAuthAdapter({ client: authClient }),
ai: createOpenAiAdapter({ apiKey: process.env.OPENAI_API_KEY }),
}}
healthCheck
>
<Router />
</AdapterProvider>
)
}3. Use adapters in components
import { useAuth, useDb, useAi } from '@geenius/adapters/react'
export function Dashboard() {
const auth = useAuth()
const db = useDb()
const ai = useAi()
async function handleSignIn() {
await auth.signIn('user@example.com', 'password')
}
async function handleOAuth() {
const { url } = await auth.signInWithOAuth('google', { redirectUrl: '/dashboard' })
window.location.href = url
}
async function handleChat() {
const response = await ai.chat([{ role: 'user', content: 'Hello!' }])
console.log(response.content)
}
}Prototyping with localStorage (Pronto tier)
Every domain ships a localStorage implementation for zero-config prototyping:
import {
createLocalStorageAuthAdapter,
createLocalStorageDbAdapter,
createLocalStorageAiAdapter,
createLocalStorageFileAdapter,
createLocalStoragePaymentsAdapter,
createLocalStorageAdminAdapter,
createNoopPaymentsAdapter,
} from '@geenius/adapters'These adapters persist data in the browser's localStorage with no external dependencies. Upgrade to real adapters by replacing a single file.
Tier Gating
import { isFeatureAvailable, isPackageAvailable, getUpgradeFeatures } from '@geenius/adapters'
isFeatureAvailable('admin', 'pronto') // → false
isFeatureAvailable('admin', 'lancio') // → true
isFeatureAvailable('ai-magic', 'studio') // → true
getUpgradeFeatures('pronto', 'lancio')
// → ['admin', 'payments', 'blog', 'file-storage', 'ai-workflow', 'ai-embeddings']Provider Registry
import { PROVIDER_REGISTRY, getProvidersForDomain, getProviderMeta } from '@geenius/adapters'
getProvidersForDomain('ai')
// → [{ id: 'localStorage', tier: 'pronto' }, { id: 'openai', tier: 'lancio' }, ...]
getProviderMeta('payments', 'stripe')
// → { id: 'stripe', name: 'Stripe', domain: 'payments', tier: 'lancio', ... }Adapter Interface Contracts
All interfaces are async (Promise-based), generic, and framework-agnostic. Swapping a provider only requires replacing the adapter factory call — no changes to consumers.
// AuthAdapter — all providers
interface AuthAdapter {
signIn(email: string, password: string): Promise<AuthSession>
signUp(email: string, password: string, name?: string): Promise<AuthSession>
signInWithOAuth(provider: OAuthProvider, options?: { redirectUrl?: string }): Promise<{ url: string }>
signOut(): Promise<void>
getSession(): Promise<AuthSession | null>
getUser(): Promise<AuthUser | null>
updateUser(updates: Partial<Pick<AuthUser, 'name' | 'image'>>): Promise<AuthUser | null>
}
// AiAdapter — all providers (stream is optional, falls back to chat)
interface AiAdapter {
chat(messages: ChatMessage[], options?: AiOptions): Promise<ChatResponse>
complete(prompt: string, options?: AiOptions): Promise<string>
embed(text: string | string[]): Promise<number[][]>
stream?(messages: ChatMessage[], options?: AiOptions): AsyncIterable<string>
}Tier Availability
| Tier | Description |
|---|---|
| Pronto | Prototype-ready. localStorage only. Zero external deps. |
| Lancio | Production-ready. Real backends: Convex, Stripe, Better Auth, R2. |
| Studio | Full ecosystem. All Lancio providers + AI Magic, Analytics, Teams, and more. |
License
MIT — © Antigravity HQ