react-native-keyboard-aware-scroll-view
A React Native ScrollView that auto-scrolls to the focused TextInput so the keyboard never covers it.
Repository Health
Technical Analysis
react-native-keyboard-aware-scroll-view solves a persistent React Native annoyance: text inputs getting hidden behind the on-screen keyboard. It wraps ScrollView, FlatList, and SectionList in a higher-order component that listens for keyboard show/hide events and automatically scrolls the focused TextInput into view, with configurable extra height and opening-time offsets.
Rather than shipping three separate components, the library exposes a single listenToKeyboardEvents HOC (KeyboardAwareHOC.js) that any scrollable component can be wrapped with, plus ready-made KeyboardAwareScrollView, KeyboardAwareFlatList, and KeyboardAwareSectionList exports built on top of it. Consumers get imperative methods (scrollToPosition, scrollToEnd, scrollToFocusedInput, scrollIntoView) via innerRef for cases where automatic scrolling isn’t enough.
iOS support works out of the box using native keyboard-will-show/hide events; Android requires opting in via enableOnAndroid since Android’s own windowSoftInputMode handles most of the resizing natively. The library has been a fixture of React Native form-heavy screens since 2015, predating built-in alternatives like KeyboardAvoidingView becoming reliable, and remains widely installed for its broader feature set (tab-bar offset handling, manual scroll-into-view, per-field extra height).
What You Get
KeyboardAwareScrollView,KeyboardAwareFlatList, andKeyboardAwareSectionList— drop-in replacements that accept all normal ScrollView/FlatList/SectionList propslistenToKeyboardEventsHOC to make any custom scrollable component keyboard-aware, curried for configuration (listenToKeyboardEvents(options)(Comp))- Automatic scroll-to-focused-input on keyboard show, with
extraHeight/extraScrollHeight/keyboardOpeningTimetuning props - Imperative API via
innerRef—scrollToPosition,scrollToEnd,scrollToFocusedInput,scrollIntoView,getScrollResponder viewIsInsideTabBarandresetScrollToCoordsoptions for handling tab bar offsets and custom scroll-reset behavior- TypeScript typings (
index.d.ts) and Flow types shipped alongside the JS source
Common Use Cases
- Login, signup, and profile-edit forms with multiple stacked TextInputs that would otherwise be hidden by the keyboard
- Multi-step wizards or checkout flows where the active field must stay visible while typing
- Chat or comment composer screens needing precise control over scroll position when the keyboard opens/closes
- Screens with a bottom tab bar where
viewIsInsideTabBarneeds to offset the keyboard-avoidance calculation - Apps supporting both iOS and Android where the same form behavior needs both native code paths reconciled
Under The Hood
Architecture
The library is built around one higher-order component, KeyboardAwareHOC (lib/KeyboardAwareHOC.js), that any scrollable can be wrapped with; KeyboardAwareScrollView.js, KeyboardAwareFlatList.js, and KeyboardAwareSectionList.js are each a one-line application of that HOC to React Native’s built-in ScrollView, FlatList, and SectionList. The HOC registers native Keyboard listeners in componentDidMount, tracks scroll position via a forked onScroll handler, and exposes an imperative surface (scrollToPosition, scrollToEnd, scrollToFocusedInput, scrollIntoView, getScrollResponder) both as instance methods reachable through innerRef and as extra props forwarded to the wrapped component. Configuration flows through a curried listenToKeyboardEvents(options)(Comp) call merged with per-instance props as defaults, so behavior can be set once at the wrapping site and overridden per usage. This keeps the public surface to a single composition pattern rather than three independently maintained components.
Tech Stack
The package targets React Native directly, declaring react-native>=0.48.4 as a peer dependency and depending only on prop-types and react-native-iphone-x-helper for runtime code, keeping the install footprint minimal. It’s written in Flow-annotated JavaScript (.flowconfig, /* @flow */ pragmas throughout) rather than TypeScript, though a hand-maintained index.d.ts is shipped separately for TypeScript consumers. There is no build/bundling step — main in package.json points straight at the flow-annotated index.js, so the library ships as source and relies on the consuming app’s own Babel/Metro pipeline to strip Flow types.
Code Quality
No test suite exists in the repository — npm test runs npm run lint (ESLint over lib/) rather than any unit or component tests, so behavioral guarantees rest entirely on manual verification and the accumulated experience of long-term usage. Naming is consistent and the Flow type annotations on props, state, and helper functions give reasonable static safety despite the lack of tests. Error handling is minimal by necessity (keyboard event payloads are trusted, native measurement callbacks aren’t defensively checked beyond null guards), which is typical for a thin native-bridge wrapper but means edge cases surface at runtime rather than being caught in CI.
What Makes It Unique
Its differentiator versus React Native’s built-in KeyboardAvoidingView is the automatic-scroll-to-focused-field behavior combined with a reusable HOC that lets any scrollable (not just the three shipped components) opt in, plus fine-grained manual controls (scrollIntoView, per-call extraHeight/keyboardOpeningTime overrides) for cases where the automatic heuristic isn’t precise enough. It predates several now-standard React Native APIs and has stayed relevant mainly through that flexibility and its very large existing install base rather than through novel technical approaches.