by bento

Wabe is a self-hosted, Firebase-alternative BaaS written in TypeScript that auto-generates a secure GraphQL API from your schema with built-in auth, permissions, hooks, emails, and file storage. Supports MongoDB and PostgreSQL via swappable adapters.
Wabe is a self-hosted backend-as-a-Service framework for Node.js and Bun that generates a typed GraphQL API, authentication system, database layer, hooks pipeline, file storage, email, and cron scheduling from a TypeScript schema definition. The typical buyer is a TypeScript developer who needs a production-ready backend without vendor lock-in, replacing Firebase or Supabase with a fully owned stack.
authentication/ - Authentication system: email/password, OTP, OAuth (Google, GitHub), session management, security helpers, and resolver pipelineauthentication/oauth/ - OAuth2 client abstractions for Google and GitHub flowsauthentication/providers/ - Concrete auth provider implementations: EmailPassword, EmailOTP, QRCodeOTP, PhonePassword, Google, GitHub, SRP variantauthentication/resolvers/ - GraphQL resolver handlers for signIn, signUp, signOut, refresh, and challenge verificationcron/ - Cron job factory (cron()) and pre-built CronExpressions enum for scheduling recurring tasksdatabase/ - DatabaseController and adapter interface for pluggable database backends (MongoDB, PostgreSQL, custom)email/ - EmailController, email adapter interface, dev adapter, and built-in OTP email templateemail/templates/ - Transactional email templates (e.g., sendOtpCode)file/ - FileController, file adapter interface, dev adapter, and hooks for upload/read/delete lifecyclegraphql/ - GraphQL schema builder, parser, resolver wiring, type definitions, and pointer/relation helpershooks/ - Hook pipeline: permissions, session, authentication, field hashing, default fields, searchable fieldsschema/ - Schema definition types and utilities for declaring classes and fieldsserver/ - Wabe server class, startup/shutdown logic, and WabeTypes type contractutils/ - Internal utilities exposed for external consumption via utils/exportindex.ts - Barrel re-export of all public modulesnpm install wabe
# Wabe requires a database adapter — install at least one:
npm install wabe-mongodb
# or for PostgreSQL:
npm install wabe-postgres
# Wabe uses croner internally for cron scheduling (bundled, no separate install)
# For email, install the official Resend adapter or implement the interface:
npm install wabe-resend
Spin up an isolated sandbox and run it server-side — no local setup.
Tetrees AI Review of this version
This Express backend / api completed archive review. Structure, dependency manifests, documentation, functional source, and common risk patterns were checked by the Tetrees verification pipeline; runtime phases are stated separately.
Deterministic AVCP artifact review
Pipeline avcp-2026-08-04.1 · SHA-256 e5bb16f03c209f2b…
This version-scoped review deterministically inspects the submitted archive for structure, dependencies, documentation, functional source, and common malicious or high-risk signals. Build and test phases are reported as passed only after an isolated sandbox audition. It is not a guarantee of perfect security.
Reviewed Aug 4, 2026
Push this product straight into your AI IDE, web builder or cloud IDE.
Connect Tetrees to a compatible AI IDE, list products you own, and request the verified ZIP without exposing seller upload controls.
No reviews yet.
Sign in to join the discussion
Loading discussion…
No native build steps, pod installs, or prebuild commands are required. Wabe runs on Node.js 18+ or Bun 1.0+.
Place source: copy source/ into your project at e.g. src/wabe/ if vendoring, or simply import from the wabe npm package which re-exports everything from index.ts.
tsconfig: ensure "moduleResolution": "bundler" or "node16", "strict": true, and "target": "ES2022" or later.
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true
}
}
process.env — you pass config directly to the constructor. Create a config file:// src/config.ts
export const config = {
rootKey: process.env.WABE_ROOT_KEY!, // min 64 chars
databaseUrl: process.env.DATABASE_URL!,
port: Number(process.env.PORT ?? 3000),
isProduction: process.env.NODE_ENV === "production",
}
Start the server: call wabe.start() in your entry point (see examples below).
No Express wiring needed: Wabe runs its own HTTP server internally. You do not mount it inside Express.
cronfunction cron<T extends WabeTypes>(options: {
pattern: string
maxRuns?: number
enabledProtectedRuns?: boolean
run: (wabe: Wabe<T>) => any | Promise<any>
}): OutputCron<T>
Factory that returns a lazy cron job constructor. Pass the result in the crons array of your Wabe config. The run callback receives the live Wabe instance so it can access the database controller, email controller, and other services. Use CronExpressions for common patterns instead of hand-writing cron strings.
CronExpressionsenum CronExpressions {
EVERY_SECOND = '* * * * * *',
EVERY_MINUTE = '0 * * * * *',
EVERY_HOUR = '0 0 * * * *',
EVERY_DAY_AT_MIDNIGHT = '0 0 0 * * *',
EVERY_WEEK = '0 0 0 * * 0',
EVERY_YEAR = '0 0 0 1 1 *',
WEEKDAYS_MORNING = '0 0 7 * * 1-5',
WEEKENDS_EVENING = '0 0 19 * * 6-7',
FIRST_DAY_OF_MONTH = '0 0 0 1 * *',
LAST_DAY_OF_MONTH = '0 0 0 L * *',
EVERY_15_MINUTES = '0 */15 * * * *',
EVERY_30_MINUTES = '0 */30 * * * *',
EVERY_2_HOURS = '0 0 */2 * * *',
EVERY_6_HOURS = '0 0 */6 * * *',
EVERY_12_HOURS = '0 0 */12 * * *',
}
Use these constants anywhere a cron pattern string is expected. They are safe to import directly and avoid typos in hand-written cron expressions.
OutputCrontype OutputCron<T extends WabeTypes> = (wabe: Wabe<T>) => Cron
The type returned by cron(). It is the element type of the CronConfig array. You rarely construct this manually — it is produced by calling cron({...}) and consumed by the Wabe server internals.
Define a schema with a single class and start the server. The GraphQL API is available immediately at http://localhost:3000/graphql.
import { Wabe } from 'wabe'
import { MongoAdapter } from 'wabe-mongodb'
import { config } from './config'
const run = async () => {
const wabe = new Wabe({
isProduction: config.isProduction,
rootKey: config.rootKey,
database: {
adapter: new MongoAdapter({
databaseName: 'myapp',
databaseUrl: config.databaseUrl,
}),
},
schema: {
classes: [
{
name: 'Article',
description: 'Blog article',
fields: {
title: { type: 'String', required: true },
body: { type: 'String' },
publishedAt: { type: 'Date' },
},
},
],
},
port: config.port,
})
await wabe.start()
console.log(`Server running on port ${config.port}`)
}
await run()
Clean up expired sessions every hour using the cron factory and CronExpressions.
import { Wabe, cron, CronExpressions } from 'wabe'
import { MongoAdapter } from 'wabe-mongodb'
const purgeExpiredSessions = cron({
pattern: CronExpressions.EVERY_HOUR,
run: async (wabe) => {
// wabe.controllers.database is the DatabaseController instance
const db = wabe.controllers.database
const now = new Date()
await db.deleteObjects({
className: 'Session',
where: { expiresAt: { lessThan: now } },
context: { isRoot: true },
})
console.log('Expired sessions purged at', now.toISOString())
},
})
const wabe = new Wabe({
isProduction: false,
rootKey: process.env.WABE_ROOT_KEY!,
database: {
adapter: new MongoAdapter({
databaseName: 'myapp',
databaseUrl: process.env.DATABASE_URL!,
}),
},
schema: { classes: [] },
port: 3000,
crons: [{ name: 'purgeExpiredSessions', cron: purgeExpiredSessions }],
})
await wabe.start()
Enable the built-in email+password authentication provider and expose the User class with an email field.
import { Wabe } from 'wabe'
import { MongoAdapter } from 'wabe-mongodb'
const wabe = new Wabe({
isProduction: false,
rootKey: process.env.WABE_ROOT_KEY!,
database: {
adapter: new MongoAdapter({
databaseName: 'myapp',
databaseUrl: process.env.DATABASE_URL!,
}),
},
authentication: {
providers: {
emailPassword: true,
},
session: {
expirationInMinutes: 60 * 24 * 7, // 1 week
},
},
schema: {
classes: [
{
name: 'User',
fields: {
email: { type: 'Email', required: true },
displayName: { type: 'String' },
},
},
],
},
port: 3000,
})
await wabe.start()
// Clients can now call the auto-generated mutations:
// mutation { signUpWith(input: { authentication: { emailPassword: { email, password } } }) { ... } }
// mutation { signInWith(input: { authentication: { emailPassword: { email, password } } }) { ... } }
index.ts - Single barrel re-export; the only import path external consumers need.server/ - Core Wabe class: accepts full config, starts HTTP server, wires all controllers.authentication/ - Auth orchestration layer: sessions, OTP, cookie utilities, role helpers, and the provider-agnostic interface.authentication/oauth/ - Oauth2Client base and Google/GitHub OAuth2 implementations.authentication/providers/ - Concrete strategy classes for each auth method (email+password, OTP, QR code, phone, OAuth delegates).authentication/resolvers/ - Thin GraphQL resolvers that delegate to provider strategies for sign-in, sign-up, sign-out, refresh, and challenge flows.cron/ - cron() factory, CronExpressions enum, and CronConfig type for scheduling.database/ - DatabaseController facade and the DatabaseAdapter interface that all DB adapters must satisfy.database/pointerRelationPayload.ts - Helper to resolve pointer and relation payloads before DB writes.email/ - EmailController, EmailAdapter interface, and a dev-only no-op adapter.email/templates/ - Pre-built transactional templates (OTP code mailer).file/ - FileController, FileAdapter interface, dev adapter, and hook handlers for upload/read/delete events.graphql/ - Schema builder that introspects your class definitions and produces a full CRUD GraphQL schema with resolvers.hooks/ - Before/after hook implementations: permissions checks, session injection, field hashing, default field population, and searchable-field indexing.schema/ - TypeScript types for class and field definitions used in Wabe config.utils/ - Shared utilities exported to consumers (see utils/export).rootKey too short: Wabe requires the root key to be at least 64 characters; use a random hex string of 64+ chars or the server will throw on startup.wabe-mongodb or wabe-postgres causes a runtime error on first query — install the adapter and pass it to database.adapter."esModuleInterop": true and "allowSyntheticDefaultImports": true in tsconfig or you will get default-import errors.croner peer dependency version mismatch: Wabe pins a specific croner major internally; installing a conflicting version at the project root can cause Cron is not a constructor — let Wabe resolve croner from its own node_modules.isProduction flag in production: leaving isProduction: false in production disables security hardening on cookies and auth — always derive this from NODE_ENV.User is reserved: Wabe uses User internally for authentication; redefining it with incompatible fields will cause GraphQL schema merge conflicts — extend rather than redefine or use a different name.I have a Node.js TypeScript project and I want to integrate the Wabe backend-as-a-service framework.
Context files available to you:
- USAGE.md — integration guide with real API signatures and working examples
- source/ — the full Wabe core source (packages/wabe/src), upstream npm package: wabe
Please help me integrate Wabe into my project step by step:
1. Read USAGE.md thoroughly before writing any code.
2. Install required dependencies based on the "Required dependencies" section.
3. Update my tsconfig.json as described in "Project setup".
4. Create a Wabe server entry point (e.g., src/index.ts) that:
- Uses a MongoAdapter (or PostgreSQL if I specify)
- Defines my schema classes from my existing data model
- Enables email/password authentication
- Adds at least one cron job using CronExpressions from source/cron/index.ts
5. Use only exports visible in source/index.ts and documented in USAGE.md — do not invent APIs.
6. Show me how to run a test GraphQL mutation against the generated API.
7. Flag any environment variables I need to set before running.
Wabe is licensed under the Apache 2.0 License (as stated in the project README). See source/LICENSE if present in the vendored copy.
Upstream repository: https://github.com/palixir/wabe
Upstream npm package: wabe
This product’s unique contribution is clean room implementation of valuable code block into AVCP compatible standard.
The full install guide and integration prompts unlock after purchase.
Automation, Utilities & Developer Tools
Free