Skip to main content

IPC Transports

By default stdui communicates with the controlling application via stdin/stdout. Two alternative transports are available for cases where subprocess pipes are inconvenient — for example, when the controlling process is not the direct parent of stdui, or when you want to connect to an already-running stdui instance.

TransportCLI flagPlatform
stdin/stdout(default, no flag needed)All
Unix domain socket--socket <path>All (Windows 10 1803+)
Named pipe--pipe <path>All
Platform note — named pipes on Unix

On Unix/macOS, --pipe is an alias for a Unix domain socket. FIFOs cannot carry reliable bidirectional IPC, so stdui creates a Unix domain socket at the given path regardless. On Windows, --pipe uses a real Windows named pipe (CreateNamedPipe).

How it works​

When either flag is passed, stdui creates the socket or pipe itself before entering its main loop. The controlling application connects after the file appears on disk. The socket/pipe file is removed by stdui on shutdown.

App (Go, Python, anything)
│ JSON commands →
│ ← JSON events
▼ (over socket or pipe instead of stdin/stdout)
stdui binary (C++)

The message format and protocol are identical to stdin/stdout — every message is a single line of JSON terminated by a newline.

CLI flags​

--socket <path>​

Starts stdui in Unix domain socket mode. stdui creates and listens on a Unix domain socket at <path>. The controlling application dials that path after the file is visible.

./stdui --socket /tmp/myapp.sock

--pipe <path>​

Starts stdui in named-pipe mode.

  • Unix/macOS: creates a Unix domain socket at <path> (same as --socket).
  • Windows: creates a Windows named pipe at <path> (must be of the form \\.\pipe\<name>).
# Unix / macOS
./stdui --pipe /tmp/myapp.pipe

# Windows
stdui.exe --pipe \\.\pipe\myapp

Go SDK​

The Go SDK provides two convenience functions that spawn stdui with the appropriate flag and connect to it automatically. Both functions retry the connection with exponential back-off for up to 5 seconds while stdui is starting up.

StartWithSocket​

import stdui "github.com/BigJk/stdui/sdk/go"

client, err := stdui.StartWithSocket(
"./build/stdui", // path to stdui binary
"/tmp/myapp.sock", // socket path — created by stdui
stdui.Settings{
Title: "My App",
WindowWidth: stdui.Ptr(800),
WindowHeight: stdui.Ptr(600),
},
)
if err != nil {
log.Fatal(err)
}

StartWithNamedPipe​

client, err := stdui.StartWithNamedPipe(
"./build/stdui", // path to stdui binary
"/tmp/myapp.pipe", // pipe path — created by stdui
stdui.Settings{
Title: "My App",
WindowWidth: stdui.Ptr(800),
WindowHeight: stdui.Ptr(600),
},
)
if err != nil {
log.Fatal(err)
}

On Windows pass a named-pipe path:

client, err := stdui.StartWithNamedPipe(
`C:\path\to\stdui.exe`,
`\\.\pipe\myapp`,
settings,
)

After obtaining the *Client, usage is identical to Start() — register handlers and call client.Wait().

Full example​

A runnable example is in example/ipc/main.go. It accepts -socket and -pipe flags to select the transport at runtime:

# Use Unix domain socket
go run ./example/ipc -socket /tmp/stdui-demo.sock

# Use named pipe (default when no -socket flag is given)
go run ./example/ipc