otherLiveFeatured

Native Update

com.aoneahsan.nativeupdate

Native Update is a production, NPM-published Capacitor plugin β€” `native-update` v3.0.1 β€” for OTA/live updates, app-store update checks, and in-app review prompts, shipped as a full monorepo with native Kotlin/Swift, a release-management CLI, a Laravel 11 + Nova 5 HTTP-only SaaS backend (Sanctum + Spatie RBAC), a React 19 marketing/dashboard site Capacitor-wrapped for Play Store, a public 58-page Docusaurus docs site, and two reference example apps.

2024-06 β†’ PresentOpen Source

At a glance

Category
other
Status
Live
Started
Jun 2024
Last updated
2 months ago

Identifier

com.aoneahsan.nativeupdate

Preview

Take a look before you go

The still below is painted first, then the running site loads behind it β€” so the dialog is never an empty rectangle waiting on a network round trip. Where a site allows framing the live app takes over; where it refuses, the still stays and says so. Nothing is requested until you press.

Native Update, as its brand card renders

About

What this actually is

How long does a typo live in a shipped mobile app?

As long as the review queue takes, plus however long your users take to update, and neither of those numbers belongs to you. Meanwhile the broken screen keeps opening.

That is the problem an over-the-air channel exists to solve, and it brings a worse one with it.

A path that can replace an app's code remotely is a path somebody else would like to use.

So integrity comes first. Every bundle is signed and verified with SHA-256 and RSA-SHA256, and one that does not verify does not run.

The second requirement is the one people skip. A bad bundle has to be able to undo itself with nobody in the loop, because the person who could intervene is asleep in a different timezone.

Fail to boot twice and the native side rolls back on its own.

native-update is a Capacitor plugin on npm, and around it sits everything an update channel actually needs rather than the plugin on its own.

A release-management CLI handles bundles. It creates them, signs them and verifies them before any of them leaves the machine.

A Laravel 11 and Nova 5 backend holds apps, keys and releases behind bearer-token authentication and role-based access control, so who may publish to a channel is a question with an answer rather than a convention. A React 19 dashboard sits on top of that, itself wrapped with Capacitor for the Play Store.

Store update checks and throttle-aware review prompts live in the same plugin, because an app that needs an over-the-air path also needs to know when a real store update is waiting for it.

Documentation runs to 58 public pages, with two runnable example apps beside it, because a plugin that changes how an app boots cannot honestly be explained in a README.

That is the difference between a package you can adopt and a package you can read about.

198 tests hold it: 62 in TypeScript and 136 in Pest, with a Detox suite running the end-to-end path against a real build rather than against a mock of one.

One release deliberately removed Firestore so the whole system runs through a single HTTP backend. Deleting a dependency is the change that never demonstrates well and always pays.

The plugin makes one demand.

It must confirm a healthy boot. An app that forgets rolls itself back after two cold starts and looks, from the outside, exactly like an update that was broken β€” which is the most expensive kind of bug, because it points at the wrong thing.

Signing keys are the other cost. A key you lose is a channel you can no longer publish to, and there is no support desk here to reissue one for you.

This is one of the few things here with a backend that has to stay awake, which is the shape of the problem rather than a slip: an update channel needs somewhere for the update to come from.

Everything else I build is arranged so that no server has to be. This one could not be, and that is the honest price of a release path that does not queue behind a store reviewer.

There is no iOS build here. There is no Apple Developer account behind any of this, so Android is where the update path has actually been exercised.

A piece of infrastructure nobody can inspect is a piece of infrastructure nobody should install. The npm page, the 58 pages of documentation and the two runnable example apps are all open to anybody, and that is the whole of the argument.

Worth knowing

  • Full ecosystem, not just a package β€” most NPM Capacitor plugins ship only the plugin; this ships plugin + CLI + native Android/iOS + backend + dashboard + public docs + example apps.
  • v3.0.0 removed a backend on purpose β€” Firestore deleted (~3000+ deletions) so all deviceβ†’server traffic goes through one Laravel HTTP API; simpler ops, single source of truth.
  • Production-shape auth without Firebase lock-in β€” Laravel Socialite redirect + Sanctum personal-access tokens + Spatie RBAC, swapped in a single 2026-05-11 cutover.
  • Deliberate dependency restraint β€” `commander` is held at v14 because v15 raises the Node floor to 22.12 while the published package promises `node >=18`; bumping would silently break older-Node consumers. Honest compatibility over a green "all latest" badge β€” re-affirmed in the 2026-06-05 pass (ncu reject list).
  • Triple module output from one source β€” a single `dist/esm/index.js` Rollup-bundles into ESM (`plugin.esm.js`), CJS (`plugin.cjs.js`), and an IIFE (`plugin.js` for unpkg), with `dist/esm/index.d.ts` types β€” so consumers on any module system import cleanly.
  • Public Docusaurus docs site β€” 58 DiΓ‘taxis pages (~76k words), 30+ AI-bot allowlist, llms.txt/llms-full.txt/ai.txt/security.txt, 3 JSON-LD blocks per page β€” engineered to be AI-citable.
  • Eats its own dog food β€” consumed by `aoneahsan-portfolio` and other Ahsan projects as the canonical OTA strategy.
  • Go-public safety net β€” `docs/SECURITY-IF-REPO-PUBLIC.md` ships a secret-rotation table + history-scrub commands for the day the private repo flips public; DIY pentest checklist at `docs/security/PRE-LAUNCH-PENTEST-CHECKLIST.md` (10 sections, 9 attack paths).

Built with

  • TypeScript
  • CapacitorJS
  • Kotlin
  • Swift
  • Node.js
  • Laravel 11
  • Laravel Nova
  • React 19

Key features

What it does, and what that costs to build

Each of these is a capability the stack genuinely provides. None of them is an outcome nobody measured β€” there is no "cut onboarding by 40%" on this page, because no one measured onboarding.

  • Live/OTA bundle updates (no store re-submission)
  • App-store update checks (Play Core + StoreKit)
  • In-app review prompts (throttle-aware)
  • Signed bundles + crash-rollback safety
  • Release-management CLI (bundle create/sign/verify)
  • Laravel 11 + Nova 5 SaaS backend (Sanctum + RBAC)
  • Public 58-page Docusaurus docs site

Screenshots

5 slots, 2 of them filled in

These are designed frames, not pictures. Each one records what belongs in the slot and at what width; the capture itself is taken from the running app. Drawing a fake screenshot here would put an image on the site that no build has ever produced.

Timeline

Still being worked on

  1. Jun 2024

    Work started

    The earliest month on record for Native Update.

  2. Sep 2026

    Last change

    Status is completed β€” 2 months ago. Ongoing, so this row moves whenever something lands.

Questions

Common questions

The questions that actually arrive, answered in the first sentence.

Who built native-update?
Ahsan Mahmood built it alone: the plugin, the release CLI, the Laravel backend, the dashboard and the documentation site. It is published on npm as native-update and the dashboard is at nativeupdate.aoneahsan.com. The native Android implementation and the TypeScript surface were written by the same person, which is why they agree with each other.
What happens if an over-the-air bundle breaks the app?
The native side rolls back on its own after the app fails to boot twice, so a broken bundle recovers without anybody being woken up. That is why the plugin requires the app to confirm a healthy start rather than assuming one, because silence is treated as failure. Bundle integrity is checked before that point too, with SHA-256 and RSA-SHA256 signing, so a bundle that has been altered never gets far enough to crash.
Does native-update work on iOS apps?
There is no iOS build and no App Store presence behind this work, because there is no Apple Developer account here β€” so the honest answer is that the over-the-air path is proven on Android. Treat anything else as unverified until somebody with an Apple account has actually run it.
Where do the bundles come from?
From a Laravel 11 and Nova 5 backend that holds apps, keys and releases, with bearer-token authentication and role-based access control in front of them. A release-management CLI creates, signs and verifies a bundle before it is uploaded, so the signing step is part of the release rather than an optional extra. One release deliberately removed Firestore from the system so that everything runs through that single HTTP backend.
How do I add native-update to a Capacitor app?
Install it from npm as native-update, then wire the healthy-boot confirmation into your app's start-up path before anything else. The documentation site runs to 58 pages and two runnable example apps ship with the project, which between them cover the wiring the README cannot. Skipping the boot confirmation is the one mistake that turns a working install into an app that rolls itself back.

Keep looking

More from the catalogue

  • ST

    Strata Storage

    com.aoneahsan.stratastorage

    One storage API across localStorage, IndexedDB, cookies, the URL, native Keychain and Keystore, SQLite and the filesystem. Zero dependencies.

    completedFeatured
  • CA

    Capacitor Auth Manager

    com.aoneahsan.capacitorauthmanager

    Framework-agnostic TypeScript authentication library unifying 15 OAuth, passwordless, credential, and biometric sign-in flows behind one provider-less API.

    completed
  • ZT

    ZTools

    com.zaions.ztools

    A privacy-first developer and power-user toolbox covering 20 categories, where the work happens in your browser rather than on someone's server.

    completedFeatured
All 23 projects