Skip to content

Local development

Edit code on your machine and run it on a Ramus emulator. The CLI connects the remote device to your local Android tools over an adb tunnel.

You need an API key from a signed-in account, local Android platform-tools (adb), and your project's build tools. Trial keys cannot open tunnels. To set up a key, see Agents and CLI.

Your machineSource + SDKs
Build + dev server
RamusAndroid emulator
Connected through adb
See the app through its browser link
Local tools, remote device. Your source, SDKs, build process, and development server stay on your machine. An adb tunnel connects them to the Ramus emulator, and a browser link lets you watch and control the app.

Start the dev loop

From your app directory:

npx ramus-cli dev

Ramus detects Expo, React Native, Flutter, or Gradle, starts a session or reuses one, and runs the framework's development process. The first build runs locally and can take a while.

In a monorepo, or when detection is ambiguous, name the app directory and framework:

npx ramus-cli dev --app-dir apps/mobile --shape expo

Run npx ramus-cli dev status to check progress, recent logs, and tunnel state. Run npx ramus-cli session share to get a browser link to the device.

Apply changes

FrameworkAfter an edit
Expo / React NativeFast Refresh applies supported changes through Metro. Native changes require a rebuild.
FlutterRun npx ramus-cli dev reload for hot reload, or add --full for a restart.
Gradle / ComposeRun npx ramus-cli dev reload to reinstall and relaunch the app.

Keep your project's usual SDK and dependency setup. Ramus supplies the emulator; the dev loop still builds with your local toolchain.

Use adb directly

For Android Studio or your own scripts, start a session and open the tunnel:

npx ramus-cli adb

The response includes a device serial such as 127.0.0.1:53124. Pass the serial you actually get to adb -s <serial> to target this emulator, especially when other devices are connected. From there you can install an APK, read logcat, or use adb reverse so the app can reach a local development server.

To run your own framework commands, keep this tunnel open and export the returned serial in your terminal:

export ANDROID_SERIAL=127.0.0.1:53124 # replace with the serial returned above
adb -s "$ANDROID_SERIAL" reverse tcp:8081 tcp:8081

Reverse port forwarding lets the app reach a local Metro server. Forward any other server ports the same way, one per port. Then use your normal tools:

ToolTarget the remote device
Flutterflutter run -d "$ANDROID_SERIAL"; press r for hot reload or R for restart.
Android StudioSelect the returned serial in the device picker and use Run or Apply Changes.
GradleRun your module's install task, such as ./gradlew installDebug, then launch your application.
Existing APKRun adb -s "$ANDROID_SERIAL" install -r app-debug.apk, then npx ramus-cli app launch --package your.application.id.

The tunnel stays open after an install command finishes. In this workflow, your framework owns its build output and reload controls. Switch back to the ramus dev commands above whenever you want Ramus to manage the dev loop.

Don't run adb root, adb unroot, adb reboot, or adb reverse --remove-all on the tunneled device. They can break the connection or end the session. After you reinstall an app, npx ramus-cli app launch brings it back to the foreground.

Stop or troubleshoot

  • Build still running: check dev status and its log output before you start another build.
  • Wrong directory or framework: pass --app-dir and --shape explicitly.
  • App installs but does not open: package detection may have failed. Pass --package <applicationId> to dev.
  • Finished developing: npx ramus-cli dev stop stops the dev loop but keeps the session. Use npx ramus-cli session end when the device is no longer needed.

Close a tunnel you opened with npx ramus-cli adb by running npx ramus-cli adb --close. Sessions expire after 10 minutes without input, including while an adb tunnel is open.