Sitelet https://github.com/harshalone/postbase
Skip to content

Latest commit

 

History

161 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Postbase

Postbase

Self-hosted auth + database platform for Next.js. Drop it in, configure your providers from a dashboard, and connect your app with a single SDK call.

Think: self-hosted Supabase / Clerk — you own the data, you control the infra.

npm: postbasejs PyPI: postbasepy pub.dev: postbasefl

SDK Language Install
postbasejs JavaScript / TypeScript npm install postbasejs
postbasepy Python pip install postbasepy
postbasefl Dart / Flutter flutter pub add postbasefl
Railway
Deploy on Railway

Railway — tested, recommended. Two services (app + managed Postgres), one required secret. See RAILWAY.md.

DigitalOcean
Deploy to DigitalOcean

DigitalOcean — tested, recommended. App Platform + managed database, provisioned from the app spec. See DIGITALOCEAN.md.

Render
Deploy to Render

Render — unverified. Blueprint (render.yaml) defines the web service + Postgres together. See RENDER.md.

Fly.io
Deploy to Fly.io

Fly.io — unverified. Button only runs fly launch; run fly/setup.sh after for Postgres + secrets. See FLY.md.

AWS
Deploy to AWS

AWS — unverified. CloudFormation: CodeBuild builds the image, deploys to App Runner + RDS Postgres. See AWS.md.

Google Cloud
Run on Google Cloud

Google Cloud — unverified. Opens Cloud Shell; gcp/setup.sh provisions Cloud SQL and deploys to Cloud Run. See GCP.md.

Azure
Deploy to Azure

Azure — unverified. ARM/Bicep: ACR Task builds the image, deploys to Container Apps + Postgres Flexible Server. See AZURE.md.

Oracle Cloud
Deploy to Oracle Cloud

Oracle Cloud — unverified, extra setup required (GitHub token, manual NEXTAUTH_URL step). Container Instances + OCI Database with PostgreSQL. See ORACLE.md.


Screenshots

Postbase landing
Self-hosted auth + database platform for Next.js

Dashboard
Dashboard — manage organisations and projects

Project overview
Project overview with quick-start guide

Auth providers
25+ auth providers — toggle any from the dashboard

SQL editor
Built-in SQL editor with AI query generation

Storage connections
S3-compatible storage — connect Amazon S3, Cloudflare R2, Backblaze B2, and more

Cron jobs
Scheduled cron jobs — run SQL snippets or HTTP requests on any schedule

API keys
API keys — anon and service role keys with SDK snippet

Project settings
Project settings — configure auth redirect URLs, JWT expiry, and more


Features

  • 25+ Auth Providers — Google, GitHub, Discord, Magic Link, Passkeys, SMS OTP, SAML/SSO, and more — all toggleable from the dashboard
  • Database API — Query your PostgreSQL via anon key (respects RLS) or service_role key (full access)
  • JOIN & Raw SQL — JOIN across tables or run raw SQL via the SDK; AI-powered SQL editor with human-readable result summaries
  • Table Explorer — Inline cell editing, column filtering, full-text row search, and CSV import directly from the dashboard
  • RLS Policies — Row Level Security policy editor with live preview
  • File Storage — S3-compatible object storage with bucket policies
  • Transactional Email — Send email via SMTP or AWS SES (IAM keys or SMTP credentials), configured per-project from the dashboard
  • Cron Jobs — SQL or HTTP jobs on any schedule; full run history with request/response detail panel, date filter, and bulk delete
  • Multi-project — One Postbase instance can serve multiple apps
  • Self-hosted — Single docker compose up and you're running

Quick Start

1. Clone & configure

git clone https://github.com/harshalone/postbase
cd postbase
cp .env.example .env

Generate and set a secret in .env:

openssl rand -base64 32   # paste output as NEXTAUTH_SECRET

2. Start the services

docker compose up -d

This starts:

  • PostgreSQL on port 5432
  • Postbase app on port 3000

3. Run database migrations

cd apps/web
pnpm install
pnpm db:push

4. Open the dashboard

Visit http://localhost:3000/dashboard

  1. Create a project → get your anon key and service_role key
  2. Go to Auth Providers → enable the providers you want, paste in OAuth credentials
  3. Copy your keys from the API Keys tab

Local Development

For development you don't need to rebuild Docker on every change. Run only the infrastructure (PostgreSQL) in Docker and the Next.js app locally with hot reload.

The quickest way is the included dev.sh script:

./dev.sh           # start infra + app (hot reload)
./dev.sh --rebuild # rebuild containers
./dev.sh --reset   # wipe data and restart clean

Or manually:

1. Start infrastructure only

pnpm infra:up

This starts PostgreSQL in Docker — without the app container.

2. Run the app locally

pnpm db:push   # first time only — run migrations
pnpm dev       # Next.js dev server with hot reload

That's it. Edit code → changes reflect instantly, no Docker rebuild needed.

Useful dev commands

Command Description
pnpm infra:up Start postgres
pnpm infra:down Stop postgres (data is preserved)
pnpm infra:logs Tail infrastructure logs
pnpm dev Start Next.js dev server
pnpm db:push Push schema changes to the database
pnpm db:studio Open Drizzle Studio (visual DB browser)

Production deployment

When deploying, use the full Docker Compose stack which includes the app container:

docker compose up -d

Connect your app

Install the SDK

npm install postbasejs
# or
pnpm add postbasejs

Initialize the client

// lib/postbase.ts
import { createClient } from 'postbasejs'

export const postbase = createClient(
  'http://localhost:3000',       // your Postbase instance URL
  'pb_anon_...',                 // your anon key (safe for browser)
  { projectId: 'your-project-id' }
)

For server-side / admin operations use your service_role key — keep it out of the browser.


Usage

Auth — email + password

await postbase.auth.signUp({ email: 'user@example.com', password: 'secret' })

const { data, error } = await postbase.auth.signInWithPassword({
  email: 'user@example.com',
  password: 'secret',
})

await postbase.auth.signOut()

const { data: { session } } = await postbase.auth.getSession()

postbase.auth.onAuthStateChange((event, session) => {
  console.log(event, session?.user)
})

Remember me (extended session TTL): pass rememberMe: true to signUp, signInWithPassword, verifyOtp, verifyEmailOtp, or signInWithIdToken to issue a 30-day refresh token instead of the default 7-day one. The flag is preserved automatically on every later refresh.

await postbase.auth.signInWithPassword({ email, password, rememberMe: true })

Browser OAuth redirects (signInWithOAuth + handleOAuthCallback) have no request body at sign-in time, so rememberMe can't be passed in directly — call postbase.auth.setRememberMe(true) after handleOAuthCallback() resolves instead. See the SKILL reference for the full pattern.

Auth — OAuth (browser / web)

// Redirects browser to the provider, then back to your redirectTo URL
await postbase.auth.signInWithOAuth({
  provider: 'google', // 'github', 'discord', 'apple', etc.
  options: { redirectTo: 'https://yourapp.com/callback' },
})

// On your callback page — parses tokens from the URL automatically
const { data, error } = await postbase.auth.handleOAuthCallback()

Auth — OAuth (native iOS / Android — custom URL scheme)

Use an in-app browser (ASWebAuthenticationSession on iOS, Chrome Custom Tab on Android) with a custom URL scheme as the redirect target:

// Returns the authorize URL for you to open in an in-app browser
const authorizeUrl = await postbase.auth.signInWithOAuth({
  provider: 'github',
  options: { redirectTo: 'com.myapp://auth/callback' },
})
// → open authorizeUrl in ASWebAuthenticationSession / Chrome Custom Tab

// After the in-app browser hands the URL back to your app:
const { data, error } = await postbase.auth.handleOAuthCallback({
  url: incomingUrl, // e.g. 'com.myapp://auth/callback?access_token=...'
})

Auth — Apple / Google native SDK (no browser at all)

For apps that use ASAuthorizationController (Apple) or GIDSignIn (Google), pass the id_token directly — no browser, no redirect:

// Apple (Swift → bridge identityToken string to JS)
const { data, error } = await postbase.auth.signInWithIdToken({
  provider: 'apple',
  idToken: appleIdentityToken,
  nonce: nonce, // optional, if you passed one to ASAuthorizationAppleIDRequest
  rememberMe: true, // optional, 30-day refresh token instead of the default 7-day one
})

// Google (Android / iOS)
const { data, error } = await postbase.auth.signInWithIdToken({
  provider: 'google',
  idToken: googleIdToken,
})
// data.session.accessToken, data.session.refreshToken, data.user

Database

// SELECT
const { data, error } = await postbase
  .from('posts')
  .select('id, title, created_at')
  .eq('user_id', userId)
  .order('created_at', { ascending: false })
  .limit(10)

// INSERT
const { data } = await postbase
  .from('posts')
  .insert({ title: 'Hello world', user_id: userId })
  .select()
  .single()

// UPDATE
await postbase.from('posts').update({ title: 'Updated' }).eq('id', postId)

// DELETE
await postbase.from('posts').delete().eq('id', postId)

// OR filters
const { data } = await postbase
  .from('posts')
  .select('*')
  .orFilters([{ column: 'status', op: 'eq', value: 'draft' }, { column: 'status', op: 'eq', value: 'published' }])

// JOIN across tables
const { data } = await postbase
  .from('posts')
  .select('id, title, users(name, email)')
  .join({ table: 'users', on: 'posts.user_id = users.id' })

// Raw SQL (service_role key required)
const { data } = await postbase.sql('SELECT count(*) FROM posts WHERE created_at > $1', ['2024-01-01'])

anon key — enforces Row Level Security policies on your tables. service_role key — bypasses RLS. Server-side only.

Reserved table names

Every project schema (proj_<uuid-no-dashes>) is auto-provisioned with four auth tables before you ever run SQL yourself: users, accounts, sessions, verification_tokens. They aren't global — they live inside your own project schema — but they already exist, so CREATE TABLE accounts (...) (or users/sessions/verification_tokens) will fail with relation "accounts" already exists. Name your own tables something else (e.g. profiles, my_accounts) and sync from users via a trigger if you need to extend the built-in user record — see the Claude Code skill for the pattern.

Storage

// Upload a file
const { data, error } = await postbase
  .storage
  .from('avatars')
  .upload('user-123/avatar.png', file)

// Get a public URL
const { data: { publicUrl } } = postbase.storage.from('avatars').getPublicUrl('user-123/avatar.png')

// Download
const { data: blob } = await postbase.storage.from('avatars').download('user-123/avatar.png')

// List files
const { data: files } = await postbase.storage.from('avatars').list('user-123/')

// Delete
await postbase.storage.from('avatars').remove(['user-123/avatar.png'])

Email

Send transactional email through the project's configured provider (SMTP or AWS SES) — configure it from the dashboard's Auth → Email settings.

const { data, error } = await postbase.email.send({
  to: 'user@example.com',
  subject: 'Welcome!',
  text: 'Hello there',
  html: '<p>Hello there</p>',
})
// data.ok

Auth Providers

Enable any of these from the dashboard — no code changes needed.

Category Providers
Social Google, GitHub, Discord, Twitter/X, Facebook, LinkedIn, Apple, Microsoft, Slack, Twitch, Spotify, Notion, GitLab, Bitbucket, Dropbox, Box
Credentials Email + Password, Magic Link, Phone/SMS OTP
Passwordless Passkeys (WebAuthn), Anonymous/Guest
Enterprise SAML/SSO, Okta, Keycloak, Auth0

Apple and Google additionally support a native id_token flow — iOS/macOS/Android apps can sign users in via the OS native SDK (no browser required) using signInWithIdToken() in the JS SDK.


Environment Variables

Variable Description Default
DATABASE_URL PostgreSQL connection string postgresql://postbase:postbase@localhost:5432/postbase
NEXTAUTH_SECRET Secret for signing tokens — required —
NEXTAUTH_URL Public URL of your Postbase instance http://localhost:3000

Stack


Claude Code Skill

A Claude Code skill is bundled at skills/postbase/SKILL.md.

It covers the full Postbase API reference, postbasejs SDK patterns, RLS, auth tables, cron jobs, storage, and Swift integration — loaded automatically when you use /postbase in Claude Code, or activated whenever Claude detects you're building against a Postbase backend.

To install it in your own project:

cp skills/postbase/SKILL.md <your-project>/.claude/skills/postbase/SKILL.md

License

MIT

About

No description, website, or topics provided.

Resources

Stars

36 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages