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 the CLI signed in to your account (ramus login, or an API key), local Android platform-tools (adb), and your project's build tools. Trial keys cannot open tunnels.

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:

ramus 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:

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

Run ramus dev status to check progress, recent logs, and tunnel state. Run ramus 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 ramus dev reload for hot reload, or add --full for a restart.
Gradle / ComposeRun ramus 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:

ramus 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 ramus 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, ramus 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: ramus dev stop stops the dev loop but keeps the session. Use ramus session end when the device is no longer needed.

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