Platform

Nodes & @Rewire

Nodes are pre-registered Swift or Kotlin functions that PipeKit can execute remotely in production. They are the atomic units of runtime control.

What is a Node?

A node is a function annotated with @Rewire that registers itself with PipeKit at app launch. Once registered, the node can be triggered remotely — individually or as part of a flow — without shipping an update.

Nodes are deterministic by design. Only functions declared at build time can execute. There is no arbitrary code injection, no eval, no dynamic payloads that run as code. This is what makes PipeKit safe for production.

Registering a Node

Use the @Rewire macro to register a function as a remotely executable node.

CacheNode.swift
import PipeKit
@FlowEntry
class CacheNode {
@Rewire("clear-cache")
static func clearCache() async throws -> [String: Any] {
let freed = await CacheManager.shared.purge()
return ["freed": "\(freed)MB"]
}
}

Nodes with Parameters

Nodes can accept typed parameters. These are passed from the flow definition or provided at execution time via the dashboard or API.

FeatureToggle.swift
import PipeKit
@FlowEntry
class FeatureToggle {
@Rewire("toggle-feature")
static func toggleFeature(name: String, enabled: Bool) async throws -> [String: Any] {
FeatureFlags.set(name, enabled)
return ["feature": name, "enabled": "\(enabled)"]
}
@Rewire("set-log-level")
static func setLogLevel(level: String) async throws -> [String: Any] {
guard let logLevel = AppLogLevel(rawValue: level) else {
throw NSError(domain: "app", code: 1,
userInfo: [NSLocalizedDescriptionKey: "Invalid log level: \(level)"])
}
Logger.shared.level = logLevel
return ["level": level]
}
}

Node Results & Failure

A node simply returns a value — a dictionary ([String: Any] /Map<String, Any>), a Bool,Double,String, etc. That return value becomes the node's output: it's recorded in the execution log and auto-wired into the next node's matching inputs. To fail a node, throw.

return valueNode completed. The returned value is stored as the node output and passed downstream.
throw errorNode failed. The error is recorded; the flow can be configured to halt or continue. (iOS funcs are async throws; Android funcs are suspend and throw normally.)

Node Catalog

When a device connects to PipeKit, the SDK reports all registered nodes to the server. These appear in the Nodes section of the dashboard, where you can see each node's identifier, parameter schema, and which devices have it registered.

Nodes are scoped to your app's bundle ID. Different apps maintain independent node catalogs.

Best Practices

Use descriptive identifiers

Node IDs like "clear-cache" or "toggle-feature" are easier to compose into flows than "action1" or "fn_23".

Keep nodes focused

Each node should do one thing. Compose complex behavior by chaining nodes in a flow.

Handle errors gracefully

Return .failure with a clear message rather than letting exceptions propagate.

Avoid side effects on registration

The @Rewire macro registers the function — it should not execute any logic at registration time.

Next: Flows & Execution

Learn how to compose nodes into remotely executable workflows.