Documentation
Self-hosted backend in one container. REST, Auth, Realtime, Functions, Storage, Cron, and AI.
Up and running in under 2 minutes.
Start the stack
git clone https://github.com/your-org/precheck cd precheck docker compose up -d
Starts PostgreSQL 17, NATS, MinIO, and the PreCheck gateway on http://localhost:8080.
Install the SDK
npm install @precheck/client
import { PreCheckClient } from '@precheck/client'
const client = new PreCheckClient({
url: 'http://localhost:8080',
anonKey: 'YOUR_ANON_KEY',
tenantId: 'YOUR_TENANT_ID',
})Get your anonKey and tenantId from the cloud dashboard after creating a project.
Query your database
const rows = await client.from('my_table').limit(10).select()
console.log(rows) The Auto-REST layer automatically exposes every table in your project's schema. See the Database section for the full query API.
Built-in user accounts with JWT access tokens. Sign up, sign in, and manage sessions with a single call.
// Sign up a new user
const { access_token, user } = await client.auth.signUp(
'[email protected]',
'password',
)
// Sign in an existing user
const { access_token } = await client.auth.signIn(
'[email protected]',
'password',
)
// Get the current user
const user = await client.auth.getUser(access_token)
// Sign out
await client.auth.signOut(access_token)Fluent query builder over your PostgreSQL tables. Supports filtering, ordering, pagination, and all four CRUD operations.
// Select with filters
const todos = await client.from('todos')
.filter('done', 'eq', false)
.order('created_at', false)
.limit(50)
.select()
// Insert a row
const todo = await client.from('todos').insert({
content: 'Buy milk',
done: false,
})
// Update
await client.from('todos').update(id, { done: true })
// Delete
await client.from('todos').delete(id)filter(col, op, val) eq · neq · gt · gte · lt · lte · like · ilike
order(col, asc?) Sort ascending (true) or descending (false)
limit(n) Max rows returned, default 100
offset(n) Skip n rows for pagination
Every INSERT, UPDATE, and DELETE streams to connected clients over WebSocket, backed by PostgreSQL logical replication. Subscribe to multiple topics on one connection using wildcard patterns — db:orders:* matches all order events.
const channel = client.realtime
.channel('db:todos:*')
.on('INSERT', (row) => console.log('Added:', row))
.on('UPDATE', (row) => console.log('Updated:', row))
.on('DELETE', (row) => console.log('Removed:', row))
channel.subscribe(access_token)
// Later — clean up
client.realtime.close()S3-compatible object storage backed by MinIO. Upload files, list buckets, generate signed download URLs, and delete objects.
// Upload a file
await client.storage.upload(
'avatars',
'user-123.png',
fileBlob,
'image/png',
)
// List objects in a bucket
const files = await client.storage.list('avatars')
// [{ name: 'user-123.png', size: 42000, last_modified: '...' }]
// Get a time-limited signed URL
const url = await client.storage.signedUrl('user-123.png', 3600)
// Delete an object
await client.storage.delete('user-123.png')Deploy serverless JavaScript functions via the dashboard or the Functions API, then invoke them with any JSON payload.
// Deploy a function via the dashboard or API, then invoke it:
const result = await client.functions.invoke<{ greeting: string }>(
'hello',
{ name: 'World' },
)
console.log(result.greeting) // 'Hello, World!'
// Functions can return any JSON-serializable value
const stats = await client.functions.invoke<{ count: number }>('get-stats')All routes served on http://localhost:8080. Authenticated routes require:
Authorization: Bearer <access_token> X-Precheck-Tenant: <tenantId>
PreCheck runs anywhere Docker runs. All configuration is via environment variables.
HTTP_PORT REST + API port — default: 8080
DB_HOST PostgreSQL hostname — default: localhost
JWT_SECRET Secret used to sign tokens — default: (auto-generated)
NATS_URL NATS server for realtime — default: nats://localhost:4222
MINIO_ENDPOINT S3-compatible storage — default: http://localhost:9000
ENABLE_AI Load ONNX + llama.cpp models — default: false
CLOUD_ADMIN_EMAIL Bootstrap admin account email — default: [email protected]
CLOUD_ADMIN_PASSWORD Bootstrap admin account password — default: changeme123