Editor mode¶
Editor mode is what lets you drag your app's real views around and have the movement
recorded as keyframes. It is a different code path in the runtime, switched on by the
dev flag on the container.
What changes when dev is true¶
dev: false |
dev: true |
|
|---|---|---|
| Animations come from | animation.inertia, loaded by the container |
the editor, over a WebSocket |
| Tagged views | animate | animate, and are selectable and draggable |
| Playback clock | runs in the app | still runs in the app; the editor pauses, scrubs and resumes it by message, and mirrors its position on the playhead |
| WebSocket client | never started | dialing the editor |
Because the container never touches its animation file in editor mode, you can start authoring before you have one at all.
Editor mode requires the container id animation
The editor addresses every schema it sends to the container id "animation", and each
runtime drops schemas meant for a different container. A container with any other id
connects and shows its hierarchy but never receives an animation.
Ports¶
The editor hosts; the app dials in. Each runtime has its own port, so all three can be open at once:
| Runtime | Editor target | Port | The app dials |
|---|---|---|---|
| SwiftUI | iOS | 8060 | ws://127.0.0.1:8060 |
| Compose | Android | 8070 | ws://127.0.0.1:8070 |
| React | Web | 8080 | ws://127.0.0.1:8080 |
Because the app dials in and retries, order does not matter: open the editor first and the app attaches when it launches, or launch the app and it picks the editor up once the editor is listening.
Turning it on¶
Do not ship dev: true. Gate it on a compile-time flag so release builds cannot
accidentally include the editor path:
struct AppEnvironment {
#if INERTIA_EDITOR
static let isInertiaEditor = true
#else
static let isInertiaEditor = false
#endif
}
InertiaContainer(dev: AppEnvironment.isInertiaEditor, id: "animation", hierarchyId: "animation") {
ContentView()
}
Add -D INERTIA_EDITOR to Other Swift Flags for a dedicated scheme or build
configuration. The example app in the repository uses a separate target for this, which
also works and keeps the flag out of your main target entirely.
The dev flag gates the WebSocket client itself: with dev: false the runtime never
dials port 8060, so a shipped build never reaches for an editor.
InertiaContainer(
dev = true,
id = "animation",
hierarchyId = "animation",
baseURL = "ws://127.0.0.1:8070"
) {
DemoApp()
}
dev gates the socket here too: with dev = false the container never dials the
editor and reads assets/animation.inertia instead, so it is safe to leave in a release
build.
baseURL is passed through as given. From an emulator, 127.0.0.1 reaches the editor
because the editor opens an adb reverse tunnel for port 8070 when it attaches — see
below. From a physical device, point it at your Mac's address on the local network
instead.
const isDev = process.env.REACT_APP_INERTIA_DEV !== "false";
<InertiaContainer id="animation" baseURL={baseURL} dev={isDev}>
<DemoContent />
</InertiaContainer>
With dev false the container never opens a socket, so a production bundle does not
reach for an editor.
Note that baseURL is not the editor's address. The editor connection is always
ws://127.0.0.1:8080; baseURL is only where <id>.inertia is fetched from when dev
is false.
Connecting¶
- Boot an iOS Simulator, or let the editor pick a booted one.
- Open the Inertia editor, open (or create) a project, and select iOS in the framework picker.
- Build your app with the
INERTIA_EDITORflag and install it on that simulator — from Xcode, or through the editor's Install and launch panel. - Launch the app.
The simulator shares the Mac's network stack, so 127.0.0.1 reaches the editor with
no address to discover.
- Start an Android emulator — from Android Studio's Device Manager, or
emulator -avd <name>. The editor never boots one for you. - Open the Inertia editor, open (or create) a project, and select Android in the framework picker.
- Install and launch your app on that emulator, from Android Studio or
adb install -r app-debug.apk.
The editor needs adb on its PATH or an ANDROID_HOME pointing at the SDK; it also
checks ~/Library/Android/sdk/platform-tools and the Homebrew prefixes. With a device
attached it does two things:
- Opens a reverse tunnel,
adb reverse tcp:8070 tcp:8070, so127.0.0.1:8070inside the emulator is the editor's listener on your Mac. Without it,127.0.0.1is the emulator itself. - Pushes scrcpy's server onto the device and streams hardware-encoded H.264 back, which is what the viewport shows.
The viewport toolbar has Back, Home and Recents buttons, since an emulator has no window chrome inside the editor.
- Start your dev server —
npm start, which Create React App serves on port 3000. - Open the Inertia editor, open (or create) a project, and select Web in the framework picker.
- Put your app's URL in the address bar above the viewport. It defaults to
http://localhost:3000.
The editor loads that URL in a web view, so your page and the editor are on the same
machine and ws://127.0.0.1:8080 reaches the listener directly. There is nothing to
install and nothing to tunnel — reload the page and the runtime redials.
Once attached, the app sends its Inertia-tagged view hierarchy, the editor's hierarchy panel fills in, and you are connected. Selecting a view in the viewport highlights it in the editor and the other way around.
If the hierarchy panel stays empty, see Troubleshooting.
The authoring loop¶
Once connected, the cycle is short and is the same on every runtime:
- Select a tagged view in the viewport.
- Move the playhead to where you want a pose.
- Turn on recording and drag the view.
- Play the timeline back with Space.
That is the subject of Timeline and keyframes.
Getting the animation into your app¶
The editor writes to its project directory, not into your app's source tree. When you are happy with the animation, take the file across:
cp ~/InertiaStorage/MyProject.inertia/animations/animation.inertia \
path/to/MyApp/animation.inertia
Then build without the INERTIA_EDITOR flag. The container now loads that file from
the bundle and plays it with no editor involved.
There is no path for this yet. The Compose container has no loader of its own, so the animation only ever exists on the wire — an Android build with no editor attached shows every tagged view at its initial pose.
Until that changes, treat the Compose runtime as an authoring target: use it to record an animation against a real Android app, and ship the result through a runtime that can load it.
Nothing to copy, as long as the animations directory is being served:
Then run with dev false and baseURL pointing at that server. For a real deploy,
copy animation.inertia into your app's static assets and point baseURL at wherever
they are served from.
Projects covers the project layout.