Package Exports
- @geenius/adapters
- @geenius/adapters/convex
- @geenius/adapters/react
- @geenius/adapters/react-css
- @geenius/adapters/solidjs
- @geenius/adapters/solidjs-css
Readme
@geenius/adapters
The architectural lynchpin of the Geenius ecosystem — standardized adapter contracts that make backend services interchangeable with a one-file swap.
Overview
@geenius/adapters defines standard interfaces for six infrastructure domains and provides localStorage mock implementations for zero-config prototyping. 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.
Architecture: Thin Contracts + Domain Packages
@geenius/adapters is the contract layer — it only defines what each service must do (the interfaces) and provides localStorage mocks for fast prototyping. Real provider implementations live in the dedicated domain packages:
| Domain | Interface | Mock (here) | Real Providers (domain package) |
|---|---|---|---|
| DB | DbAdapter |
localStorage |
@geenius/db → Convex, Supabase, Neon, MongoDB, CloudflareKV, Memory |
| Auth | AuthAdapter |
localStorage |
@geenius/auth → Better Auth, Convex Auth, Clerk, Supabase Auth |
| Payments | PaymentsAdapter |
localStorage, noop |
@geenius/payments → Stripe, LemonSqueezy, Polar |
| AI | AiAdapter |
localStorage |
@geenius/ai → OpenAI, Anthropic, Gemini, Ollama, CF AI Gateway, Vercel AI SDK |
| File Storage | FileStorageAdapter |
localStorage |
@geenius/file-storage → R2, S3, Uploadthing, Supabase Storage, Convex Storage, Minio |
| Admin | AdminAdapter |
localStorage |
(localStorage only for now) |
Installation
pnpm add @geenius/adaptersSub-package Exports
import { configureAdapters, createLocalStorageDbAdapter } 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'
// 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 { createLocalStorageDbAdapter, createLocalStorageAuthAdapter } from '@geenius/adapters'
// Pronto tier — zero external deps
export function App() {
return (
<AdapterProvider
adapters={{
db: createLocalStorageDbAdapter(),
auth: createLocalStorageAuthAdapter(),
}}
healthCheck
>
<Router />
</AdapterProvider>
)
}For production (Lancio/Studio), use real providers from the domain packages:
import { AdapterProvider } from '@geenius/adapters/react'
import { createConvexDbAdapter } from '@geenius/adapters' // DB still in adapters
import { createAuthProvider } from '@geenius/auth' // Real auth provider
import { createPaymentProvider } from '@geenius/payments' // Real payment provider
export function App() {
return (
<AdapterProvider
adapters={{
db: createConvexDbAdapter({ client: convex, functions: myFns }),
auth: createAuthProvider({ provider: 'better-auth', baseUrl: '/api/auth' }),
payments: createPaymentProvider({ provider: 'stripe', apiKey: '...' }),
}}
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 users = await db.list('users')
const session = await auth.getSession()
}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 swapping one factory call.
Where are the real providers?
| Domain | Package | Example |
|---|---|---|
| AI | @geenius/ai |
AIClient, memory, skills, tool calling, content templates |
| Auth | @geenius/auth |
AuthProviderAdapter with MFA, passkeys, API keys, RBAC, session management |
| Payments | @geenius/payments |
PaymentProviderAdapter with webhooks, invoices, customer portal, plan sync |
| File Storage | @geenius/file-storage |
R2, S3, Uploadthing, Supabase Storage, Convex Storage, Minio |
These domain packages implement the contracts defined here and extend them with rich, production-grade features.
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.
// DbAdapter — generic, collection-based
interface DbAdapter {
create<T>(collection: string, data: Omit<T, 'id'>): Promise<T & { id: string }>
get<T>(collection: string, id: string): Promise<T | null>
update<T>(collection: string, id: string, data: Partial<T>): Promise<T | null>
delete(collection: string, id: string): Promise<boolean>
list<T>(collection: string, options?: ListOptions): Promise<T[]>
query<T>(collection: string, filter: QueryFilter): Promise<T[]>
count(collection: string, filter?: QueryFilter): Promise<number>
}
// AuthAdapter — minimal contract (see @geenius/auth for MFA, passkeys, etc.)
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 — minimal contract (see @geenius/ai for memory, skills, tools)
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 via domain packages. |
| Studio | Full ecosystem. All Lancio providers + AI Magic, Analytics, Teams, and more. |
License
MIT — © Antigravity HQ