> ## Documentation Index
> Fetch the complete documentation index at: https://docs.endstate.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Readers and environments

> Supported reader hardware, the environment matrix, connecting once rather than every mount, and the package's export map.

## Supported readers

`pickReader()` picks the best supported driver for the current browser:

| Environment              | Reader                             | Notes                                                                                                |
| ------------------------ | ---------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Chrome / Edge on desktop | TapTrack Tappy over **Web Serial** | Preferred transport - works on Windows, macOS, and Linux with stock drivers                          |
| Chrome / Edge on desktop | TapTrack Tappy over WebUSB         | Automatic fallback; not available on Windows (the OS serial driver owns the device)                  |
| Android Chrome           | Phone NFC (Web NFC)                | No extra hardware; requires HTTPS and a user gesture                                                 |
| iOS                      | -                                  | iOS has no Web NFC; the OS opens the tap URL directly - see [tap redirects](/concepts/tap-redirects) |

`connect()` and `start()` may show a browser device or permission prompt, so
call them from a click handler.

## Connecting once, not every time

The browser remembers which reader an origin may use, so choosing a device is
a one-time authorization rather than part of connecting. The SDK splits the
two:

| Call                         | Prompts?                    | Use it for                                                                                     |
| ---------------------------- | --------------------------- | ---------------------------------------------------------------------------------------------- |
| `connect({ prompt: false })` | Never                       | Reconnecting on page load, remount, or SPA navigation. No user gesture needed.                 |
| `requestDevice()`            | Always                      | Pairing a reader the first time, or switching to a different one. Must run in a click handler. |
| `connect()`                  | Only when nothing is paired | The general-purpose call: silent when it can be, chooser when it must be.                      |

`stopScanning()` stops delivering taps and leaves the device connected, so
the next scan starts without a prompt - use it for component teardown between
scans. `disconnect()` is the explicit release, for when another tab or a
desktop application needs the reader. `stop()` keeps its original "stop and
release" meaning and is a deprecated alias for `disconnect()`.

Render the pairing control from the connection state, not from a guess:

```ts theme={null}
type NfcConnectionState =
  | "disconnected"
  | "authorization-required" // no reader paired: show "Connect reader"
  | "connecting"
  | "connected"
  | "error";

reader.onConnectionStateChange?.((state) => render(state));
```

Only `authorization-required` is cleared by a user gesture, so a button gated
on that state stays hidden once a reader is paired, and a reader unplugged and
plugged back in reconnects on its own. Both hold while the browser keeps the
grant. When it does not, the state returns to `authorization-required` and the
button comes back - see
[Troubleshooting](/sdks/reader/troubleshooting#the-device-picker-opens-every-time).

## Package exports

| Subpath                      | Contents                                  | Runs where      |
| ---------------------------- | ----------------------------------------- | --------------- |
| `@endstate-sdk/reader`       | Readers, `pickReader()`, chip URL parsing | Browser         |
| `@endstate-sdk/reader/react` | `useNfcReader` hook                       | Browser + React |
| `@endstate-sdk/reader/ndef`  | NDEF URI parsing                          | Anywhere (pure) |
| `@endstate-sdk/reader/tcmp`  | TapTrack TCMP protocol helpers            | Anywhere (pure) |
