Skip to content

createNizhalServer

Copy page
import { createNizhalServer } from "@nizhal/server";
const server = createNizhalServer({
db: process.env.DATABASE_URL!,
schema,
mutators,
syncRules,
auth,
storage, // optional — defaults to postgresStorage(db)
realtime, // optional — defaults to inProcessRealtime()
blob, // optional BlobAdapter
observer, // optional NizhalObserver hooks
jobs, // optional durable job registry
limits, // body size + per-actor rate limit
presence, // heartbeat timeout for /sync/stream
});
server.listen(4000);

Returns { app, listen, fetch }listen for Node/Bun, fetch for Workers.

MethodPathPurpose
POST/sync/pullCursor delta scoped to buckets
POST/sync/pushIdempotent mutator batch
GET/sync/streamWebSocket bucket pings + presence
GET/nizhal/contractOpenAPI/JSON-Schema contract
GET/nizhal/statsAdmin stats (password-gated)
  • db — Postgres connection string or Drizzle client
  • schema — map of table name → ContractSchemaSource
  • mutatorsdefineMutators registry
  • syncRulesdefineSyncRules output
  • authNizhalAuth (e.g. bearerTokenAuth)
  • Unknown mutator → 400
  • Auth failure → 401
  • Sync-rule violation → row filtered (never leaked)
  • Mutator invariant failure → 400, client optimistic revert