Loading repository data…
Loading repository data…
kahveciderin / repository
Your Drizzle schema is already a backend. Covara turns it into a complete, production-ready API — REST endpoints, real-time subscriptions, auth, file uploads, billing, email, and background jobs — with a type-safe, offline-first TypeScript client on the other end.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
Your Drizzle schema is already a backend. Covara turns it into a complete, production-ready API — REST endpoints, real-time subscriptions, auth, file uploads, billing, email, and background jobs — with a type-safe, offline-first TypeScript client on the other end. Built on Hono, it runs standalone on Node or at the edge on Cloudflare Workers.
Every product backend is the same 80%: CRUD endpoints, filtering, pagination, auth, sessions, password reset, file uploads, webhooks for payments, transactional email, a job queue, and a client that talks to all of it. You rewrite this plumbing for every project, and the pieces never quite fit together — your realtime layer doesn't know about your auth scopes, your client types drift from your API, your offline cache fights your subscriptions.
Covara's goal is to make that 80% one coherent system derived from a single source of truth: your Drizzle schema.
The remaining 20% — your business logic — goes in lifecycle hooks, RPC procedures, and ordinary Hono routes, with the framework's tracking and typing intact.
// server: a table becomes an API
const app = createCovara({ cors: true })
.resource("/todos", todosTable, {
id: todosTable.id,
db,
auth: { update: async (user) => rsql`userId==${user.id}` },
});
// client: the API becomes live UI
function TodoList() {
const { items, mutate } = useLiveList<Todo>("/api/todos", { orderBy: "position" });
return items.map((todo) => (
<Todo key={todo.id} {...todo} onDelete={() => mutate.delete(todo.id)} />
));
// creates/updates/deletes apply optimistically, sync offline,
// and stream to every other connected client over SSE
}
belongsTo, hasOne, hasMany, manyToMany with efficient batch loading, optional foreign-key auto-discovery (autoRelations), and scope-enforced includes (a relation never reveals rows the user couldn't read directly)HAVING filtering on aggregate output — available as a one-shot query or a live subscription (useLiveAggregate) that recomputes on every changebelongsTo parents and hasMany/hasOne children in one atomic POST?withDeleted=truePOST /batch/upsert)fields.writable is an enforced allowlist (mass-assignment protection); strictInput rejects unknown fieldscomputed fields added to every response and subscription eventtsvector / OpenSearch / in-memory adapters, with an opt-in transactional outbox for at-least-once index convergencestartServer(app) via covara/nodeexport default app, D1/Postgres, nodejs_compatPOST /register, plus POST /consent/revoke and consent TTLbackends.passport to use any Passport.js OAuth2 strategy (GitHub, Discord, …) as an upstream under your own OIDC providerfromPassport; runs on Node and Workers, with one-call loginWithSocial / signInWith on the clientJWTClient + useJWTAuth hook on the client with pluggable token storage (localStorage, memory, AsyncStorage)hashPassword/verifyPassword/needsRehash (Workers-safe) plus an enforceable password policyX-Frame-Options, MIME-sniffing protection, and more, auto-mounted by createCovara; opt-in CSP (so it never blocks your frontend)fields.readable allowlist strips non-readable columns from every response and subscription event (cannot be bypassed via ?select=)abuseProtection({ budget, pow }): within budget, requests are served and debited; over budget, the server issues a stateless, request-bound, one-time-use 428 challenge that the client library solves and retries transparently (solving pays the overdraft). Difficulty is programmatically controllable via a trust hook; an endpoint can also always require PoW. Disable PoW for a hard 429 instead. KV-backed with in-memory fallback; works alongside the conventional rateLimit. See docs<CovaraCaptcha/> component renders the provider widget and retries transparently.StorageAdapter interfaceapp.fileResource(...) chains like any resource and inherits the full CRUD/hooks/procedures/relations/subscriptions/scopes surface, plus MIME/size validation, per-user keys, and storage cleanup on deletecreateCovara auto-serves a local adapter's baseUrl; admin data explorer gets a per-row Download actionuseFileUpload (with progress), useFile, useFiles; getDownloadUrl() for React Nativecatchup policyctx.reportProgress, heartbeats, and resultTtlMs result expirymaxConcurrencyworker.drain() / worker.stop({ drain: true })onDlqEnqueue alerting hookcovara/email with Resend and Cloudflare Email Service adapters behind one EmailAdapter interfacecreateEmail().heading().button().code().build() rendering responsive, escaped HTML + a plaintext fallback, with themingsendEmailBatch for bulk deliverycovara/billing over Stripe, Lemon Squeezy, Paddle, and Polar.sh (fetch-based, no SDK deps, Workers-safe)reportUsage, hosted portalgrant/consume/balance/historypayment.succeededcreateBillingRouter plus client.billing.* and useCredits/useSubscription/useCheckout hooksselect projections that narrow return types, typed filter builder, generated types from your APIuseLiveList, useInfiniteList, useLiveAggregate, useMutation, useSearch, useAuth, useJWTAuth, useFileUpload/useFile/useFiles, useCredits/useSubscription/useCheckout, usePublicEnv, plus query invalidation and prefetchTokenStorage (AsyncStorage-compatible), environment-aware transport and offline backends, getDownloadUrl() for native file handlingAbortSignal + timeout, automatic 401 refresh-and-retry, SSE reconnect with jittergetOrCreateClient for developmentapp.page(path, Component) server-renders a page whose <Live> regions auto-generate the htmx endpoints (list/create/update/delete/subscribe). Covara generates wiring, not UI components