# rpc Call a public `@rpc` method exposed by another runtime. Returns a Future that resolves to the method's return value when the target finishes. Works from any runtime — in-panel apps, headless child runtimes (e.g. the shell's REPL), cluster workers, or standalone scripts. `rpc` is a runtime-level peer of `pub/*`: available in every host, not just the TUI. ## Syntax
[rpc runtime-name method-name arg1 arg2 ...]
## Returns `future` — a pending `ObjFuture` that the caller can `[await]` to get the method's return value, or ignore for fire-and-forget invocation. ## Identity The target is addressed by runtime name — the `id` the runtime was created with. In the TUI, each app panel's runtime is named after its app (the auto-numbered app name, which is also the panel tag), so the same string you would pass to `tui/find-panel` is the RPC target:
[rpc "editor" "cmd-open-file" $path]
[rpc "diff"  "load-diff" $left $right]
For ad-hoc runtimes, the name is whatever was passed to `runtime/spawn` or `createChild`. Runtime names are unique across live runtimes. ## Usage The target runtime must have declared the method with `@rpc`:
def get-marked {||
    @rpc true
    @doc "Return the currently marked items."
    [deref $state~marked]
}
Inside an `@async` function or coroutine:
def load {||
    @async 
    set marked [await [rpc "files" "get-marked"]]
    echo "got:" $marked
}
For fire-and-forget calls (no return value needed), drop the future:
[rpc "editor" "cmd-open-file" $path]
The shell's REPL supports `await` directly at the prompt: ``` repl:user> await [rpc "files" "get-marked"] @{...} ```` ## Errors If the target runtime is unknown, the method is not registered, the target queue is full, or the target eval throws — the future is rejected with a string error message. Use `[try { ... } catch e { ... }]` around `await`:
try {
    set result [await [rpc "files" "get-marked"]]
} catch e {
    echo "call failed:" $e
}
## How it works - Arguments are stringified and re-emitted as a deft-level call (`[method-name arg1 arg2 ...]`) on the target's VM. Only data values (strings, numbers, bools, nil, keywords) survive the crossing — closures and opaque references don't. - The return value round-trips through `deft/stringify` → `deft/parse`, so structured data (vectors, maps, keywords, tagged maps) is preserved on the caller side. - The response Future is allocated on the caller's runtime heap and resolved by the caller's own event-loop tick. The routing uses a `Runtime`-level pending-call table that works for AppThread-hosted apps, loop-driven children, and standalone runtimes alike. - The registry is keyed by runtime name + method name; dispatch goes to the owning runtime's driver thread. - See rpc/methods to list registered methods.