---
title: useMagicKeys
description: "Reactive key-press state — access any key as a `ReadonlyObservable<boolean>` that is `true` while the key is held down."
category: Sensors
sidebar:
  order: 1
type-declarations:
  file: ./core.ts
  comments: true
---

## Demo

## Usage

<CodeTabs>
  <Fragment slot="hook">
    ```tsx twoslash
    // @noErrors
    import { useMagicKeys } from "@usels/web";

    function KeyboardDemo() {
      const keys = useMagicKeys();

      return (
        <div>
          {/* Single key — true while held */}
          <p>A: {keys["a"].get() ? "pressed" : "released"}</p>
          {/* Modifier keys (aliases: ctrl, cmd, alt, esc, etc.) */}
          <p>Ctrl: {keys["ctrl"].get() ? "pressed" : "released"}</p>
          {/* Combo — true only when all parts are pressed simultaneously */}
          <p>Ctrl+S: {keys["ctrl+s"].get() ? "pressed" : "released"}</p>
          {/* Current pressed keys set */}
          <p>Pressed: {[...keys.current$.get()].join(", ")}</p>
        </div>
      );
    }
    ```

  </Fragment>
  <Fragment slot="scope">
    ```tsx
    import { createMagicKeys } from "@usels/web";

    function KeyboardDemo() {
      "use scope"
      const keys = createMagicKeys();

      return (
        <div>
          <p>A: {keys["a"].get() ? "pressed" : "released"}</p>
          <p>Ctrl: {keys["ctrl"].get() ? "pressed" : "released"}</p>
          <p>Ctrl+S: {keys["ctrl+s"].get() ? "pressed" : "released"}</p>
          <p>Pressed: {[...keys.current$.get()].join(", ")}</p>
        </div>
      );
    }
    ```

  </Fragment>
</CodeTabs>

### Destructuring with `$` suffix

Since JavaScript destructuring cannot use `+` or bracket notation, append `$` to key names and use `_` instead of `+` for combos:

```tsx
// @noErrors
import { useMagicKeys } from "@usels/web";

function DestructuredDemo() {
  const { shift$, space$, Ctrl_S$ } = useMagicKeys();

  return (
    <div>
      <p>Shift: {shift$.get() ? "pressed" : "released"}</p>
      <p>Ctrl+S: {Ctrl_S$.get() ? "pressed" : "released"}</p>
    </div>
  );
}
```

## Built-in Aliases

| Alias     | Resolves to  |
| --------- | ------------ |
| `ctrl`    | `control`    |
| `cmd`     | `meta`       |
| `command` | `meta`       |
| `option`  | `alt`        |
| `esc`     | `escape`     |
| `del`     | `delete`     |
| `space`   | ` ` (space)  |
| `up`      | `arrowup`    |
| `down`    | `arrowdown`  |
| `left`    | `arrowleft`  |
| `right`   | `arrowright` |

Key names are lowercased and resolved through the alias map. Combo keys are specified with `+` separator (e.g., `"ctrl+a"`, `"shift+enter"`).

For destructuring, append `$` to any key name (e.g., `shift$`) and use `_` instead of `+` for combos (e.g., `Ctrl_A$`). The `$` suffix is stripped and `_` is converted to `+` internally.
