npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tiledev/tile-push-cli

v0.1.0

Published

Tile Push CLI — OTA deploys for React Native, built on top of hot-updater.

Readme

Tile Updater

Over-the-air (OTA) code-push updates for React Native — ship JS/asset changes to installed apps without an app-store release. Multi-tenant, fingerprint-safe, and self-contained: the SDK and CLI are plain npm packages.

  • @tiledev/tile-updater — the runtime SDK (wrap your app; devices auto-update on launch).
  • @tiledev/tile-push-cli — the tile-push CLI (init, fingerprint, deploy, manage bundles).

Built on hot-updater.


Install

npm install @tiledev/tile-updater @hot-updater/react-native @hot-updater/core
npm install --save-dev @tiledev/tile-push-cli @hot-updater/expo

@hot-updater/react-native and @hot-updater/core are peer dependencies of the SDK — install them explicitly. Use @hot-updater/metro instead of @hot-updater/expo for a bare React Native (non-Expo) project.

Using the Tile platform? Skip all of this — tile init --blueprint default installs and wires the SDK, the config plugin, tile-push.config.ts, the app wrap, and a reconciled lockfile automatically. Jump to Ship an update.


Wire it up (3 steps)

1. Wrap your root component

// App.tsx
import { TileUpdater } from '@tiledev/tile-updater';

function App() {
  return <YourAppRoot />;
}

export default TileUpdater.wrap({
  appId: 'your-app-id',                // your Tile Push tenant id
  apiUrl: 'https://ota.tile.dev',      // the OTA backend
  updateStrategy: 'fingerprint',       // or 'appVersion'
})(App);

2. Register the Expo config plugin

app.json → expo.plugins. This injects the native fingerprint into the build so devices only receive bundles built from a matching native tree:

{
  "expo": {
    "plugins": ["@tiledev/tile-updater"]
  }
}

3. Create tile-push.config.ts

Run npx tile-push init --app-id <id> --token <deploy-token>, or write it by hand:

import 'dotenv/config';
import { defineConfig } from 'hot-updater';
import { expo } from '@hot-updater/expo';
import { tilePushDatabase, tilePushStorage } from '@tiledev/tile-push-cli';

const appId = process.env.TILE_PUSH_APP_ID;
if (!appId) throw new Error('TILE_PUSH_APP_ID is not set (see .env).');

export default defineConfig({
  build: expo({ enableHermes: true }),
  storage: tilePushStorage({ appId }),
  database: tilePushDatabase({ appId }),
  updateStrategy: 'fingerprint',
});

Ship an update

The fingerprint is a hash of your native inputs (deps, native config). A bundle is only served to devices whose installed build has the same fingerprint — so a JS push can never land on an incompatible native app. Keep fingerprint.json committed as the single source of truth.

1. Fingerprint (once per native change)

npx tile-push fingerprint create   # writes fingerprint.json

For Expo prebuild projects the order is prebuild → fingerprint create → prebuild (injects the hash) → build. The value is stable across re-injection.

2. Build the native app

Any normal build works — the SDK is just a package, and the config plugin injects the fingerprint at expo prebuild. No OTA/deploy step happens during the build.

3. Deploy

npx tile-push deploy --platform android --rollout 10   # ship to 10% of devices
npx tile-push deploy --platform android                # ship to everyone

deploy bundles your JS (Hermes), verifies its fingerprint matches fingerprint.json, tags the bundle, and uploads it. Devices whose native build matches pick it up on next launch; others are correctly skipped.


Commands

| Command | Description | | --- | --- | | tile-push init | Write tile-push.config.ts + ~/.tile-push/credentials.json | | tile-push fingerprint create | Compute/snapshot the native fingerprint | | tile-push deploy | Build and ship a new bundle (supports staged --rollout) | | tile-push bundle list/show/enable/disable/update/promote/delete | Manage bundles | | tile-push rollback <channel> | Disable the most recent enabled bundle | | tile-push channel [set] | Read/write the channel baked into the native app | | tile-push whoami | Show the active tenant + token | | tile-push doctor | Diagnose config / credentials / server / project | | tile-push console | Open the web console for this tenant |

Credentials

The CLI reads credentials in this order:

  1. TILE_PUSH_APP_ID + TILE_PUSH_TOKEN env vars (preferred for CI)
  2. ~/.tile-push/credentials.json (written by tile-push init, chmod 600)

Never put tokens in tile-push.config.ts — it's committed to your repo. Override the API base URL with TILE_PUSH_API_URL.


On the Tile platform

Apptile customers manage the same thing through the unified CLI — tile ota forwards to this binary with the app id + session token injected automatically:

tile ota deploy --platform android --rollout 10
tile ota bundle list
tile ota rollback production

tile init --blueprint default installs and wires everything above, so a fresh app is code-push-ready after npm install.


Roadmap

  • Cloud Push — deploy an OTA bundle remotely from a tile save or git ref, the same way native builds already run in the cloud. The bundle is built in the same container as the APK, so the fingerprint matches by construction — no local toolchain, no fingerprint drift. Planned surface: tile ota deploy --source save|git, with a reach-check that refuses a push no installed build can receive.
  • iOS build/deploy parity docs.
  • First-class staged-rollout cohort tooling in the CLI.
  • tile-push login — browser device-code flow that mints and stores a token.

Acknowledgements

Built on hot-updater (MIT). Tile Push wraps it with hosted storage, auth, multi-tenancy, and a unified deploy CLI. The bundle pipeline, fingerprinting, and bundle metadata model are hot-updater's work.

License

MIT. See LICENSE.