Skip to content

doyoonkim12345/cloud-push

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Cloud Push

OTA Update solution compatible with Expo Updates

β†’ Self-hosted update distribution system

Typescript Only, Zero kotlin, Zero Swift, Zero java, Zero Object-C

2025-05-21.9.45.54.mp4

@cloud-push/cloud
@cloud-push/expo
@cloud-push/next
@cloud-push/cli
@cloud-push/utils

πŸ“š Documentation

You can find the full usage guide and API reference in the
πŸ‘‰ Cloud Push Docs

πŸš€ Motivation

Expo projects are highly customized React Native projects. Because of this, available CodePush solutions are limited.
This project, inspired by hot-updater, offers an alternative way to manage bundles using storage services like S3, Firebase, Supabase, etc.
It follows Expo Updates technical specs and maintains compatibility with Expo Updates.

πŸ§ͺ Compatibility

  • βœ… Works with expo run:android --variant release
  • βœ… Works with expo run:ios --configuration Release
  • βœ… Compatible with Expo Managed Workflow

✨ Key Features

  • πŸ“‘ Self-hosted deployment supported
  • πŸ“¦ Flexible storage & DB (S3, Supabase, Firebase, etc.)
  • πŸ”„ Compatible with Expo Updates APIs
  • πŸ’Ύ Web-based bundle version dashboard
  • 🌐 Supports expo.dev environment variables (via EAS Secrets)
  • πŸͺŸ Works on Windows
  • πŸ§ͺ EAS build supported

πŸ›  Configuration Examples

Supabase

import { defineConfig } from "@cloud-push/cli";
import { SupabaseStorageClient, SupabaseDbClient } from "@cloud-push/cloud";

export default defineConfig(() => ({
  loadClients: () => {

    const storageClient = new SupabaseStorageClient({
      bucketName: process.env.SUPABASE_BUCKET_NAME!,
      supabaseUrl: process.env.SUPABASE_URL!,
      supabaseKey: process.env.SUPABASE_KEY!,
    });

    const dbClient = new SupabaseDbClient({
      tableName: process.env.SUPABASE_TABLE_NAME!,
      supabaseUrl: process.env.SUPABASE_URL!,
      supabaseKey: process.env.SUPABASE_KEY!,
    });
    
		return {
			storage: storageClient,
			db: dbClient,
		};
	},
}));

AWS S3 + lowdb

import { defineConfig } from "@cloud-push/cli";
import { AWSS3StorageClient, LowDbClient } from "@cloud-push/cloud";

export default defineConfig(() => ({
  loadClients: () => {
    
    const storageClient = new AWSS3StorageClient({
      accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
      bucketName: process.env.AWS_BUCKET_NAME!,
      region: process.env.AWS_REGION!,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
    });

    const dbClient = new LowDbClient({
      downloadJSONFile: () => storageClient.getFile({ key: "cursor.json" }),
      uploadJSONFile: (file: Uint8Array) =>
        storageClient.uploadFile({ key: "cursor.json", file }),
    });

    return {
      storage: storageClient,
      db: dbClient,
    };
  },
}));

Firebase

import { defineConfig } from "@cloud-push/cli";
import { FirebaseStorageClient, FirebaseDbClient } from "@cloud-push/cloud";

export default defineConfig(() => ({
  	loadClients: () => {
		const storageClient = new FirebaseStorageClient({
			credential: process.env.FIREBASE_CREDENTIAL!,
			bucketName: process.env.BUCKET_NAME!,
		});

		const dbClient = new FirebaseDbClient({
			credential: process.env.FIREBASE_CREDENTIAL!,
			databaseId: process.env.FIREBASE_DATABASE_ID!,
		});

		return {
			storage: storageClient,
			db: dbClient,
		};
	},
}));

πŸ“˜ Expo Updates SDK Compatibility

🧱 Constants

Constant Supported
Updates.channel βœ…
Updates.checkAutomatically βœ…
Updates.createdAt βœ…
Updates.emergencyLaunchReason ⏳
Updates.isEmbeddedLaunch βœ…
Updates.isEmergencyLaunch ⏳
Updates.isEnabled βœ…
Updates.latestContext βœ…
Updates.launchDuration βœ…
Updates.manifest βœ…
Updates.runtimeVersion βœ…
Updates.updateId βœ…

🧩 Hooks

Hook Supported
useUpdates() βœ…

πŸ›  Methods

Method Supported
checkForUpdateAsync() βœ…
clearLogEntriesAsync() βœ…
fetchUpdateAsync() βœ…
getExtraParamsAsync() ❌
readLogEntriesAsync() βœ…
reloadAsync() βœ…
setExtraParamAsync() ❌

About

Self-hostable OTA solution for Expo projects compatible with expo-updates (as an alternative to EAS Update)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published