Vercel
Since v0.22.0+Deploy Hot Updater server to Vercel with serverless functions.
Prerequisites
- Vercel account at vercel.com
- A current Marketplace Postgres integration, such as Neon
- Cloud storage (S3, R2, Supabase, Firebase, or custom)
Installation
Install required dependencies.
npm install @hot-updater/server @hot-updater/aws hono drizzle-orm pgnpm install @hot-updater/bare @hot-updater/standalone hot-updater drizzle-kit @types/pg dotenv --save-devConnect Postgres
Install a Postgres integration from the Vercel Marketplace, link the project, and pull its environment variables for local schema work:
npx vercel link
npx vercel env pull .env.localAdd the Hot Updater management and storage values to .env.local for local
development, and configure the same names for the Production environment in
your Vercel project settings:
HOT_UPDATER_AUTH_TOKEN=replace-with-a-secret
R2_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com
R2_ACCESS_KEY_ID=your-access-key-id
R2_SECRET_ACCESS_KEY=your-secret-access-key
R2_BUCKET_NAME=your-bucket-nameDatabase Setup
Create the database connection file.
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import * as schema from "../hot-updater-schema";
const pool = new Pool({ connectionString: process.env.DATABASE_URL! });
export const db = drizzle({ client: pool, schema, casing: "snake_case" });import { config } from "dotenv";
import { defineConfig } from "drizzle-kit";
config({ path: ".env.local" });
export default defineConfig({
schema: "./hot-updater-schema.ts",
out: "./drizzle",
dialect: "postgresql",
dbCredentials: { url: process.env.DATABASE_URL! },
});Hot Updater Configuration
Create the Hot Updater instance.
import { createHotUpdater } from "@hot-updater/server";
import { drizzleAdapter } from "@hot-updater/server/adapters/drizzle";
import { s3Storage } from "@hot-updater/aws";
import { db } from "./drizzle";
export const hotUpdater = createHotUpdater({
database: drizzleAdapter({ db, provider: "postgresql" }),
storages: [
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!,
}),
],
basePath: "/hot-updater",
routes: { updateCheck: true, bundles: true },
});Serverless Function
Create Vercel serverless function with Hono.
import { Hono } from "hono";
import { bearerAuth } from "hono/bearer-auth";
import { hotUpdater } from "./hotUpdater";
const managementToken = process.env.HOT_UPDATER_AUTH_TOKEN;
if (!managementToken) {
throw new Error("HOT_UPDATER_AUTH_TOKEN is required");
}
const app = new Hono();
app.use("/hot-updater/api/*", bearerAuth({ token: managementToken }));
app.mount("/hot-updater", hotUpdater.handler);
export default app;With Hono mount(), update-check routes such as /hot-updater/app-version/*
and /hot-updater/fingerprint/* are usually exposed for React Native clients,
but that is a deployment choice. /hot-updater/version is always mounted for
diagnostics. Always protect /hot-updater/api/* when routes.bundles: true.
Schema Generation
Generate the Drizzle schema for Hot Updater tables.
npx hot-updater db generate src/hotUpdater.ts --yes
npx drizzle-kit pushdb generate writes hot-updater-schema.ts; drizzle-kit push applies it to
Postgres. Use reviewed migrations for production change control.
Development
Run the development server locally.
npx vercel devServer runs at http://localhost:3000.
Deploy
Deploy to Vercel.
npx vercel deploy --prodYour Hot Updater server will be available at https://your-project.vercel.app/hot-updater.
CLI Configuration
Configure your CLI to use this deployed server.
import { bare } from "@hot-updater/bare";
import { s3Storage } from "@hot-updater/aws";
import { standaloneRepository } from "@hot-updater/standalone";
import { defineConfig } from "hot-updater";
const managementToken = process.env.HOT_UPDATER_AUTH_TOKEN;
if (!managementToken) {
throw new Error("HOT_UPDATER_AUTH_TOKEN is required");
}
export default defineConfig({
build: bare({ enableHermes: true }),
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!,
}),
database: standaloneRepository({
baseUrl: "https://your-project.vercel.app/hot-updater",
commonHeaders: { Authorization: `Bearer ${managementToken}` },
}),
updateStrategy: "appVersion",
});The storage plugin must match the storages in your server's createHotUpdater.