Kysely
Build a self-hosted Hot Updater server with Kysely query builder.
Before you start
Use this recipe in the server project from the custom-server quick start or your existing backend. Make the database and storage environment variables available to the server and schema commands. The React Native project's deploy configuration is a separate step.
kyselyAdapter supports PostgreSQL, MySQL 8.0 or later, and SQLite.
CockroachDB and SQL Server are not supported.
Installation
Install Kysely and SQLite driver.
npm install @hot-updater/server @hot-updater/aws kysely better-sqlite3npm install --save-dev hot-updater @types/better-sqlite3For other databases, see Kysely's dialect documentation.
Setup
Create a database connection file:
import { Kysely, SqliteDialect } from "kysely";
import Database from "better-sqlite3";
export const db = new Kysely<object>({
dialect: new SqliteDialect({
database: new Database("./data/database.db"),
}),
});Hot Updater configuration
Create the Hot Updater instance:
import { createHotUpdater } from "@hot-updater/server";
import { kyselyAdapter } from "@hot-updater/server/adapters/kysely";
import { apiKeys, insights } from "@hot-updater/server/plugins";
import { s3Storage } from "@hot-updater/aws";
import { db } from "./kysely";
export const hotUpdater = createHotUpdater({
database: kyselyAdapter({ db, provider: "sqlite" }),
plugins: [insights(), apiKeys()],
storage: s3Storage({
region: "auto",
endpoint: process.env.R2_ENDPOINT,
credentials: {
accessKeyId: process.env.R2_ACCESS_KEY_ID!,
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
},
bucketName: process.env.R2_BUCKET_NAME!,
}),
});kyselyAdapter({ db, provider }) takes only these two options. It returns an
engine database with the migrator that hot-updater db runs. provider is
"postgresql", "mysql" or "sqlite" and must match the Kysely dialect. The
adapter runs Hot Updater's shared SQL core on the Kysely instance, with one
transaction per write; on SQLite, each transaction begins with
BEGIN IMMEDIATE. insights() records app events, and apiKeys() protects
the client routes with the x-api-key header.
Schema management
Generate an SQL migration file for Hot Updater's tables:
mkdir -p data
npx hot-updater db generate src/hotUpdater.ts --yesApply the schema to the database:
npx hot-updater db migrate src/hotUpdater.tsGenerate vs Migrate
generate- Writes the SQL tohot-updater_migrations/for review or for your own migration toolmigrate- Applies the same SQL to the database through Kysely
The SQL creates the tables and indexes, with no database foreign keys, then
writes the schema settings rows last. The tables are core's and those of the
server's plugins. db migrate runs it in one transaction
on PostgreSQL and SQLite. Both commands read the database first and do
nothing when its settings are current; run db migrate again after upgrading
Hot Updater. They refuse a database created by an older Hot Updater schema
instead of converting it; start from an empty database.
The server checks the settings rows before its first read or write. Until
they exist, it throws HotUpdaterSchemaMigrationRequiredError and its
handlers answer 503. A running server checks again on its next request, so it
recovers once the migration has run.
Need plain SQL to apply yourself? See SQL
Export for standalone SQL generation with
the --sql flag.
CLI configuration
After the schema is applied, create the client API key
using this same direct server configuration. Then
connect the React Native project's CLI to the
protected admin mount. Its storage configuration must match a server entry,
and its plugins must list the server's plugins.
API endpoints
The adapter persists data; your framework mounts the HTTP handlers. Continue with the Hono, Express or Elysia recipe. See the handler boundaries and repository contract for client and admin access.
Finish with Set up your app and Test an OTA update.