knowa_sdk

Code push for Flutter. Fix a bug in your Dart code, run knowa patch, and the fix reaches apps that are already installed — no store release, no reinstall. It runs on the stock Flutter SDK, with no forked engine, and every patch is signed with a key only you hold.

This is the part that goes in your app. It checks the Knowa service for a patch, verifies its signature, and runs it. Anything a patch does not touch runs exactly as you shipped it.

Get started

  1. Install the Knowa CLI and sign up at knowa.knowalabs.com:

    curl -fsSL https://knowa.knowalabs.com/install.sh | sh
    
  2. In your Flutter app:

    flutter pub add knowa_sdk
    knowa init
    

    knowa init creates your signing keys and lib/knowa_config.dart, which carries your app id and public keys into the build.

  3. Start Knowa before runApp:

    import 'package:flutter/material.dart';
    import 'package:knowa_sdk/knowa_sdk.dart';
    
    import 'knowa_app_bridge.g.dart'; // written by `knowa init`
    import 'knowa_config.dart'; // written by `knowa init`
    
    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Knowa.initialize(const KnowaConfig(
        appId: knowaAppId,
        trustedKeys: knowaTrustedPatchKeys,
        revocationKeys: knowaRevocationKeys,
        source: PatchSource.server('https://knowa.knowalabs.com'),
        bridges: knowaAppBridges,
      ));
      runApp(const MyApp());
    }
    

    PatchSource.hosted() means the same thing.

  4. Ship it, then patch it:

    knowa release   # builds your app and registers what shipped
    # ...fix the bug in your own code...
    knowa patch     # publishes the fix
    

Nothing in your code has to be annotated. knowa release works out which functions and build methods a patch can reach, and leaves your source as you wrote it.

The full guide is at knowa.knowalabs.com.

What it guarantees

  • Startup never waits on the network. initialize applies the patch already on the device and returns; the check for a newer one runs after the first frame, and what it finds applies on the next launch. updateMode: KnowaUpdateMode.blockingOnStart waits instead.
  • Anything that goes wrong runs your shipped code. An unreachable server, a patch signed by a key your build does not trust, a patch built for another version of your app, a corrupt download, a patch that throws — each ends with the code in your build, never a crash.
  • Only your key can change your app. A patch is verified on the device before anything reads it, against the public keys compiled into your build. The service stores and serves patches; it cannot sign one.
  • Withdrawn patches are recalled. Roll a patch back and devices revert to your shipped code on their next launch.

Requirements

  • The Flutter release the Knowa CLI names (knowa --version); 3.41.4 for this release. Build your app and your patches with the same one.
  • Android or iOS.

Configuration

appId the app this build accepts patches for
trustedKeys the Ed25519 public keys a patch may be signed with; a list, so a key can be rotated across two releases
revocationKeys keys that can revoke a leaked signing key; kept offline
source PatchSource.server(url, channel:), PatchSource.hosted(channel:), or PatchSource.file(url) for one signed file you host yourself
updateMode onNextLaunch (default) or blockingOnStart
onEvent every outcome, for your own logging
deviceIdentity generated() (default), supplied(id), or none()
reporting full (default), outcomesOnly, or none
storage, environment seams for encrypted storage or a pinned TLS client

Limits worth knowing

  • A patch changes function and method bodies. It cannot change a signature the shipped app calls, add native code, or touch assets; those need a store release, and knowa diff tells you which is which before you try.
  • Patched code runs slower than code compiled into your app. Right for UI and business logic, wrong for hot loops.
  • One Knowa per isolate.

License

BSD-3-Clause. See LICENSE.

Libraries

knowa_sdk
Knowa client SDK.
wrappers
Argument wrappers for values passed into a zone.