Run the app
Use kasy run day to day. Simulator, physical device, web on port 5555, and kasy reset to test from scratch.
Implementation
-
Recommended: always use
kasy run(or the MCP). It's the complete path: loads credentials, shows the Kasy brand, and warns you when a CLI update is available.Via MCP: ask "run the app". The assistant asks for the platform (iOS, Android, or web) and, on web, whether you want only the URL, the default browser (
openBrowser), or Flutter's isolated Chrome (flutterChrome). For a fresh onboarding test on web, usefreshStorageorclear_web_storage. See Kasy MCP.Via terminal:
cd your_app kasy run # first available device kasy run --ios # iOS simulator kasy run --android # Android emulator kasy run --web # web at localhost:5555 kasy run --web --open-browser --fresh # default browser, storage cleared kasy run --web --open # Flutter's isolated Chrome kasy clear-web # clear storage only (app must already be running) kasy run --prod # uses launch.json's production config -
To validate the first-open flow (push, onboarding, ATT, Face ID), run:
Via MCP: "reset the app on iOS" (
reset_app).Via terminal:
kasy reset # detects the device, asks if there's more than one kasy reset --ios kasy reset --android kasy reset --web # clears dev storage in the browser (needs kasy run --web running) kasy reset -d <device-id> # specific device (ID from flutter devices) kasy reset --no-reinstall # only uninstallsUninstalls the app from the simulator/emulator and reinstalls it right after. A plain
flutter runkeeps the data and permissions already granted, so it doesn't work for this test (details in Information). -
When you're ready for a release build:
flutter build ipa --release --dart-define=ENV=prod # or simply: kasy ios release # already injects ENV=prod and bumps the buildVia MCP: "publish iOS" (
release_ios). See Kasy MCP.
Next step: see the app running.
Information
Why not just flutter run?
kasy run | flutter run | |
|---|---|---|
Reads the .env | Yes | Yes |
Injects --dart-define from launch.json | Yes | No |
| Picks the right RevenueCat key (simulator vs physical) | Yes | No |
| Kasy logo + update notice | Yes | No |
Automatic RevenueCat key
RevenueCat has three key types, and each one only works in one place:
| Key | Works on |
|---|---|
test_xxx | iOS simulator and Android emulator |
appl_xxx | Physical iPhone |
goog_xxx | Physical Android |
kasy run detects the device and injects the right key from the .env. You don't have to remember which one goes where.
RC_TEST_KEY=test_xxx
RC_IOS_PROD_KEY=appl_xxx
RC_ANDROID_PROD_KEY=goog_xxxWeb: which variant to pick
All of them run the same build and show the same screen, with the device preview frame included. The difference is only which window hosts the page:
| Command | What opens | When to use it |
|---|---|---|
kasy run --web --open-browser | Opens localhost:5555 in the system default browser (Chrome, Safari, Firefox, Edge…) | Day to day with a saved Google account, extensions, etc. |
kasy run --web --open-browser --fresh | Same, but clears dev storage first (localStorage, sessionStorage, IndexedDB) | Test the native-like preview flow without an incognito tab |
kasy clear-web | Only opens the clear URL (app already running) | Quick reset without restarting Flutter |
kasy run (pick Chrome in the picker) or kasy run --web --open | A new, isolated Chrome window: clean profile, no extensions or saved accounts | Quick QA, no leftover sessions or old data |
kasy run --web (no open flags) | Doesn't open anything on its own. Prints the URL (localhost:5555) in the terminal | Copy the URL, open manually, or let the MCP return the link only |
On the web, login stores the session by origin (domain + port), whether Supabase Auth or Firebase Auth. That's why the port is pinned at 5555: if it changed on every run, the login would seem to vanish.
If 5555 is already in use: kasy run --web --web-port 6000.
Initial screen in debug
kasy run may open on the last screen you were on (e.g., admin, components). This helps day-to-day work and hot restart (R). This isn't production behavior: in release, the app starts at Home (native) or at the URL the user opened (web). Details in Navigation → debug vs production.
Other ways (they work)
make run # without the CLI installed globally
flutter run # faster; uses the .env but without kasy run's extrasIn VS Code, F5 uses .vscode/launch.json (with a graphical debugger).
Full log for debugging errors
kasy run records all of Flutter's output to .kasy/run.log. Paste that file to an AI when you need help.
To see the raw output directly in the terminal:
kasy run --raw # raw output, no spinner
kasy run | tee out.log # any pipe already falls back to raw mode automaticallyWhat kasy reset clears on each platform
| iOS simulator | Physical iPhone | Android (emu/device) | |
|---|---|---|---|
| SharedPreferences and local database | Yes | Yes | Yes |
| Push / ATT / camera permission | Yes | May persist a few minutes | Yes |
| Firebase Auth (Keychain) | No | No | Yes |
iOS Keychain persists by Apple's design, the same way WhatsApp "remembers" you after a reinstall. To test without an account on a physical device: sign out inside the app itself.
How to test "from scratch" on a physical iPhone
| I want to test | What to do |
|---|---|
| Onboarding / login flow | Sign out in the app. A fresh login lands on the initial flow |
| Push permission from scratch | Settings → app → Notifications → turn off |
| ATT permission | Settings → Privacy → Tracking → toggle for the app |
| Face ID | Settings → biometrics → turn the switch off and back on |
Where kasy reset shines: on the iOS simulator and Android emulator, where it wipes everything (including permissions) in seconds.
Last updated on 08/02/2026

