Glow Effect on TextInput with Reanimated CSS Animations

Beto, March 2026

Subtle UI feedback makes an app feel alive. One of the simplest ways to add polish to a text input is a glow that activates when the user starts typing.

With Reanimated's CSS animation support, you can do this in a few lines, no useSharedValue, no useAnimatedStyle, just keyframes and boxShadow.

The Approach

The idea is straightforward:

  1. Define two keyframe animations: one that fades a boxShadow in and one that fades it out.
const glowIn: CSSAnimationKeyframes = {
  from: { boxShadow: `0 0 0 0 ${GLOW_COLOR}00` },
  to: { boxShadow: `0 0 32px 4px ${GLOW_COLOR}80` },
};
 
const glowOut: CSSAnimationKeyframes = {
  from: { boxShadow: `0 0 32px 4px ${GLOW_COLOR}59` },
  to: { boxShadow: `0 0 0 0 ${GLOW_COLOR}00` },
};
  1. Toggle between them based on whether the input has text.
const [text, setText] = useState("");
const hasText = text.length > 0;
 
return (
  <Animated.View
    style={{
      animationName: hasText ? glowIn : glowOut,
    }}
  />
);
  1. Wrap the TextInput in an Animated.View and apply the animation declaratively via style props.
import { useState } from "react";
import { StyleSheet, TextInput, View } from "react-native";
import Animated, { type CSSAnimationKeyframes } from "react-native-reanimated";
 
const GLOW_COLOR = "#6C63FF";
 
const glowIn: CSSAnimationKeyframes = {
  from: { boxShadow: `0 0 0 0 ${GLOW_COLOR}00` },
  to: { boxShadow: `0 0 32px 4px ${GLOW_COLOR}80` },
};
 
const glowOut: CSSAnimationKeyframes = {
  from: { boxShadow: `0 0 32px 4px ${GLOW_COLOR}59` },
  to: { boxShadow: `0 0 0 0 ${GLOW_COLOR}00` },
};
 
export function GlowInput() {
  const [text, setText] = useState("");
  const hasText = text.length > 0;
 
  return (
    <View style={styles.container}>
      <Animated.View
        style={[
          styles.glow,
          {
            animationName: hasText ? glowIn : glowOut,
            animationDuration: hasText ? "400ms" : "500ms",
            animationFillMode: "forwards",
            animationTimingFunction: "ease-out",
          },
        ]}
      >
        <TextInput
          autoFocus
          value={text}
          onChangeText={setText}
          placeholder="Type something..."
          placeholderTextColor="#999"
          cursorColor={GLOW_COLOR}
          style={styles.input}
        />
      </Animated.View>
    </View>
  );
}
 
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    paddingHorizontal: 24,
  },
  glow: {
    borderRadius: 999,
  },
  input: {
    color: "#fff",
    fontSize: 18,
    fontWeight: "500",
    paddingHorizontal: 20,
    paddingVertical: 16,
    backgroundColor: "#1c1c1e",
    borderRadius: 999,
    borderWidth: 1,
    borderColor: "#333",
  },
});

Tips

  • Swap the color, change GLOW_COLOR to match your app's accent color. Red for errors, green for valid state, whatever fits.
  • Adjust intensity, the 32px blur radius and 4px spread control how dramatic the glow feels. Dial them down for something more subtle.
  • Trigger on focus instead, replace the hasText check with onFocus / onBlur state if you want the glow to activate on tap rather than on input.

Want to go deeper?

The React Native course includes a lesson on Animations and Gestures: Reanimated helpers (withTiming, withSpring, and related APIs) and gesture types from React Native Gesture Handler, with a small app example you can reference.

LessonAnimations and Gestures

For the full curriculum, see the React Native course.

I also share practical tips, experiments, and updates in my newsletter if you want to stay in the loop.

Want to partner with me? You can reach me at beto@codewithbeto.dev.

Let's connect!