Skip to main content
Every recipe below runs unchanged in software mode; add a Rebind Link for hardware output. The building blocks are small and the same throughout:
  • Bind.Remap(from, to): a declarative one-line key-to-key remap.
  • OnDown(key) / OnUp(key): return true to let a key pass through, false to swallow it. Send your replacement with HID.Down / HID.Up / HID.Press.
  • Input.IsDown(key): test whether a physical key is currently held, which is how you build chords, modifier holds, and layers.
Press Left Ctrl + Left Alt + K at any time to stop every running script. (The kill switch uses the left-hand modifiers specifically. Right Ctrl / right Alt don’t trigger it.)

Single-key remap

Bind.Remap takes the key you press and the key you want sent in its place: no hooks, no state. Caps Lock becomes Escape; your real Escape is untouched.
Bind.Remap returns a handle, so you can toggle a remap at runtime with :disable() and :enable(). Here a hotkey flips it live, and the handle reports its state through .enabled.
For conditions more nuanced than on/off, such as “only in this app” or “only while another key is held,” drop down to OnDown / OnUp and decide per event. The remaining recipes all use that form.

Chords and combos

A chord fires one action only when several keys are held together. Printable keys need to be deferred: if the first key passes through immediately, it has already typed before the second key completes the chord. This example holds J and K until release, emits Escape when both are down, and emits a single key on release when no chord formed.
The tradeoff is that a lone J or K appears on release rather than press, and normal hold-to-repeat is suppressed. For a combo that includes a real modifier, test it with Input.IsDown("LCtrl") and emit a keyboard combo with the + syntax:

Modifier hold

A modifier hold gives one key two jobs: tap it for its normal value, hold it to change what other keys do. Track when the key went down and whether another key was used while it was held. On release, if nothing else fired and the hold was short, send the tap.
usedAsMod prevents a stray Space when you genuinely used the hold, and TAP_MS keeps a long, lone hold from emitting a late Space.

Hold-to-access layer

A layer is a modifier hold scaled up: hold one key to expose an alternate set of keys, release it to return to normal. Keep the mappings in a table so adding a key is a one-line edit.
Because the layer is gated on Input.IsDown(layerKey), every other key behaves normally the instant you let go. To make it app-aware (active only in one program), wrap the body in a System.Window() check:

Opposing-key resolution (last pressed wins)

For movement keys mapped to opposite directions, such as left and right or up and down, holding both at once is ambiguous: the two presses cancel and you stop. One way to resolve it deterministically: when two opposing directions are held at once, the most recently pressed one is active. Release the newer key and the older one, still held, takes over again. Record the order in which each key of an opposing pair went down, then send only the winner and suppress its opposite.
The behavior is timing-driven: pressedAt stores when each key last went down, activeOf picks the larger timestamp, and refresh makes the live output match. Releasing the newer key calls refresh on the survivor so the older direction resumes with no extra tap. OnStop releases both outputs when the script stops. See Platforms for the full capability matrix.