ShipNative
PricingBlogFAQContact
Build my app
ShipNative
PricingBlogFAQContact
Build my app
GuideOctober 2026 · 8 min read · By Saurabh Singh

react-native-keyboard-controller: Setup and Real Examples

The built-in KeyboardAvoidingView reacts after the keyboard moves, behaves differently on iOS and Android, and has no idea which input is focused. react-native-keyboard-controller fixes all three by tracking the keyboard frame by frame on the UI thread. This guide covers the setup most people get stuck on, the three components that cover almost every screen, and a custom keyboard-synced animation, with code you can paste.

Setup in four steps

npx expo install react-native-keyboard-controller react-native-reanimated
npx expo run:ios      # or run:android, or an EAS development build

It is a native module, so after installing you need a fresh development build. Then wrap your root layout once:

// app/_layout.tsx
import { Stack } from 'expo-router';
import { KeyboardProvider } from 'react-native-keyboard-controller';

export default function RootLayout() {
  return (
    <KeyboardProvider>
      <Stack />
    </KeyboardProvider>
  );
}

Forgetting KeyboardProvideris the number one reason the library “does nothing”. Every component and hook reads keyboard state from it. Running an old build that predates the install is number two.

The components and what each is for

ExportUse it for
KeyboardAvoidingViewDrop-in replacement for the core one, same props, consistent on both platforms
KeyboardAwareScrollViewLong forms: scrolls the focused input above the keyboard
KeyboardStickyViewChat composers and bottom bars that ride on top of the keyboard
KeyboardToolbarPrevious / Next / Done bar above the keyboard for multi-field forms
useKeyboardHandlerYour own worklet callbacks on start, move, and end of the keyboard animation

The quickest win is swapping the import on an existing screen: change KeyboardAvoidingView from react-nativeto the library's version. Same props, but it animates in step with the keyboard and behaves the same on both platforms, so the per-platform behavior switch most codebases carry can go.

Long forms: KeyboardAwareScrollView

import { TextInput } from 'react-native';
import { KeyboardAwareScrollView, KeyboardToolbar } from 'react-native-keyboard-controller';

export default function ProfileForm() {
  return (
    <>
      <KeyboardAwareScrollView
        bottomOffset={24}
        contentContainerStyle={{ padding: 16, gap: 12 }}
        keyboardShouldPersistTaps="handled"
      >
        <TextInput placeholder="Name" />
        <TextInput placeholder="Email" keyboardType="email-address" />
        <TextInput placeholder="Company" />
        <TextInput placeholder="Bio" multiline />
      </KeyboardAwareScrollView>
      <KeyboardToolbar />
    </>
  );
}

When an input gains focus, the scroll view moves it just above the keyboard, with bottomOffset as breathing room. That is the behaviour people try to fake with KeyboardAvoidingView plus ScrollView plus manual scrollTo calls. KeyboardToolbar adds previous, next, and done buttons, which matter on iOS number pads that have no return key.

Chat input: KeyboardStickyView

import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { KeyboardStickyView } from 'react-native-keyboard-controller';

export function Composer() {
  const { bottom } = useSafeAreaInsets();
  return (
    <KeyboardStickyView offset={{ closed: 0, opened: bottom }}>
      <View style={{ paddingBottom: bottom, flexDirection: 'row', padding: 8 }}>
        <TextInput style={{ flex: 1 }} placeholder="Message" />
        <SendButton />
      </View>
    </KeyboardStickyView>
  );
}

The composer moves with the keyboard every frame, so there is no gap or overlap mid-animation. The offset.opened value cancels the bottom safe-area padding once the keyboard covers the home indicator, otherwise the input floats one inset too high. The safe area guide explains where that inset comes from. For the message list itself, see the chat app guide.

Custom animation synced to the keyboard

import Animated, { useAnimatedStyle, interpolate } from 'react-native-reanimated';
import { useReanimatedKeyboardAnimation } from 'react-native-keyboard-controller';

export function ShrinkingHeader() {
  const { progress } = useReanimatedKeyboardAnimation(); // 0 closed, 1 open

  const style = useAnimatedStyle(() => ({
    height: interpolate(progress.value, [0, 1], [160, 64]),
    opacity: interpolate(progress.value, [0, 1], [1, 0.6]),
  }));

  return <Animated.View style={style} />;
}

progress and height are Reanimated shared values updated on the UI thread, so a header that shrinks while the keyboard rises stays perfectly in step. For full control over each phase, useKeyboardHandler gives you onStart, onMove, and onEnd worklets. The animations guide covers the Reanimated basics.

When the built-in component is enough

A login screen with two inputs does not need a native dependency. The core KeyboardAvoidingView handles it with the right behavior and offset. Reach for keyboard-controller when you have a composer pinned to the bottom, a form longer than one screen, inputs inside a bottom sheet, or Android and iOS disagreeing in ways you keep patching.

Keyboard bugs only show up on a real phone with a real keyboard. Describe the screen to ShipNative and it generates the React Native with keyboard handling included, then runs it on your phone, so you test the last field of the longest form before your users do.

Frequently Asked Questions

What is react-native-keyboard-controller?

A native library that reports the keyboard position frame by frame on the UI thread, on both iOS and Android, and builds components on top of it: a drop-in KeyboardAvoidingView, KeyboardAwareScrollView for forms, KeyboardStickyView for inputs pinned above the keyboard, and KeyboardToolbar for previous, next, and done buttons.

Does react-native-keyboard-controller work in Expo Go?

It contains native code, so it only works in Expo Go if the Expo Go version for your SDK bundles it. Check the Expo docs for your SDK. A development build always works and is what you will ship anyway.

Do I need Reanimated for react-native-keyboard-controller?

Yes. react-native-reanimated is a peer dependency, because the keyboard position is exposed as Reanimated shared values and the handlers run as worklets on the UI thread. Most Expo apps already have Reanimated installed.

Why does nothing happen after I install it?

The usual cause is a missing KeyboardProvider. Every component and hook in the library reads from it, so wrap your root layout in KeyboardProvider once. The second cause is running an old build: after installing a native package you have to rebuild the development client.

Should I replace every KeyboardAvoidingView with this library?

No. The built-in KeyboardAvoidingView is fine for short screens like a login form. Use keyboard-controller for chat composers, long forms, inputs inside sheets, and anywhere the keyboard animation is visible enough that a snap looks cheap.

Can an AI app builder handle keyboard behaviour for me?

Yes. Describe the screen, "a chat screen with the message input pinned above the keyboard", and ShipNative generates it with keyboard handling as real React Native, then runs it on your phone so you can check it with the real keyboard.

→

React Native KeyboardAvoidingView

When the built-in component is enough, and the values that make it work.

Read guide →
→

React Native TextInput

Keyboard types, return keys, and focus handling for the inputs themselves.

Read guide →

Ship a real React Native app today

Describe, preview, and export Expo code, free to start.

Build with ShipNative
ShipNative

Build mobile apps with AI. Describe it, try it on your phone, own the code.

Features

Text to App AIApp Generator from ScreenshotPRD to Mobile App

Tools

All free toolsApp Cost CalculatorApp Name GeneratorApp Store Keyword ToolReact Native Components

Blog

All blog postsHow to Build an App Without CodingBest AI Tools for Real Mobile AppsExpo EAS App Store ChecklistLovable, Cursor & v0 for MobileBest AI App Builders in 2026React Native AI App Builder Guide
© 2026 ShipNative
PrivacyTermsAboutFAQPricingDiscordShipNative - Featured on Startup FameFeatured on Twelve ToolsFeatured on TinyShelfShipNative - Launched on Fazier