> ## Documentation Index
> Fetch the complete documentation index at: https://react-native-nfc-kit.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Bare React Native

> Installing without the Expo SDK, and writing by hand what prebuild would have written.

<Info>
  This library is built on the Expo Modules API, which does **not** require the Expo SDK. It
  requires the `expo` package, which ships the module and autolinking infrastructure and little
  else.
</Info>

Bare React Native is a supported route, not a footnote. The only thing you give up
is the config plugin, because there is no `prebuild` to run it — so the plist keys
and manifest XML are yours to write, and every [setup page](/setup/overview) gives
you exactly what to write.

## Install

<CodeGroup>
  ```bash Automatic theme={null}
  npx install-expo-modules@latest
  npm install react-native-nfc-kit
  npx pod-install
  ```

  ```bash By hand theme={null}
  npm install expo react-native-nfc-kit
  npx pod-install
  ```
</CodeGroup>

`install-expo-modules` adds the `expo` package, switches the Babel config to
`babel-preset-expo`, and extends `metro.config.js` from `expo/metro-config`. Doing
it by hand means writing those three things yourself:

```js babel.config.js theme={null}
module.exports = { presets: ['babel-preset-expo'] };
```

```js metro.config.js theme={null}
const { getDefaultConfig } = require('expo/metro-config');
module.exports = getDefaultConfig(__dirname);
```

```ruby ios/Podfile theme={null}
platform :ios, '16.4'
```

Then `npx pod-install`.

## Requirements

| Axis         | Minimum  | Why                                                         |
| ------------ | -------- | ----------------------------------------------------------- |
| React Native | 0.86     | New Architecture only; the legacy one is gone from Expo 55+ |
| iOS          | 16.4     | The Expo SDK 57 podspec floor                               |
| Android      | API 24   | The Expo SDK 56+ floor                                      |
| Node         | 20.19.4+ | Expo SDK 57's requirement                                   |

CoreNFC has existed since iOS 11, so with a 16.4 floor there is no weak linking to
arrange and no `-weak_framework CoreNFC` hack to copy from anywhere.

## Native configuration

Pick the page for what you are building and copy the blocks under **Bare React
Native**:

<CardGroup cols={2}>
  <Card title="NDEF" icon="tag" href="/setup/ndef">
    The baseline every project needs.
  </Card>

  <Card title="ISO 7816" icon="credit-card" href="/setup/iso7816">
    Plus the AIDs you select.
  </Card>

  <Card title="FeliCa" icon="train-subway" href="/setup/felica">
    Plus the system codes you read.
  </Card>

  <Card title="Background tags" icon="mobile" href="/setup/background-reading">
    Plus intent filters.
  </Card>
</CardGroup>

Those blocks are generated from the config plugin and checked in CI, so they are
what an Expo project would have got, not a description of it.

## The iOS capability

Editing the entitlements file is not enough on its own. The App ID needs the
capability too:

<Steps>
  <Step title="Open your App ID">In the Apple Developer portal.</Step>

  <Step title="Enable Near Field Communication Tag Reading">
    In the identifier's capability list.
  </Step>

  <Step title="Regenerate the provisioning profile">
    With "Automatically manage signing" in Xcode this happens for you. With a manually managed
    profile it does not, and the failure appears at runtime as a session that will not open.
  </Step>
</Steps>

## Verifying autolinking

If the module did not link, every call fails with `contractMismatch` and a message
telling you to rebuild — which is the right answer often enough to be worth
checking first.

<CodeGroup>
  ```bash iOS theme={null}
  # The pod should be listed.
  grep -r ReactNativeNfcKit ios/Podfile.lock
  ```

  ```bash Android theme={null}
  # The module should be in the generated autolinking package list.
  grep -r nfckit android/app/build/generated/autolinking/ 2>/dev/null
  ```
</CodeGroup>

On Android, a fresh `./gradlew :app:assembleDebug` regenerates that list. On iOS,
`npx pod-install` after any dependency change.

## What is not available in a bare project

Only the plugin itself. Everything else — the runtime API, the NDEF codec, the
protocol layers, the React hooks — is plain JavaScript and behaves identically.
