Skip to main content
The whole SDK runs free in software mode. No hardware is required. To install or update, run the one-line installer in the quickstart. A few namespaces depend on OS-specific APIs; see Platforms & limits for the authoritative per-namespace support matrix.

Globals

Run

Launches a function as a coroutine. Returns immediately. The function executes concurrently with other script code. Returns a TaskHandle with:
  • handle:Cancel(): stop the coroutine
  • handle:IsRunning(): returns boolean
If the coroutine errors, the runtime logs it with a traceback (visible in the Logs tab), stops that coroutine (handle:IsRunning() then returns false), and marks the script’s error state. Other coroutines and hooks keep running. Wrap fallible work in pcall to let a coroutine survive a recoverable error.

Sleep

Pauses the current coroutine for ms milliseconds. Only valid inside a Run() block. Calling Sleep() outside a coroutine raises an error. Does not block anything else.

After

Shorthand for running a function after a delay. Equivalent to Run(function() Sleep(ms) fn() end). Returns a TaskHandle.

Async

Returns a new function that automatically runs fn in a coroutine when called. This lets you use Sleep() and other coroutine features inside callbacks that are normally synchronous (like Bind handlers). When the wrapped function is called from the main thread, it spawns a Run() and returns false (swallow). When called from inside an existing coroutine, it calls fn directly to avoid double-wrapping.

require

Loads a sibling module file relative to the script’s own directory and returns its value (a module is a file that returns something, usually a table). Modules are cached: the file is evaluated once on first require, and later requires of the same path return that same value. Resolution for an extensionless name, in order: <name>.luau, <name>.lua, <name>/init.luau, <name>/init.lua. Dots are path separators (require("lib.math") → lib/math.luau); a leading ./ is stripped; an explicit .lua / .luau suffix pins that exact file. Sandboxed to the script directory: a name containing .., or any candidate that resolves outside the directory, raises path traversal not allowed; an unresolved name raises module '<name>' not found. A name the script directory cannot resolve is looked up once more, by the same rules, in the packages folder of Rebind’s app directory. A name starting with macros/ that neither resolves is looked up in the macros folder of your scripts, where the recorder saves takes, so any script can require("macros/<name>") and get that macro’s actions. There are no registries, package.path, or aliases: local files only. rebind check and publishing resolve inside the package only.
Only a directly-run script needs a min_sdk modeline; a require’d module is loaded through that script, not run directly, so it needs no header. See the scripting guide.

_REBIND

Read-only table injected by the host with metadata about the current script and runtime. Available immediately at load time. version is the installed Rebind SDK version, not the script’s modeline version. platform is the host operating system as "windows", "macos" or "linux", for chords and launchers that differ per OS.

Hooks

Global functions your script defines. The runtime calls them when events occur.

Lifecycle

OnTick fires on a fixed cadence set by the tick_rate modeline (default 1,000/s, max 8,000/s) while the script is active. Its argument dtMs is the real time elapsed since this script’s previous OnTick, in milliseconds. It is fractional (at 8,000/s it’s ~0.125), and 0 on the very first call. Use it for frame-rate- independent work, e.g. pos += velocity * dtMs. Run() coroutines, Timer callbacks, and network I/O are serviced on every engine tick regardless of tick_rate. OnStart runs once per load, before any other hook. For a targeted script that is already focused at load time, OnFocus fires immediately on the same load; an unfocused targeted script gets OnStart only, and its OnFocus/OnTick/timers wait until the target gains focus. Top-level code runs immediately when the script file is loaded, before OnStart is called. Use it for constants, module initialization, and guards that must run before anything else.
OnStart is the right place for anything that needs the script to be fully registered first, such as reading persisted UI values or starting timers.

Input

All input hooks can return false to block the event from reaching the PC, or return true to pass it through. OnMove is the exception: it needs a Rebind device, and its return value counts only with mouse_block=true.
Exclusive capture: because OnDown/OnUp may block any key, defining either one makes Rebind intercept every key system-wide and re-emit the ones your script passes through. Tools that only trust real device input (Keyboard Maestro, Karabiner, some games) will not see re-emitted keys while such a script runs. If you only care about specific keys, use Bind. It intercepts only its declared triggers and leaves everything else untouched. A hook script that never blocks can also declare key_block=false to observe without intercepting.

Observers

Every input event is also delivered to a matching observer hook. Observers fire on all running scripts and their return value is ignored, so they cannot block an event. Use them to watch input without taking exclusive capture.
A script that defines only observers never intercepts anything, so it does not trigger the exclusive-capture behavior described above.

Other (reserved, not yet dispatched)

These hooks are recognized but not dispatched in the current release. Defining them will not cause errors; they won’t fire.

System

Read-only methods updated automatically every tick.

System.TypeText

System.TypeText inserts text the way the OS would from a keyboard, but it never touches the script’s HID output path. In hardware mode HID.Type goes to the Rebind Link and is limited to the characters its layout map knows; System.TypeText still reaches the focused app on the host and carries any Unicode. Use it for snippets, replies and clipboard slots. It raises an error when the OS refuses the injection (macOS without the Accessibility grant, a Windows secure desktop), so wrap it in pcall when you want to report that. Release the chord that triggered it before typing: a modifier still held turns the inserted characters into shortcuts in the receiving app. A Bind release callback plus a short wait on Input.GetModifiers() is the usual shape.

System.Exec

Runs a shell command (cmd.exe /C on Windows, sh -c on macOS/Linux) and returns when it completes. Returns: { exit: number, stdout: string, stderr: string } Options:
  • timeout: max execution time in ms (default: 5000). The process is killed if it exceeds this.
  • cwd: working directory for the command.
Output is capped at 64KB per stream. The console window is suppressed on Windows.
Non-blocking inside Run(): Called from inside Run() or an Async() handler, System.Exec runs the command on a background thread and yields the coroutine. The tick thread never blocks, and the call returns its result table on a later tick. Called outside a coroutine (OnTick, OnDown/OnUp/OnMove, plain Bind callbacks, the top-level chunk), it falls back to synchronous blocking that stalls the tick thread until the command finishes and logs a one-time warning. This sync fallback is deprecated. Wrap System.Exec in Run().
Permission: System.Exec requires the exec permission. It is granted by default, but once the modeline declares any permission= line you must include permission=exec, or the call raises System.Exec() requires 'exec' permission at call time. (System.ExecDetached is gated by the same exec permission. See Permissions.)

System.ExecDetached

Launches cmd as a detached, fire-and-forget process and returns immediately with its PID. Unlike System.Exec, it does not wait for the process or capture its output: stdio is discarded (null). Returns: the spawned process PID as a number. Options:
  • cwd: working directory for the process.
The console window is suppressed on Windows. The process keeps running after the script exits.
System.Exec vs System.ExecDetached:
  • System.Exec: captures stdout/stderr/exit. Non-blocking inside Run() (yields the coroutine); synchronous blocking fallback elsewhere. Use when you need the output.
  • System.ExecDetached: detached, returns instantly with a PID, no output captured. Use to launch apps or background processes.

HID

Sends keyboard and mouse output through the active transport.

Keyboard

Important: HID.Press and HID.Typewriter use Sleep() internally and must be called inside a Run() coroutine or an Async() handler: calling them outside a coroutine (e.g. directly in OnDown or a Bind action) raises an error. HID.Down, HID.Up, and HID.Combo do not sleep. HID.Type needs no coroutine, but hardware typing emits per-character reports and can occupy the calling hook while it does so.

Combos

Combo, Down, Up, and Press all support + for modifier combos:
HID.Combo presses keys left-to-right and immediately releases them right-to-left, in one synchronous call. Use it to fire a shortcut from a Bind action or OnDown. HID.Press does the same but holds for a duration (coroutine only). HID.Down presses left-to-right; HID.Up releases right-to-left. Modifier aliases: in addition to the canonical LCtrl/LShift/LAlt/LWin names, combos accept the shorthands Ctrl, Shift, Alt, Win/Meta/Cmd, and (macOS-friendly) Opt/Option. So "cmd+opt+i" and "LWin+LAlt+I" are equivalent. The + key itself is spelled Equal (unshifted) or KpPlus (numpad), so there is no ambiguity.

Usages

Keys can also be named by USB HID keyboard usage: usage:N, where N is decimal or 0x hex from 0x04 to 0xE7. This reaches keys that have no name. The media codes 0xB5 to 0xB7 and 0xCD are refused, because the software transports treat them as media keys. An invalid usage raises an error before any key is pressed.

Mouse

Joypad

A Rebind Link whose USB profile includes a joypad appears to the computer as a game controller with 32 buttons, an 8-way hat, four axes, and two sliders. state fields: buttons (a list of pressed buttons, 1 to 32), hat (0 for up through 7 clockwise; leave it out for centered), x, y, z, rz (-1 to 1, 0 is center), and slider, dial (0 to 1).
The last state written wins, whichever script wrote it. The relay returns the joypad to neutral when a script stops or errors and when the kill switch fires. On a Link whose profile has no joypad, and in software mode, these calls raise an error. Keyboard and mouse calls raise the same way on a Link whose profile leaves that interface out.

Mouse mode

Relative mode (default): single-pass movement, designed to be fast; may drift. Best for fast cursor movement. Absolute mode: iterative correction with position validation, slower, designed for sub-5px accuracy. Best for desktop automation.

Input

Reads the current physical state of input devices. Input.IsDown / Input.GetDuration accept the same names as the rest of the SDK, including mouse buttons (Mouse1 through Mouse5); an unknown or never-pressed code returns false / 0 rather than erroring.

UI

Defines a settings panel rendered in the Rebind UI.

Schema

Returns a proxy handle. Read values with cfg.key, write with cfg.key = value.

Widgets

Widget options

A Slider with no min/max defaults to a range of 0 to 100. tooltip, group, tab, and showIf apply to every widget, including UI.Color.

Other

Persistence

Values are saved automatically on every change and restored at startup. Persistence is keyed to the script’s file path: no configuration required.

Macro

Record and play back input sequences.

Playback

Speed: 1.0 = normal, 0.5 = half speed, 2.0 = double speed. Default: 1.0. Mode: "parallel" (default), "replace". Handle methods:
  • handle:Stop()
  • handle:Pause()
  • handle:Resume()
  • handle:IsPlaying(): returns boolean
  • handle:GetProgress(): returns 0.0 to 1.0
  • handle:Wait(): blocks the current coroutine until playback ends. Must be called inside Run()

Hardware streaming

Macros containing "type" actions always play host-side. Macro.Play() automatically falls back to host-side execution when any Type action is present.

Recording

Record options: { ignore_mouse = false, ignore_keyboard = false, precision = "normal" } (keys are snake_case, and camelCase is silently ignored)

Format

Actions in a macro table:

Timer

Handle methods: handle:Cancel(), handle:Pause(), handle:Resume()

Math

Random

Transforms

All transform functions return a new table (original is unchanged). Interpolate vs Resample:
  • Resample changes all delays uniformly (normalizing recorded macros)
  • Interpolate adds intermediate steps between existing points (smoothing patterns)

JSON


Hash

Common cryptographic and checksum hashing. All inputs are treated as raw bytes. Hash.HMAC accepts algo of "sha256", "sha512", or "sha1". Any other value raises an error.

Codec

Base64 and hex encoding/decoding. These are encodings, not encryption. They provide no confidentiality.

Log

Globals: print(...) and log(...) are both aliases for Log.Info. They accept multiple arguments, joined by tabs, identical to standard Lua print behaviour.
Logs appear in the Rebind UI Logs tab.

File

All paths are relative to your script’s directory. Path traversal (..) is rejected. File.IsDir and File.IsFile never throw: they return false for missing or out-of-sandbox paths. File.Move uses a rename and may fail across filesystems.

Net

Client

Client calls yield. Wrap them in Run() / Async(). Every HTTP client method below blocks on a background thread and yields the coroutine, so calling one directly in OnDown, top-level code, or any synchronous hook raises Net.X() must be called inside Run(). The snippets below assume they run inside a Run() block or an Async() handler. (The WebSocket calls Net.WSListen / Net.WSConnect are exempt: their I/O runs on dedicated threads. Net.UDPListen is exempt too: it never blocks.)
Response: { status: number, body: string, headers: table } Options: { timeout = milliseconds }: optional trailing table for convenience methods. Net.Request options: { method: string, url: string, body?: string, headers?: table, timeout?: number }
Custom headers (including User-Agent) can be set on any request via the headers table.

HTTP server

Handler: receives request, returns { status?, body?, headers? } (status defaults to 200), or a plain string sent as a 200 body. Request fields: req.method (e.g. "GET", "POST"), req.path (e.g. "/click"), req.body (string), req.headers (table). Server handle: server:Stop() Net.Listen binds 127.0.0.1 (localhost only). It is not reachable from other machines. For a LAN-facing endpoint use Net.WSListen, which binds 0.0.0.0, or Net.UDPListen on a LAN address. Each server answers one request at a time: a request waits for your handler, which runs on the script’s tick loop, before the next is read. A request still unanswered after 30 seconds receives 504, so keep handlers fast. For the same request-in, input-out shape over a persistent connection, see the WebSocket remote in the cookbook.

WebSocket server

Handlers table: all optional. Client handle (passed to handlers): client.id, client:Send(text), client:SendBinary(bytes), client:Close(). Server handle: server:Broadcast(text), server:BroadcastBinary(bytes), server:ClientCount(), server:Stop(). Binary frames arrive as Lua strings (read bytes with string.byte / string.unpack); the is_binary flag distinguishes them from text. The maximum message/frame size is 64 MiB per connection. A larger frame drops the connection. Net.WSListen and Net.WSConnect are exempt from the Run() requirement the HTTP client methods have: their socket I/O runs on dedicated threads. The server binds 0.0.0.0:<port>. Events are dispatched to Lua handlers on the script’s tick loop. Up to 32 events are processed per tick per server, within a 20 ms handler budget shared by every WebSocket server and client; excess messages backlog into the next tick. There is no built-in rate limiting. Scripts exposed to untrusted networks should implement their own. For latency and throughput caveats, see Remote control. Example:

WebSocket client

URL: ws://host:port/path or wss://host:port/path. TLS uses the standard web root certificates. Handlers table: all optional. Connection handle: conn:Send(text), conn:SendBinary(bytes), conn:Close(). Example:

UDP

Handler: function(data, ip, port) receives each datagram’s bytes as a Lua string and the sender’s address. Socket handle: socket.port, socket:SendTo(ip, port, bytes), socket:Stop(). SendTo sends from the bound address, returns false when the send fails or the socket is stopped, and raises an error on an invalid address. Port 0 picks a free port, readable from socket.port. The socket binds the address you give, so "127.0.0.1" stays on this computer and a LAN address is reachable from that network. The call raises an error when the address is invalid or the port is taken. Datagrams are dispatched on the script’s tick loop, up to 32 per tick per socket within a 20 ms handler budget shared with Net.Listen servers; UDP sockets are served first. Datagrams of 2048 bytes or more are dropped. A handler error is logged and the socket keeps running. There is no authentication; check the sender and contents in your handler.
Remote clients are available for TypeScript, Python, and Rust: drive a running script’s HTTP/WebSocket server from any program.

Screen

Pixel color sampling from the screen. See Platforms for supported calls and platform-specific errors. While a script that mentions Screen is loaded, on macOS the relay streams each display into a frame it keeps in memory, so a read never waits on the compositor. On Windows each read is still a GDI call until the equivalent stream lands. GetPixelColor costs about a microsecond. SearchForColor scans the frame at about 0.6 ns per physical pixel: a region up to 200k physical pixels, about 220x220 on a 2x display or 440x440 on a 1x one, answers on the thread that calls it, tick included. A larger region runs on a worker thread and yields inside Run(); outside a coroutine it raises an error naming the limit. Screen.Capture and Screen.FindImage always yield and are refused outside a coroutine. The stream starts when the script loads and stops when it unloads. On macOS it lights the screen recording indicator, as any screen read does. Reads see the display as of the last change the window server published, which is what a screenshot would show at that moment. On macOS, capture handles Retina displays automatically. GetPixelColor/SearchForColor coordinates are in logical (non-retina) pixels; Screen.Capture returns native (physical) pixels and reports the scale via the returned dimensions vs the display’s logical size.

Screen.SearchForColor

  • region: {x1, y1, x2, y2} table of screen coordinates. Negative values address displays left of or above the primary.
  • color: hex string "rrggbb", case-insensitive (matches GetPixelColor output)
  • tolerance: optional, 0.0 to 1.0 (default 0.0 = exact match). Per-channel percentage of 255.
  • Returns {x, y} of first match (top-left to bottom-right scan), or nil if not found. A capture failure is an error, never nil.
  • Regions over 200k physical pixels must be called inside Run().

Screen.List

Returns one entry per connected monitor. Use #Screen.List() for the monitor count. Each entry:

Screen.Capture

Captures a display live and returns a lossless PNG plus the geometry needed to map image pixels back to screen coordinates. This is the primitive behind screenshot-driven automation (see the remote-control protocol’s screen.capture). opts (all optional):
  • display: 1-based index from Screen.List(). Defaults to the display under the cursor.
  • region: {x, y, w, h} in that display’s local coordinates. Defaults to the full display; clamped to the display’s bounds.
  • max_edge: optional. Downscale the returned PNG so its longer side is at most this many pixels, preserving aspect ratio. Omit for native resolution. Use it to keep base64 frames small in screenshot-heavy loops, for example a remote-control server passing max_edge = 1280 so a 4K capture doesn’t overrun the script’s memory limit.
Returns:

Screen.FindImage

Captures a display live, like Screen.Capture, and scans it for a needle image. Inside Run() the capture and scan run on a worker thread and the coroutine yields; outside a coroutine the call raises an error.
  • needle: path to a PNG, relative to the script directory. Pixels with alpha below 128 match anything, so cut a needle with a transparent background to ignore what is behind it.
  • opts (all optional): display and region as in Screen.Capture, plus tolerance, 0.0 to 1.0 (default 0.0 = exact). Per-channel percentage of 255, the same scale as SearchForColor. scales is a list of 1 to 8 ratios, 0.1 to 10, the needle is resampled by before scanning (default { 1 }).
  • Returns {x, y, width, height} of the first match in screen coordinates, or nil. Scales are tried in the order given, and within one scale the scan runs top-left to bottom-right, so list the most likely ratio first.
The needle is compared at native pixel scale. Cut it from a Screen.Capture frame on the display you target and it matches with no options. When the same needle must work on another display, pass scales: a needle cut on a 2x Retina display finds its 1x rendering with scales = { 1, 0.5 }, a 1x needle finds pixel-doubled game UI with scales = { 1, 2 }. Each ratio costs one extra scan. Resampling softens edges, so start at tolerance = 0.1 and raise it until the needle hits, then confirm with Screen.Capture that the hit is the target and not a flat region. Icons and text that the OS renders separately per DPI, such as the macOS Dock or Windows text at 125%, are not resamples of each other and may never match across scales. Windows display scaling is not visible to the runtime, so a Windows needle is always compared at ratio 1 unless you pass scales.

Window

Window manipulation functions. Handles are integer values obtained from Window.Find() or Window.List(). Passing nil for a handle targets the active (foreground) window. See Platforms for implemented calls and unsupported-call errors.
macOS Accessibility: Window.Activate and Window.Move require Rebind to hold the macOS Accessibility grant. Having this grant does not enable unimplemented Window calls. On macOS Window.Move targets the frontmost focused window; the handle is advisory.

Query

Activation

Movement / sizing

State control

Window.Close asks the window to close gracefully (it may prompt to save). Window.Kill force-terminates the process that owns the window. There is no prompt and unsaved work is lost. Window.Kill can take down sibling windows in the same process. Window.SetAlwaysOnTop and Window.SetTransparency are best-effort: some fullscreen/DirectX apps repaint over them.

Waiting

Examples


App

Application-level control: the counterpart to Window (which acts on individual windows). App acts on whole applications: launch, focus, hide, quit, and query running apps. Apps are addressed by name, matched case-insensitively against the application’s display name on macOS and its executable name on Windows. Platform support: macOS and Windows. On macOS, Front, IsFront, IsRunning, and Activate are permission-free; Hide, Quit, and IsHidden drive an AppleEvent and prompt for macOS Automation permission on first use. On Windows, chrome and chrome.exe name the same app and App.Front().name returns the file name (chrome.exe). Activate focuses a visible window of a running app but does not launch one (use System.ExecDetached), Quit closes the app’s windows (an app that minimizes to the tray keeps running), and Hide and IsHidden raise an error. On Linux every call raises an error.
App vs Window: use App when you mean the whole application (“activate Terminal”, “is Slack running”), and Window when you mean a specific window (find/move/resize by handle or title). For app-conditional remaps, prefer a process=-scoped script (Rebind activates/deactivates it as you switch apps) over polling App.Front() on every keypress.

Audio

Audio.Play

Options: File paths are relative to the script directory (same sandboxing rules as File).

SoundHandle

The object returned by Audio.Play: Always call Audio.StopAll() in OnStop and OnBlur to clean up playing sounds.

Clipboard

Read and write the system clipboard. See Platforms for platform support and unsupported-call errors.
Clipboard paste is the most reliable way to input multi-line or long text. Applications handle pasted newlines correctly, and there are no per-character timing concerns.

Process

Query and manage system processes.

Dialog

Native OS dialogs for messages, confirmations, and file selection. All functions must be called inside Run(): they yield the coroutine while the dialog is open. Input processing, timers, and other coroutines continue running uninterrupted.
Linux/BSD: requires Zenity, KDialog, or YAD to be installed.

Message and confirm

Options: { title?: string, level?: string } level controls the icon: "info" (default), "warning" (alias "warn"), or "error". Matching is case-insensitive, and any unrecognized value falls back to "info".

File dialogs

Options: { title?: string, location?: string, filters?: { { name: string, extensions: { string } } } }
  • location: initial directory the dialog opens in.
  • filters: restrict the file types shown. Each entry has a display name and a list of extensions (without leading dot).

Regex

Pattern matching using Rust regex syntax. It is backtracking-free and does not support lookaround or backreferences. Use [[ ]] long strings for patterns to avoid Luau escape interpretation: [[\d+]] instead of "\\d+".

Match result

Regex.Find and Regex.FindAll return tables with:

Replacement syntax

Replacements use $1, $2, etc. for capture group references:

Examples

Note: Luau also has built-in Lua patterns (string.find, string.match, string.gmatch) which use different syntax (%d instead of \d). The Regex namespace uses standard regex syntax and supports features Lua patterns lack: alternation (|), counted repetition ({2,4}), and more.

Config

Read and write TOML configuration files. TOML is a superset of INI for common use cases: simple key = value files work as-is, with support for typed values (booleans, numbers, strings), arrays, and nested tables. File paths are relative to the script directory (same sandboxing rules as File).
For JSON config files, use the File.ReadJSON / File.WriteJSON functions in the File namespace.

Env

Environment variables and known user folders.

Variables

Env.Set mutates the Rebind process-wide environment: the change is visible to Env.Get in every other running script and to any later System.Exec / System.ExecDetached, and persists until Rebind exits. It is not scoped to your script. Prefer File / Config for per-script state.

Known folders

Each returns an absolute path, or nil if the location cannot be determined. Env.Temp is the exception: it always returns a string. These paths point outside the File sandbox. Use them for informational purposes (such as a Dialog.OpenFile start location), not for sandboxed File.* operations.

Pipe

Shared memory IPC for communicating with external processes (Python, Node.js, etc). Windows only. Returns an error on macOS and Linux (POSIX shared memory support planned).

Opening

Creates or opens a shared memory region backed by the OS object Local\Rebind_<name>, the tag an external process opens (so Pipe.Open("vision") maps Local\Rebind_vision). The name must be 1 to 64 characters of ASCII letters, digits, -, or _. The size option (default 65536) is rounded up to the next power of two, then clamped between 1024 and 16 MiB, so pipe.size (and pipe.capacity = size/2 − 12) may exceed what you requested.

Methods

Properties

Wire protocol

The region is split into two fixed channels so both sides can read and write without locking: the script writes to channel A (offset 0) and reads from channel B (offset size / 2). An external peer does the inverse: it writes to channel B and reads from channel A. Each channel is a 12-byte header followed by the payload: A writer lays down the payload, then the length, then the sequence number last (a release barrier); a reader compares the sequence to the one it last saw and only reads when it changed. Each channel is a single slot, last-writer-wins. It is not a queue, so an unread message is overwritten by the next write. Pace writes to the reader’s poll interval. Working Python, Rust, and Node peers are included in the SDK’s examples.

Registry

Read and write the Windows registry. Windows only. Every function raises an error on macOS and Linux. keyPath begins with a hive: HKLM / HKEY_LOCAL_MACHINE, HKCU, HKCR, HKU, or HKCC. Registry.Write accepts a type of REG_SZ, REG_DWORD, REG_QWORD, REG_EXPAND_SZ, REG_MULTI_SZ, or REG_BINARY.

Script

Globals: exit(reason?) and die(reason?) are aliases for Script.Exit.

Bind

Declarative key binding as an alternative to writing OnDown/OnUp handlers.

Blocking

Bind blocks by default. This is the opposite of OnDown/OnUp. Most binds remap or trigger actions where blocking the original key is what you want. To pass the key through, you must explicitly return true. When using Async() with Bind, the wrapper always returns false (block) immediately when it spawns the coroutine. Any return value inside the coroutine body has no effect on propagation. The decision was already made.

Handle

Handle methods: handle:unbind(), handle:disable(), handle:enable(), handle.enabled (read-only).

Routing

Keys claimed by Bind do not reach OnDown/OnUp. If a bind’s when guard returns false, the key falls through to the next bind or to OnDown/OnUp.

Selective interception

Bind triggers are declared data, so Rebind intercepts only those keys at the OS level. Every other key stays outside the bind’s interception path, and device-level tools (Keyboard Maestro, Karabiner) keep working alongside your script. This is the key advantage over an OnDown handler that inspects key itself: defining OnDown forces system-wide interception (see Input hooks). The trigger string is captured when Bind() runs. Bind(cfg.hotkey, …) reads the saved value of a UI.Keybind field at load, but rebinding it later in the config panel takes effect on the next script restart, not live.

Modeline

A modeline at the top of a script sets its configuration. A directly-run script must declare min_sdk: in its modeline, or in its package’s rebind.toml (any script under a package root inherits [package].min_sdk; see Package format). Rebind refuses to run a plaintext script with no declared Rebind version. Every other key is optional and falls back to its default. (require’d modules are loaded through their parent script and are not gated.) Inside a package, rebind.toml overrides the modeline; see Package format. Three comment forms are accepted. The multi-line block is the recommended header. One rebind: line per setting reads cleanly as a script grows, and it is the exact form Rebind suggests on failure:
Values may be unquoted (ending at the next space) or wrapped in " or ' to include spaces and =: name="My Script". Inside a quoted value, escape its quote and backslashes as \" and \\. A string-valued key alone on its own line (as in the block form) takes the rest of the line, so rebind: name=My Script needs no quotes. Repeatable keys may appear on separate lines or together on one line. Unknown keys are ignored. Scripts using regex or exclusion targeting must declare min_sdk=3.4.1 or newer so an older Rebind build refuses them instead of ignoring their scope. Positive window and process rules combine with OR. With no positive rules, the script is active for every focused window. Any matching exclusion deactivates it, even when a positive rule also matches. Exclusion-only configs therefore mean “active everywhere except here.” Regular expressions use Rust regex syntax. Lookaround and backreferences are not supported. Invalid or empty expressions stop the script from loading instead of widening its scope. The former id key is deprecated and ignored. UI state now persists automatically by file path.

Permissions

A script that declares no permission= line holds every permission. The moment any permission= line is present, the script switches to allow-list mode: only the listed permissions are granted, so permission=net alone also denies exec, and vice-versa. To declare that a script needs nothing, give the key an empty value or none:
Both spellings behave identically. permission= and permissions= each accept one value or a comma-separated list, and every line adds to the set, so permissions=net,exec and two singular lines are the same thing. An empty value or none resets to the empty set, so a later “needs nothing” wins over an earlier grant. In a package, permissions = [] in rebind.toml means the same. Omitting the key entirely is the only state that grants everything. There is no difference between permission= and permissions=none: both deny. Only exec and net actually gate anything; any other permission= value grants nothing real but still flips the script into allow-list mode. A denied call fails as a runtime error when it runs (e.g. Net.Get() requires 'net' permission), not as a load-time refusal, so a gated call inside a branch only fails when reached.
Nothing else is gated. File, Registry, Process, Clipboard, Env, Input, HID, and Macro have no permission check: they work the same whether or not the modeline declares permissions. File paths are still confined to the script directory, but that is path resolution, not a permission. Declare the minimum permissions a script needs.

Key reference

Key names are case-insensitive. "F1" and "f1" are identical. Use these strings with HID.Down, HID.Up, HID.Press, Bind, and in OnDown/OnUp hooks.

Transport key support

Named keys are USB HID usages, not characters. The operating system’s active keyboard layout decides which glyph a usage produces. Text handling differs by transport:
  • Software mode gives HID.Type text to the operating-system output backend. Unicode and layout behavior therefore follows that backend.
  • Rebind Link output converts each character to a USB HID usage. On Windows it consults the active keyboard layout when a matching HID usage exists. On macOS and Linux it uses a US-layout map for letters, digits, common punctuation, newline, and tab.
  • Unsupported hardware-mode characters may not type. macOS software mode can fall back to Unicode text for characters without a keycode mapping, but that is not a portable hardware guarantee.
For arbitrary Unicode or long text, use Clipboard.Set plus the platform paste shortcut where Clipboard is supported. Test layout-sensitive scripts on every target layout and transport.

Letters

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Numbers

0 1 2 3 4 5 6 7 8 9

Function keys

F1 through F24. F13-F24 are HID output only (they work with HID.Press but will not appear in OnDown/OnUp hooks).

Mouse buttons

Modifiers

Editing and control

System

Punctuation

These names refer to the physical key, regardless of shift state.

Numpad

Media keys (HID output only)

These can be sent via HID.Press but will not appear in input hooks.