Skip to content

Profiles

Profiles are named serial-connection settings: port, baud, framing, and the various per-session toggles. Baudrun stores every profile in a single JSON file, which makes them easy to hand-edit, version- control, or generate programmatically from inventory data.

All profiles live in one file:

  • macOS: ~/Library/Application Support/Baudrun/profiles.json
  • Windows: %APPDATA%\Baudrun\profiles.json
  • Linux: $XDG_CONFIG_HOME/Baudrun/profiles.json (usually ~/.config/Baudrun/profiles.json)

The file is a JSON array. Baudrun loads it once at startup; changes made while the app is running are not picked up until the next launch. Use the app UI for interactive edits, hand-edit only while the app is closed.

[
{
"id": "8c6b3d4f-...",
"name": "Core-SW-01 (Aruba)",
"portName": "/dev/cu.usbserial-AU04CDLV",
"baudRate": 9600,
"dataBits": 8,
"parity": "none",
"stopBits": "1",
"flowControl": "none",
"lineEnding": "cr",
"localEcho": false,
"highlight": true,
"themeId": "",
"dtrOnConnect": "default",
"rtsOnConnect": "default",
"dtrOnDisconnect": "default",
"rtsOnDisconnect": "default",
"hexView": false,
"timestamps": false,
"lineNumbers": false,
"logEnabled": false,
"autoReconnect": true,
"backspaceKey": "del",
"createdAt": "2026-04-17T10:15:22Z",
"updatedAt": "2026-04-17T10:15:22Z"
}
]
FieldTypeRequiredNotes
idstringyes*UUID. Generated automatically when the app creates a profile. Required for the in-app update path. Hand-written profiles can set any unique string.
namestringyesDisplay name shown in the sidebar. Must be non-empty.
portNamestringyesOS device path. macOS /dev/cu.usbserial-..., Linux /dev/ttyUSB0 or /dev/ttyACM0, Windows COM7. Must match what the app enumerates.

* id is only required when round-tripping through the app UI. A hand-added profile with a blank id will be loaded but can’t be updated through the form until it gets one.

FieldTypeRequiredValid valuesDefault
baudRateintyesAny positive integer. Common: 9600, 19200, 38400, 57600, 115200.none
dataBitsintyes5, 6, 7, 88
paritystringyes"none", "odd", "even", "mark", "space""none"
stopBitsstringyes"1", "1.5", "2" (strings, not numbers)"1"
flowControlstringyes"none", "rtscts", "xonxoff""none"

Shorthand “8N1” = dataBits: 8, parity: "none", stopBits: "1". Network gear is overwhelmingly 9600 8N1.

FieldTypeValid valuesDefaultPurpose
lineEndingstring"cr", "lf", "crlf""cr"Byte(s) the Enter key sends. Most network gear wants CR; Linux consoles want LF; legacy/Windows sometimes CRLF.
localEchobooleantrue / falsefalseEcho typed characters locally. Enable when the device doesn’t echo.
highlightbooleantrue / falsetrueRun the line-buffered regex colorizer over incoming text.
enabledHighlightPresetsstring array | nullany subset of pack ids ("baudrun-default", "cisco-ios", "junos", "aruba-cx", "arista-eos", "mikrotik-routeros", "user")nullPer-profile highlight-pack subset. null (or absent) inherits the global enabled list from Settings. An empty array means “no highlighting at all” for this profile even when highlight: true. Only consulted when highlight is true.
backspaceKeystring"del", "bs""del"What the Backspace key sends. DEL (0x7f) matches VT100/xterm; BS (0x08) for some older Cisco/Foundry gear. Wrong setting surfaces as ^H echoed on screen.
hexViewbooleantrue / falsefalseRender incoming bytes as a hex dump (16 per line, ASCII sidebar). Binary protocols, firmware loaders.
timestampsbooleantrue / falsefalsePrefix each line with [HH:MM:SS.mmm].
lineNumbersbooleantrue / falsefalsePrefix each line with a session-local counter. Resets to 1 on every reconnect.
themeIdstringany theme ID or """"Per-profile theme override. Empty = use the global default theme from Settings.

UARTs on the receiving end of a paste are easy to overrun — even modest multi-line blobs can outpace a switch’s input buffer at 9600 baud. Two complementary defences, both on by default.

FieldTypeDefaultPurpose
pasteWarnMultilinebooleantrueShow a confirmation dialog before pasting anything containing a newline. Catches the “I meant to paste one line” copy-paste mistake.
pasteSlowbooleantruePace pasted bytes one at a time with pasteCharDelayMs between each, instead of writing the whole buffer at once.
pasteCharDelayMsint | null10Per-byte delay in milliseconds when pasteSlow is on. 10 ms = 100 bytes/s = effectively 1000 baud — slow enough for any device’s input buffer to drain between bytes. Bump higher (20–50 ms) for known-fragile UARTs, or lower (1–5 ms) when you’ve confirmed the target keeps up. Ignored when pasteSlow is false.

The Send Hex… path doesn’t use the slow-paste throttle — hex sends write the whole parsed byte vector through in one go, paced only by what the UART itself can absorb. If your target can’t keep up with that, paste the equivalent bytes from the keyboard buffer instead so they go through pasteSlow / pasteCharDelayMs.

Four policies for when the app asserts/deasserts the DTR and RTS lines on connect/disconnect. All four accept the same enum:

ValueMeaning
"default"Leave the line in the OS default state (both asserted on Unix; RTS asserted on Windows).
""Same as "default". Treated as unset.
"assert"Force the line high at the bookend.
"deassert"Force the line low at the bookend.
FieldApplies at
dtrOnConnectPort open
rtsOnConnectPort open
dtrOnDisconnectPort close
rtsOnDisconnectPort close

Common uses:

  • RS-485 direction. Some adapters use RTS to toggle TX/RX; pin it.
  • Arduino DTR reset. Deassert DTR on connect to avoid auto-reset on port open.
  • Device state gating. Some firmwares require a specific DTR state to accept input.

Live DTR/RTS toggle pills in the session header let you flip the lines mid-session regardless of the connect-time policy.

FieldTypeDefaultPurpose
logEnabledbooleanfalseRecord raw incoming bytes to a timestamped file. Directory configured in Settings → Advanced (defaults to <support>/logs/).
autoReconnectbooleantrueOn disconnect (port disappeared), poll for the port to reappear (1s interval, 30s timeout) and reopen with the same config. Preserves the scrollback backlog across the gap.
FieldTypeNotes
createdAtRFC3339 stringManaged by the app. Preserved on update. Don’t touch in hand-edits unless you’re forging history.
updatedAtRFC3339 stringManaged by the app. Bumped on every UI edit.

For a complete reference with every field set to a representative value, see docs-next/public/examples/profile.example.json. The task-focused snippets below omit fields they don’t need to make their point — the app fills defaults from the table above for anything missing.

Standard network switch (Cisco, Aruba, etc.)

Section titled “Standard network switch (Cisco, Aruba, etc.)”
{
"name": "Edge-SW-02",
"portName": "/dev/cu.usbserial-AU04CDLV",
"baudRate": 9600,
"dataBits": 8,
"parity": "none",
"stopBits": "1",
"flowControl": "none",
"lineEnding": "cr",
"highlight": true,
"backspaceKey": "del"
}

USB-C consoles (RuggedCom RST2228, newer Cisco, HPE/Aruba) are CDC-ACM, so the port name looks different (cu.usbmodem... on macOS). Otherwise the same:

{
"name": "RST2228-Plant-A",
"portName": "/dev/cu.usbmodem00000000001A1",
"baudRate": 57600,
"dataBits": 8,
"parity": "none",
"stopBits": "1",
"flowControl": "none",
"lineEnding": "crlf"
}

Deassert DTR on connect so the port open doesn’t reset the board:

{
"name": "Uno-Prototype",
"portName": "/dev/cu.usbmodem14201",
"baudRate": 115200,
"dataBits": 8,
"parity": "none",
"stopBits": "1",
"flowControl": "none",
"lineEnding": "lf",
"localEcho": true,
"dtrOnConnect": "deassert",
"autoReconnect": true
}

Hex view for binary protocol inspection, RTS/CTS for half-duplex adapters, auto-reconnect for flaky USB, slow-paste tuned wider than default since small embedded targets often need it:

{
"name": "Modbus-PLC",
"portName": "/dev/cu.usbserial-0001",
"baudRate": 19200,
"dataBits": 8,
"parity": "even",
"stopBits": "1",
"flowControl": "rtscts",
"lineEnding": "cr",
"hexView": true,
"timestamps": true,
"autoReconnect": true,
"pasteSlow": true,
"pasteCharDelayMs": 25
}

Because the file is a plain JSON array, generating many profiles at once is a scripting job. Two common approaches:

Given switches.csv with columns name,port,baud:

Terminal window
tail -n +2 switches.csv | \
jq -Rs 'split("\n") | map(select(length > 0)) |
map(split(",")) |
map({
name: .[0],
portName: .[1],
baudRate: (.[2] | tonumber),
dataBits: 8,
parity: "none",
stopBits: "1",
flowControl: "none",
lineEnding: "cr",
highlight: true,
backspaceKey: "del",
dtrOnConnect: "default",
rtsOnConnect: "default",
dtrOnDisconnect: "default",
rtsOnDisconnect: "default"
})' > profiles.json
import json, uuid
from datetime import datetime, timezone
inventory = [
("Core-01", "/dev/cu.usbserial-A1", 9600),
("Core-02", "/dev/cu.usbserial-A2", 9600),
("Edge-01", "/dev/cu.usbserial-B1", 115200),
]
now = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
profiles = [
{
"id": str(uuid.uuid4()),
"name": name,
"portName": port,
"baudRate": baud,
"dataBits": 8,
"parity": "none",
"stopBits": "1",
"flowControl": "none",
"lineEnding": "cr",
"localEcho": False,
"highlight": True,
"backspaceKey": "del",
"dtrOnConnect": "default",
"rtsOnConnect": "default",
"dtrOnDisconnect": "default",
"rtsOnDisconnect": "default",
"hexView": False,
"timestamps": False,
"lineNumbers": False,
"logEnabled": False,
"autoReconnect": True,
"pasteWarnMultiline": True,
"pasteSlow": True,
"pasteCharDelayMs": 10,
"enabledHighlightPresets": None,
"createdAt": now,
"updatedAt": now,
}
for name, port, baud in inventory
]
with open("profiles.json", "w") as f:
json.dump(profiles, f, indent=2)

Close the app, drop profiles.json into the config dir, relaunch.

  • Quit Baudrun first. The app reads once at startup and rewrites the whole file on every save. Hand-edits during a running session will be clobbered on the next UI edit.
  • Validation is strict. The app refuses to load a profile whose baud rate ≤ 0, data bits outside 5-8, or parity/stopBits/flowControl/ lineEnding outside the enum. Fix typos before relaunching.
  • IDs must be unique within the file. Duplicates cause ambiguity on update and may get deduped unpredictably.
  • Don’t bump createdAt. Not dangerous, but future sorting features might rely on it.

A natural workflow for shared environments: keep profiles.json in a private git repo, symlink it into <support>/profiles.json on each workstation. Hand-edits become commits; diffs show who changed what when.

The file has no secrets (passwords aren’t stored, since this is a serial terminal, not SSH), so a shared team repo works without additional encryption.

There’s no per-profile file format today. Workarounds:

  • Copy a single object out of the JSON array and paste into a gist / email. Recipient merges it into their own profiles.json.
  • Keep a shared JSON snippets file alongside profiles.json and import by hand.

A profiles export/import UI is a candidate feature if this becomes a real workflow. File an issue with the use case.