LerixBlog
ArticlesChangelogChangelogDocs
العربية
Dashboard
Lerix

The Lerix blog: guides for app developers, and news of every release of Lerix and its SDKs.

Blog

ArticlesChangelog RSS feed

Lerix

HomePricingDocsRefund policy

© 2026 Lerix · All rights reserved

LerixBlog
ArticlesChangelogChangelogDocs
العربية
Dashboard
  1. Lerix Blog
release controlfluttermobile

Force an app update or turn on maintenance mode, without shipping a release

An old version breaks against your new API, or the backend needs an hour offline. Set update rules and maintenance windows from the dashboard and every app follows within minutes.

The Lerix team

30 October 20267 min read

An 'Update required' screen, the release control settings, and a 'Back soon' maintenance screen
On this page
  1. How it reaches the apps
  2. Update rules: suggest, recommend, require

Read next

A Flutter checkout screen failing, its stack trace, and the grouped issue in the Lerix dashboard
flutterع

Crash reporting for Flutter apps: a practical setup guide

Most users never report a crash, they just leave. Set up crash reporting in a Flutter app in minutes: what gets caught, how to add context, and how to cut the noise.

30 October 20266 min read

One user in the centre, receiving the same notification on an iPhone, an Android phone, Chrome and a Mac
pushع

Send a push notification to a person, not a device

Your users have a phone, a laptop and a browser tab. Stop storing device tokens: link devices to your own user ID and send once to iOS, Android, web and macOS.

Lerix

The Lerix blog: guides for app developers, and news of every release of Lerix and its SDKs.

Blog

ArticlesChangelog RSS feed

Lerix

HomePricingDocsRefund policy

© 2026 Lerix · All rights reserved

  • Maintenance mode
  • In the app
  • Your own screens
  • Did people actually update?
  • Limits worth knowing
  • Checklist
  • Two situations every mobile team runs into sooner or later:

    • An old version has to go. It crashes against the new API, it has a security hole, or it charges the wrong price. You shipped the fix, but app stores don't force anyone to update, and a few thousand people are still on version 1.8.
    • The backend needs to go offline. A database migration, a provider outage, a launch you want to hold until 9 a.m. Meanwhile the apps keep calling your API and show their users a wall of errors.

    The usual fix is a "minimum version" field on your own server and a screen in the app that checks it. It works, until you notice you can't change the screen without a release, and that apps already in people's hands can only do what you built into them in advance.

    Lerix release control builds that in: you set the rules in the dashboard, and the SDK shows the right screen in every app, on iOS, Android, macOS, Windows and the web.

    How it reaches the apps

    Rules are evaluated on Lerix's side. The app asks "what applies to me?" and gets back an answer for its exact platform, version, build, environment and country.

    • At launch, the app applies the last answer it saved before making any request, so a blocking screen is up from the first frame, even offline. Then it fetches a fresh one.
    • When the app comes back to the foreground, it checks again if the saved answer is older than its lifetime: 5 minutes normally, 1 minute during maintenance and for half an hour after you change anything.
    • On iOS, Android and macOS, blocking changes (maintenance starting or ending, a forced update) also send a silent push, so most devices update within a minute. It's best-effort: the system may delay it in low-power mode.

    Unchanged answers cost almost nothing: the app sends what it has, and Lerix replies "not modified".

    Update rules: suggest, recommend, require

    Each platform gets its own rule per environment (prod unless you choose another). A rule can hold:

    • Latest version (and build): anyone below it is offered the update.
    • Minimum version (and build): anyone below it is blocked until they update.
    • Blocked versions: specific broken releases, blocked even if they're above the minimum.
    • Below latest: show the update as Optional (can be skipped) or Recommended (can't be skipped, can be postponed).
    • Becomes required on: a deadline after which the recommended update turns into a required one.
    • Remind again after: how long "Later" lasts, 72 hours by default.
    • Countries, a store link override and a message in English and Arabic.

    Lerix checks them in this order: a blocked version is required; below the minimum is required; below the latest is optional or recommended (or required once the deadline has passed); otherwise nothing is shown. Versions are compared as numbers, part by part, so 1.10.0 is newer than 1.9.2.

    Blocking users is serious, so the dashboard shows the effect while you type, for example "This will block 1,240 devices (31%)", and asks you to confirm when a rule would stop half your active devices or set a minimum above every version seen in the wild. A Versions in the wild list shows what people are actually running.

    The Update button opens the store page: Google Play from your package name, or the App Store from your app's id, which the dashboard can look up for you.

    Maintenance mode

    Maintenance lives on the Emergency tab. A window has:

    • a scope: platforms, environment, specific versions or versions below one, countries;
    • a title and message in English and Arabic, and an optional "Expected back at", shown in the device's time zone;
    • a start: now, or scheduled up to 30 days ahead. Devices learn about a scheduled window up to 24 hours early and keep it to themselves, so it starts on time even on a phone that has gone offline;
    • an end: every window has one, 24 hours after the start by default and 7 days at most, so a forgotten window can't lock people out. Devices lift it on their own at that time, even with no network.

    Two features make it safe to use in a hurry:

    • An allow-list of user ids or installs that are let through, for your team.
    • Test on allow-listed devices only: the window applies to your own devices first. When it looks right, Go live, and every device in scope sees the maintenance screen within a minute.

    Turning maintenance on asks for a reason and for you to type the project slug, and every change lands in the History with who made it. Lift all ends every maintenance window and turns off every forced update in one step, for the moment you realise the rule was a mistake.

    In the app

    In Flutter, release control is on by default once lerix_flutter is set up. There is no widget to add: the SDK puts its screens over your app's top-level navigator.

    Lerix.init(
      url: 'https://api.lerix.dev/v1/your-project-slug',
      apiKey: 'your-api-key',
      projectId: 'your-project-slug',
      appControl: const LerixAppControlOptions(
        enabled: true,  // false: no checks, no screens, no events
        ui: true,       // false: draw your own screens
      ),
      builder: () => runApp(const MyApp()),
    );
    

    The built-in screens are a full-screen maintenance page with Try again, a full-screen Update required page, and a dialog for optional and recommended updates. Their buttons come in English and Arabic, right to left included.

    On Android you can go one step further: add the lerix_app_update package and a required update opens Google Play's in-app update instead of the store page, for apps installed from Play. Apps that don't use Play don't ship that library.

    On the web, set release to the version you deploy. There's no store there, so Update reloads the page:

    import { Lerix } from '@lerix-dev/lerix-core';
    
    await Lerix.initialize({
      apiKey: 'your-api-key',
      projectId: 'your-project-slug',
      release: '1.4.0', // update rules need it; use numbers, not a commit hash
    });
    

    Your own screens

    Set ui: false and draw them yourself. The SDK still fetches, saves and applies everything, including the offline rules; only the drawing is yours:

    ValueListenableBuilder<LerixAppControlState>(
      valueListenable: Lerix.appControl,
      builder: (context, state, _) {
        final maintenance = state.maintenance;
        final update = state.update;
        if (maintenance != null) {
          return MaintenanceScreen(
            title: maintenance.title,
            message: maintenance.message,
            onRetry: () => Lerix.appControl.refresh(),
          );
        }
        if (update != null && update.state == LerixUpdateState.required) {
          return ForceUpdateScreen(
            message: update.message,
            onUpdate: () => Lerix.appControl.openStore(),
          );
        }
        return child;
      },
    );
    

    React has the same as a hook, useLerixAppControl(), and Angular as LerixAppControlService.

    Did people actually update?

    The SDK records $update_prompt_shown, $update_prompt_action (update, later or skip) and $maintenance_shown. Together with the app's version changes they form a funnel in Analytics → Funnels: how many saw the prompt, tapped Update, and arrived on the new version. The propagation meter on the Emergency tab shows how many active devices already have your latest change.

    Limits worth knowing

    • Release control runs inside your app, so a modified or very old build can ignore it. Keep enforcing anything security-critical on your backend too.
    • A version with no digits in it can't be compared, so it's never blocked.
    • Saved optional updates expire 7 days after the last successful check; a saved required update keeps blocking offline until a check says otherwise. That's deliberate: failing open would defeat the point.

    Checklist

    1. Set Latest version on each platform as you release, so older versions get a gentle prompt.
    2. Use Minimum version or Blocked versions only for versions that are actually broken.
    3. Prefer a deadline over an immediate block when there's time: recommended first, required later.
    4. For maintenance, schedule it, test it on your own devices, then Go live.
    5. Keep Lift all in mind. It's the undo button.
    release controlfluttermobile
    Share X LinkedIn

    On this page

    1. How it reaches the apps
    2. Update rules: suggest, recommend, require
    3. Maintenance mode
    4. In the app
    5. Your own screens
    6. Did people actually update?
    7. Limits worth knowing
    8. Checklist

    30 October 20266 min read

    A minified stack trace next to the same error mapped back to TypeScript source
    source mapsع

    Readable stack traces from minified JavaScript: source maps and error grouping

    index-8f3a1c.js:1:48213 tells you nothing. Upload source maps from your build so every error points at your own file, line and function, and see how errors become issues.

    30 October 20266 min read

    Catch your next crash before your users report it

    Crash reporting, push, analytics and an AI assistant that reads your code. Free to start.

    Start free