Home
Softono
hot-updater

hot-updater

Open source TypeScript
1.5K
Stars
150
Forks
22
Issues
10
Watchers
1 week
Last Commit

About hot-updater

A self-hostable OTA update solution for React Native (Alternative to CodePush)

Platforms

Web Self-hosted

Languages

TypeScript

Hot Updater

Vercel OSS Program



NPM pkg.pr.new

image

hot-updater

Documentation

Full documentation is available at: https://hot-updater.dev

AI Skills

Attach the Hot Updater agent skill so AI coding agents can use concise CLI context for deploys, bundle management, rollbacks, and verification: .agents/skills/hot-updater/SKILL.md

  npx skills add gronxb/hot-updater --skill hot-updater

Then ask your agent with prompts like $hot-updater deploy using the current app version or $hot-updater roll back the most recently deployed bundle.

See the AI Agent Guide for the full workflow.

Key Features

  • Self-Hosted: Complete control over your update infrastructure
  • Multi-Platform: Support for both iOS and Android
  • Web Console: Intuitive update management interface
  • Plugin System: Support for various storage providers (AWS S3, Cloudflare R2 + D1, etc.)
  • Version Control: Robust app version management through semantic versioning
  • New Architecture: Support for new architecture like React Native

Plugin System

Hot Updater provides high extensibility through its plugin system. Each functionality like build, storage, and database is separated into plugins, allowing users to configure them according to their needs.

Plugin Types

  • Build Plugin: Support for bundlers like Metro, Re.Pack, Expo
  • Storage Plugin: Support for bundle storage like AWS S3, Supabase Storage, Cloudflare R2 Storage
  • Database Plugin: Support for metadata storage like Supabase Database, PostgreSQL, Cloudflare D1

Configuration Example

  • Supabase
    
    import { bare } from "@hot-updater/bare";
    import { supabaseDatabase, supabaseStorage } from "@hot-updater/supabase";
    import { config } from "dotenv";
    import { defineConfig } from "hot-updater";

config({ path: ".env.hotupdater" });

export default defineConfig({ build: bare({ enableHermes: true }), storage: supabaseStorage({ supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!, supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!, bucketName: process.env.HOT_UPDATER_SUPABASE_BUCKET_NAME!, }), database: supabaseDatabase({ supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!, supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!, }), });


* [Cloudflare](https://hot-updater.dev/docs/managed/cloudflare)
```tsx
import { bare } from "@hot-updater/bare";
import { d1Database, r2Storage } from "@hot-updater/cloudflare";
import { config } from "dotenv";
import { defineConfig } from "hot-updater";

config({ path: ".env.hotupdater" });

export default defineConfig({
  build: bare({ enableHermes: true }),
  storage: r2Storage({
    bucketName: process.env.HOT_UPDATER_CLOUDFLARE_R2_BUCKET_NAME!,
    accountId: process.env.HOT_UPDATER_CLOUDFLARE_ACCOUNT_ID!,
    cloudflareApiToken: process.env.HOT_UPDATER_CLOUDFLARE_API_TOKEN!,
  }),
  database: d1Database({
    databaseId: process.env.HOT_UPDATER_CLOUDFLARE_D1_DATABASE_ID!,
    accountId: process.env.HOT_UPDATER_CLOUDFLARE_ACCOUNT_ID!,
    cloudflareApiToken: process.env.HOT_UPDATER_CLOUDFLARE_API_TOKEN!,
  }),
});
  • AWS S3 + Lambda@Edge
    
    import { bare } from "@hot-updater/bare";
    import { s3Storage, s3Database } from "@hot-updater/aws";
    import { config } from "dotenv";
    import { defineConfig } from "hot-updater";

config({ path: ".env.hotupdater" });

const options = { bucketName: process.env.HOT_UPDATER_S3_BUCKET_NAME!, region: process.env.HOT_UPDATER_S3_REGION!, credentials: { accessKeyId: process.env.HOT_UPDATER_S3_ACCESS_KEY_ID!, secretAccessKey: process.env.HOT_UPDATER_S3_SECRET_ACCESS_KEY!, }, };

export default defineConfig({ build: bare({ enableHermes: true }), storage: s3Storage(options), database: s3Database(options), });


* [Firebase](https://hot-updater.dev/docs/managed/firebase)
```tsx
import { bare } from '@hot-updater/bare';
import {firebaseStorage, firebaseDatabase} from '@hot-updater/firebase';
import * as admin from 'firebase-admin';
import { config } from "dotenv";
import { defineConfig } from "hot-updater";

config({ path: ".env.hotupdater" });

// https://firebase.google.com/docs/admin/setup?hl=en#initialize_the_sdk_in_non-google_environments
// Check your .env file and add the credentials
// Set the GOOGLE_APPLICATION_CREDENTIALS environment variable to your credentials file path
// Example: GOOGLE_APPLICATION_CREDENTIALS=./firebase-adminsdk-credentials.json
const credential = admin.credential.applicationDefault();

export default defineConfig({
  build: bare({
    enableHermes: true,
  }),
  storage: firebaseStorage({
    projectId: process.env.HOT_UPDATER_FIREBASE_PROJECT_ID!,
    storageBucket: process.env.HOT_UPDATER_FIREBASE_STORAGE_BUCKET!,
    credential,
  }),
  database: firebaseDatabase({
    projectId: process.env.HOT_UPDATER_FIREBASE_PROJECT_ID!,
    credential,
  }),
});