VM Patches

Fix your compiled Dart code on a live app, over the air. VM Patches replace the actual Dart that runs in the VM — the part a Runtime Bundle can't touch — so you can ship a real bug fix without waiting for store review.

When to reach for a VM Patch

If a change is a value — a limit, a URL, a toggle — a Runtime Bundle is simpler and works on any build. Reach for a VM Patch when the fix is in code: a wrong calculation, a null-check you forgot, a broken navigation flow, a crash in a specific screen. Anything you'd normally fix in a .dart file and re-ship through the store.

What a VM Patch can and can't change

  • Your Dart application code — logic, widgets, fixes
  • Adding, removing, or changing a Dart package your code uses (Android)
  • Native code (Kotlin/Java, Swift/Objective-C)
  • Native plugins, permissions, or the app manifest
  • The Flutter engine or Dart SDK version

Requirements

VM Patches have two requirements that Runtime Bundles don't:

  • Built with the Koolbase engine. The shipped binary must be built with koolbase build using the Koolbase engine for your Flutter version — that's what contains the interceptor that applies patches. A stock Flutter build cannot receive VM Patches.
  • A matching engine for your Flutter version. Each Flutter version has its own Koolbase engine build. See Flutter Versions & Engines.

The integration

On the app side there's nothing extra to write — Koolbase.initialize() sets up the VM patch client (KoolbaseVmPatchClient) automatically. It checks the resolver, downloads, and stages patches for you.

main.dart
dart
await Koolbase.initialize(
  KoolbaseConfig(
    baseUrl: 'https://api.koolbase.com',
    publicKey: 'pk_live_...',
    codePushChannel: 'stable',
  ),
);
// VM patch client is now running. It will check for a patch matching
// this binary, stage it, and the engine applies it on the next launch.

Applied before your code runs

Verification and apply happen at launch, before your application code executes — on iOS, before the first frame renders. Your code never sees a half-applied state: a patch either passes the full verification chain and runs, or is rejected and the previous code runs.

Building and pushing a patch

When you have a fix, recompile your app binary and push a diff patch against the build that's live. The CLI builds, signs, uploads, and (with --publish) makes it live in one command:

koolbase patch push \
  --app <project_id> \
  --binary ./base/libapp.so \   # the build that's live
  --new ./fixed/libapp.so \     # your recompiled fix
  --diff \
  --key ./private.key \
  --platform android \
  --channel stable \
  --rollout 25 \
  --publish

On iOS, you author the patch from your fixed Dart source and ship it in one command — the release build_id is derived from your binary automatically:

koolbase patch ios build \
  --source lib/main.dart \
  --app-package myapp \
  --engine 3.44.4-koolbase.4

koolbase patch push-ios \
  --app <project_id> \
  --kbpi myapp_patch.kbpi \
  --binary ./Runner.app/Frameworks/App.framework/App \
  --key ./private.key

See the full command set, including stage-local, list, recall, and publish, in the CLI Reference.

Keep your base binary

Patches target the exact binary that's live. Keep the build artifact you shipped to the store — on Android you'll diff every future fix against it, and on iOS it's the source of the build_id every patch is pinned to. Don't rebuild the base between releases; build once, ship it, and patch against that frozen binary.

Testing a patch locally

Before pushing to the server, you can build a patch and stage it directly on a device for testing with stage-local — useful while developing against the engine:

koolbase patch stage-local \
  --binary ./base/libapp.so \
  --new ./fixed/libapp.so \
  --diff \
  --key ./private.key

Safety & compliance

Every patch is signature- and build_id-verified, diff patches are hash-checked after reconstruction, and a patch that fails to boot auto-reverts — the full chain is described in How It Works. Because VM Patches change app behavior, they carry compliance responsibilities: use them for fixes, not for shipping features around review. Read Store Compliance before using them on a production app.