React Native Runtimes
Threaded runtime

Prewarming

Start a runtime before its UI is visible to remove cold-start latency.

Prewarming creates and starts a named secondary runtime before a surface needs it. The runtime is ready when the first surface mounts, so the user sees no cold-start delay.

import { ThreadedRuntime } from '@react-native-runtimes/core';

await ThreadedRuntime.prewarm('conversation-release-room-runtime');

preload is an alias of prewarm:

await ThreadedRuntime.preload('conversation-release-room-runtime');

ThreadedScreen preloads its runtime by default, but that preload runs from a React effect — meaning the runtime starts at roughly the same time the screen mounts. For low-latency navigation, prewarm earlier, such as while a picker or inbox is visible:

const runtimeNames = conversations.map(
  conversation => `conversation-${conversation.id}-runtime`,
);

useEffect(() => {
  for (const runtimeName of runtimeNames) {
    void ThreadedRuntime.prewarm(runtimeName);
  }
}, [runtimeNames]);

On tap, prewarm the selected runtime again before switching screens. The call is cheap when the runtime already exists, so this is safe to do liberally:

function openConversation(conversationId: string) {
  void ThreadedRuntime.prewarm(`conversation-${conversationId}-runtime`);
  setSelectedConversationId(conversationId);
}

Best-effort + cheap when warm

Calling prewarm on an already-started runtime is essentially free. Treat it as a hint, not an expensive imperative call.

Native prewarm

Prewarm from native code for runtimes that should exist before any JS runs — typically your background runtime or a chat inbox.

ThreadedRuntime.prewarmRuntime(
  applicationContext,
  "conversation-release-room-runtime",
)
ThreadedRuntime.prewarmRuntime("conversation-release-room-runtime")
#include <nativecompose/threadedruntime/ThreadedRuntimeDispatcher.h>

nativecompose::threadedruntime::prewarmRuntime(
  "conversation-release-room-runtime"
);

Releasing runtimes

Destroy a named runtime when it no longer owns useful work:

await ThreadedRuntime.destroy('conversation-release-room-runtime');

For route components, set destroyOnUnmount when the screen should release the runtime immediately:

<ThreadedScreen
  component={ConversationScreen}
  destroyOnUnmount
  props={{ conversationId }}
  runtimeName={`conversation-${conversationId}-runtime`}
/>

Don't destroy app-lifetime runtimes

A background runtime that owns sync, caching, or queues should never be destroyed during normal app use. Only call destroy for runtimes you're sure no one else needs.

Strategy cheat sheet

SituationRecommendation
User likely to open screen X within 5 secondsPrewarm X's runtime from a parent screen's effect
App-lifetime background workPrewarm from native at startup
Per-conversation chatPrewarm a small N (e.g. 3–5 visible inbox items) ahead, prewarm the selected one on tap
Rarely-used heavy featureDon't prewarm — let the surface start the runtime on demand

On this page