Native-first React Native toolkit for physical (external) keyboard support on iOS and Android — focus management, key-press events, custom focus order, and focus locking.
- 🎯 Keyboard focus management — focus/blur events,
autoFocus, imperative focus viaref - ⌨️ Key press events — handle key-down / key-up with full modifier info
- 🔢 Custom focus order — link-based, index-based, or direction locking
- 🔒 Focus lock — keep focus inside modals and overlays (
Focus.Frame/Focus.Trap) - 🎨 Native focus styling — iOS halo effect &
tintColor, AndroiddefaultFocusHighlightEnabled - ⚡ New Architecture · Bridgeless · Expo prebuild
Tip
The quickest start is the K namespace — K.Pressable, K.View, and K.Input are drop-in, keyboard-focusable versions of Pressable, View, and TextInput. To add focus to a component you already have (a custom button, TouchableOpacity, …), reach for the withKeyboardFocus HOC. See the getting started guide.
Note
On iOS, long-pressing the spacebar does not fire a long press — iOS routes it through Full Keyboard Access. Use Tab + M (the default "open context menu" command) instead.
npm install react-native-external-keyboard
cd ios && pod installThis installs 2.x, which needs React Native 0.87 or newer — on an older version, pick your row in React Native compatibility first.
Get started with the getting started guide or jump straight to the component overview.
Use the K namespace — K.Pressable, K.View, and K.Input are ready-made, keyboard-focusable replacements for Pressable, View, and TextInput:
import { K } from 'react-native-external-keyboard';
import { Text } from 'react-native';
<K.Pressable
autoFocus
onPress={onPress}
style={({ focused }) => focused && { backgroundColor: 'dodgerblue' }}
>
<Text>Press me with Space or Enter</Text>
</K.Pressable>Need focus on a component the K namespace doesn't cover — TouchableOpacity, a custom button, a third-party component? Wrap it with the withKeyboardFocus HOC:
import { withKeyboardFocus } from 'react-native-external-keyboard';
import { TouchableOpacity } from 'react-native';
const KeyboardTouchable = withKeyboardFocus(TouchableOpacity);Find your React Native version, install the matching package version:
| React Native | Install | Architecture |
|---|---|---|
| 0.87 and newer | react-native-external-keyboard@2 |
New Architecture only |
| 0.80 – 0.86 | react-native-external-keyboard@1 |
New + Old Architecture |
| 0.79 and older | react-native-external-keyboard@0.13 |
New + Old Architecture |
On 2.0.0 the New Architecture is the only code path — Fabric, Turbo Modules, and bridgeless, in both Expo prebuild and bare projects. Old Architecture (Bridge) support wasn't switched off in 2.0.0, it was removed, so there's nothing to fall back to: the package declares react-native >=0.87 as a peer dependency, and installing it on anything older trips the peer check. Pick the row for your version instead.
New here? Start with the getting started guide, then follow a task-focused guide. The full docs index links everything.
Guides — task-focused walkthroughs
- Pressable focus handling — focus/blur events,
style/containerStyle, render props - Native focus styling — iOS halo &
tintColor, Android focus highlight - Programmatic focus —
ref.focus(),keyboardFocus(),autoFocus - Keyboard text input —
KeyboardExtendedInput,focusType,blurType - Focus order — link-based, index-based, and direction-lock ordering
Advanced
- Native focus services — native-side focus API & memory service for custom native code
Reference
- Component overview — every component and its props
- API reference — modules, hooks, the imperative ref, shared types
- Migration guide — version-to-version upgrade notes
Components
| Export | Purpose |
|---|---|
K.Pressable / K.View / K.Input |
Ready-made, keyboard-focusable Pressable / View / TextInput. Start here. |
withKeyboardFocus(C) |
HOC that adds keyboard focus to any Pressable/Touchable-like component. |
KeyboardExtendedView |
Focus-aware View for key handling and grouping (also K.View). |
KeyboardExtendedInput |
TextInput with keyboard focus support (also K.Input). |
KeyboardExtendedBaseView |
Low-level focusable view (alias ExternalKeyboardView). |
KeyboardFocusGroup |
iOS focusGroupIdentifier grouping + global tintColor. |
Focus.Frame / Focus.Trap |
Confine focus to a region (modals, overlays). |
KeyboardOrderFocusGroup |
Namespacing + index-based focus ordering. |
API
| Export | Purpose |
|---|---|
Keyboard |
Dismiss the soft keyboard from a hardware keyboard. |
KeyboardFocus ref |
Imperative focus handle (focus, keyboardFocus, screenReaderFocus). |
| Hooks | useIsViewFocused, useIsViewPressed, useOrderFocusGroup. |
| Focus-order props | orderId, order*, orderIndex, orderGroup, lockFocus. |
iOS 26+. Testing on iOS 26 (including iOS 27) found real Tab-navigation differences compared to iOS 18.x — these are OS-level behavior changes, not bugs in this library. If something behaves as expected on iOS 18.x but not on the latest iOS, layout is a likely reason.
Since iOS 26, inner groups or children that cover a parent Pressable can affect Tab
navigation — the library handles the common case automatically, but a sufficiently complex
layout may still behave differently. Separately, TextInput focus order and behavior has
also changed; it appears related to layout and geometry, not just component order, and
there is currently no flag or fix to restore the iOS 18 behavior. For more details see:
iOS 26+ platform-specific issues.
All planned features are implemented and released. No new functionality or API changes are planned.
Future work is limited to:
- React Native version support (new releases)
- Bug fixes and issue resolution
Both active versions receive fixes:
| Version | React Native | Status |
|---|---|---|
2.0.0 |
≥ 0.87 | Active — bug fixes and new RN support, New Architecture only |
0.13.0 |
≤ 0.79 | Active — bug fixes only |
Any type of contribution is highly appreciated. Feel free to create PRs, raise issues, or share ideas — see the contributing guide for the development workflow.
It has been a long journey since the first release of the react-native-external-keyboard package. Many features have been added, and a lot of issues have been fixed.
With that, I would like to thank the contributors, those who created issues, and the followers, because achieving these results wouldn't have been possible without you.
Thanks to the initial authors: Andrii Koval, Michail Chavkin, Dzmitry Khamitsevich.
Thanks to the contributors: João Mosmann, Stéphane.
Thanks to those who created issues: Stéphane, proohit, Rananjaya Bandara, SteveHoneckPGE, Wes.
I really appreciate your help; it has truly helped me move forward!
MIT
Made with create-react-native-library

