Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Coming from AutoHotkey

If you’ve written AutoHotkey, Rebind will feel familiar: you bind keys, send input, react to windows, and loop over time. The differences are that scripts are Luau (a fast, typed Lua) instead of AHK syntax, they run on Windows, macOS, and Linux, and their output can come from real USB hardware instead of a software Send.

How concepts map

AutoHotkeyRebind
Hotkey — F1::Bind("F1", fn) or the OnDown(key) hook
Remap — CapsLock::EscapeBind.Remap("CapsLock", "Escape")
Send / SendInputHID.Type, HID.Press, HID.Down / HID.Up
Hotstring — ::btw::by the waya Bind that calls HID.Type (or a key-sequence watcher)
#HotIf WinActive(...)the window= / process= modeline
Sleep, LoopRun(function() … Sleep(ms) … end) coroutines
PixelGetColorScreen.GetPixelColor
WinActivate, WinGetTitleWindow.Activate, Window.GetTitle
A_ClipboardClipboard.Get / Clipboard.Set
Persistent scriptscripts stay loaded until you stop them

Side by side

A remap and a hotkey that types text:

; AutoHotkey v2
CapsLock::Escape

F1::Send("Hello{Enter}")
--[[
  rebind: min_sdk=3.0.0
  rebind: name=Basics
--]]
Bind.Remap("CapsLock", "Escape")

-- HID.Type / HID.Press sleep between keystrokes, so they must run inside a
-- coroutine. A plain Bind callback runs synchronously, so wrap it with Async().
-- (Type the text, then press Enter explicitly — a literal "\n" is not a key.)
Bind(
  "F1",
  Async(function()
    HID.Type("Hello")
    HID.Press("Enter")
  end)
)

Scope a script to one application:

; AutoHotkey v2
#HotIf WinActive("ahk_exe chrome.exe")
F2::Send("^t")  ; new tab
#HotIf
--[[
  rebind: min_sdk=3.0.0
  rebind: name=Browser Helper
  rebind: process=chrome.exe
--]]
Bind(
  "F2",
  Async(function()
    HID.Press("LCtrl+T") -- new tab
  end)
)

What’s different

  • A required header. Unlike AHK, every Rebind script needs a modeline declaring the Rebind version (min_sdk) before it will run — the relay refuses a script without it. The rest of the header (name, process= targeting) is optional. See Modeline.
  • Sending input yields. HID.Type and HID.Press sleep between keystrokes, and Net.* requests block, so they must run inside a Run() / Async() coroutine — not directly in a plain Bind/OnDown callback.
  • Cross-platform. The same script runs on Windows, macOS, and Linux. AutoHotkey is Windows-only.
  • Hardware output. In hardware mode your HID.* calls leave a Teensy as standard USB HID, with deterministic timing — not a software SendInput. The same script runs free in software mode first; see How it works.
  • A typed language. Luau brings types, coroutines, and a real standard library. Sequences and delays use Run/Sleep instead of SetTimer/Loop.
  • More reach. Beyond remaps and macros, Rebind adds an HTTP and WebSocket server, shared-memory IPC, and remote clients for TypeScript, Python, and Rust — so other programs can drive input directly. See Remote control.

AutoHotkey has a deep Windows GUI and COM surface that Rebind doesn’t replicate — Rebind is about transforming input, not building desktop apps. For everything input-related, the Scripting guide and SDK reference are your next stops.