Make every user run the version you shipped
Teardown gates stale app versions from the dashboard. Block a broken build, require the latest, or nudge a soft update, and the SDK enforces it on the next check. No new native release to change the rule.
$ bun add @teardown/force-updatesWorks with Expo and bare RN. Free to start.A new version is available
This version is no longer supported. Update to keep using the app.
What's new
Fixes a checkout crash and a sync bug on cold start.
import { useForceUpdate } from '@teardown/force-updates'function App() { const { isUpdateRequired } = useForceUpdate() if (isUpdateRequired) { return <UpdateRequiredScreen /> } return <RootNavigator />}Already have an app? Read the 5-minute setup.
You shipped the fix. Your users are still on the bug.
App store updates are opt-in. A slice of your users runs builds you released months ago, hitting code paths you've already deleted and filing tickets for bugs that no longer exist.
Old clients hammer endpoints you want to retire
You can't change an API contract while months-old builds still call it. With opt-in updates, that long tail never fully goes away.
Critical fixes reach a fraction of users
A crash fix sitting in the store does nothing for the people who won't tap Update for weeks. The users who most need the patch are the slowest to get it.
Hand-rolled version checks rot
A DIY “please update” gate drifts out of sync with what's actually live, ships hardcoded version numbers, and becomes one more thing to maintain.
Three steps to a gated release
Integrate once. From then on, you control which versions can run from the dashboard.
Install the SDK
Add the package and the device adapter for your stack. Expo and bare React Native are both first-class.
bun add @teardown/force-updatesnpx expo install expo-device expo-applicationWrap your app
Drop the provider at your root. The SDK identifies the device, checks the version on launch, and re-checks every time the app returns to the foreground.
import { TeardownProvider } from '@teardown/force-updates'import { teardown } from './lib/teardown'export default function RootLayout() { return ( <TeardownProvider core={teardown}> <RootNavigator /> </TeardownProvider> )}Set the policy in the dashboard
Mark any version required, recommended, or disabled. No code change, no resubmission. The SDK picks it up on the next check.
Five states. One source of truth.
Every version reports exactly one status. Read it once with useForceUpdate() and decide how hard to push.
up_to_dateUp to dateThe build is current. Your app runs normally.
update_availableUpdate availableA newer version exists. Surface it on your own terms, or not at all.
update_recommendedRecommendedShow a dismissible banner that strongly nudges users to update.
update_requiredRequiredBlock the app behind a full-screen takeover until the user updates.
disabledDisabledKill a build entirely. The fastest way to pull a bad release.
Re-checks on foreground
Every time the app resumes, the SDK re-checks the policy on a configurable interval.
Cached for offline
The last known status is persisted, so the gate still works without a connection.
Release notes built in
Notes you write in the dashboard flow straight to useForceUpdate().releaseNotes.
Drop it into the stack you already have
One hook drives the whole flow. Swap adapters to match how your app already does storage, device info, and push, without touching the rest of your code.
function App() { const { isUpdateRequired, isUpdateRecommended, releaseNotes, } = useForceUpdate() if (isUpdateRequired) return <ForceUpdate notes={releaseNotes} /> if (isUpdateRecommended) return <SoftBanner notes={releaseNotes} /> return <RootNavigator />}Identity
Attach a user to a device with identify() and follow sessions across launches.
Event tracking
Send analytics events through the same client, no second SDK to wire up.
TypeScript-first
Fully typed states and hooks, with discriminated unions for every status.
Questions you're probably asking
- Isn't this just OTA, like Expo Updates or CodePush?
- OTA ships JavaScript bundles. It can't move a user off an old native binary, and it won't force anyone to do anything. Teardown gates by store version and can hard-block. Run it alongside your OTA pipeline, they solve different problems.
- Can't I just check the version myself?
- You can. Then you own the version service, the foreground polling, the offline cache, and the release-notes plumbing forever, and every release means editing a hardcoded number. That maintenance is exactly what the SDK is.
- Will the app stores allow a forced update?
- Yes. Teardown sends users to your store listing to update through the normal flow, it never side-loads anything. You decide when a version is too old to keep running.
Ship your next release like the old ones don't exist
Install the SDK, set a policy, and stop designing around users who never update.
Free tier. No credit card required.