How flex: 1 Controls Layout in React Native: Yoga Engine Deep Dive

Using flex: 1 in React Native sets flexGrow to 1, flexShrink to 1, and flexBasis to 0, causing the component to expand and fill all remaining available space in its parent container while sharing that space proportionally with siblings.

When building layouts in React Native, the flex: 1 declaration is the most common tool for distributing space within a container. According to the facebook/react source code, this single property triggers a specific behavior in the Yoga layout engine that differs subtly from standard CSS Flexbox. Understanding precisely how flex: 1 in React Native expands to its constituent properties ensures you build predictable, responsive interfaces.

What Does flex: 1 Actually Do in React Native?

React Native uses the Yoga layout engine, which implements the Flexbox specification. In a style object, the flex property acts as a shorthand for three separate Flexbox properties:

  • flexGrow – defines how much a component should expand relative to its siblings when free space exists.
  • flexShrink – defines how much a component should shrink when the container is too small.
  • flexBasis – defines the initial main-size of the component before any flexing occurs.

In React Native, the shorthand is interpreted as flexGrow value with flexShrink fixed at 1 and flexBasis set to 0. Consequently, writing flex: 1 tells Yoga that the component should take up all remaining space in its parent container while sharing that space proportionally with any siblings that also declare a flex value.

The Three Properties Behind flex: 1

flexGrow: 1

The flexGrow value of 1 instructs the Yoga engine to distribute available free space to this component. When multiple siblings have flex: 1, they divide the remaining space equally. If one sibling has flex: 2 and another has flex: 1, the first receives twice as much space as the second.

flexShrink: 1

By default, React Native sets flexShrink to 1 when using the flex shorthand. This allows the component to shrink below its content size if the container dimensions are constrained. This prevents overflow issues when the combined intrinsic sizes of children exceed the parent container.

flexBasis: 0

Setting flexBasis to 0 means the component starts with no intrinsic size along the main axis before the remaining space is distributed. This ensures that the flexGrow calculation operates on the entire available space rather than starting from the component's content size. This behavior is crucial for achieving true proportional distribution.

Practical Layout Examples with flex: 1

The following example demonstrates how flex: 1 distributes vertical space between components while respecting fixed dimensions on non-flex children.

import {View, Text, StyleSheet} from 'react-native';

export default function FlexDemo() {
  return (
    <View style={styles.container}>
      {/* Takes half the available height */}
      <View style={styles.topBox}>
        <Text>Top (flex: 1)</Text>
      </View>

      {/* Takes the other half */}
      <View style={styles.bottomBox}>
        <Text>Bottom (flex: 1)</Text>
      </View>

      {/* Fixed height – does not flex */}
      <View style={styles.footer}>
        <Text>Footer (height: 50)</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,                 // Fill the whole screen
    flexDirection: 'column' // Default, but explicit for clarity
  },
  topBox: {
    flex: 1,                 // Grow to occupy half the vertical space
    backgroundColor: '#a2d5f2',
    justifyContent: 'center',
    alignItems: 'center',
  },
  bottomBox: {
    flex: 1,                 // Same as topBox – shares space equally
    backgroundColor: '#f2a2a2',
    justifyContent: 'center',
    alignItems: 'center',
  },
  footer: {
    height: 50,              // Fixed size – not part of flex distribution
    backgroundColor: '#d5f2a2',
    justifyContent: 'center',
    alignItems: 'center',
  },
});

In this implementation, the container fills the entire screen because it declares flex: 1. Inside it, topBox and bottomBox each receive equal portions of the remaining vertical space because they both specify flex: 1. The footer remains at a fixed height of 50 logical pixels and sits at the bottom because it lacks a flex value and instead uses an explicit height.

How React Native Processes the flex Property

The React Native source code treats flex as a unit-less property during style processing. According to the implementation in packages/react-dom-bindings/src/shared/isUnitlessNumber.js at lines 24-27, the property is listed among unit-less CSS numbers, ensuring that numeric values are not suffixed with px or other units.

The mapping from the shorthand to its constituent components is defined in packages/react-dom-bindings/src/client/CSSShorthandProperty.js at line 109. This file establishes that the flex property expands to control flexBasis, flexGrow, and flexShrink simultaneously.

When Yoga receives the style object, it interprets the expanded values to calculate the final layout. The flex: 1 declaration ultimately instructs the engine to distribute available space proportionally while allowing the component to shrink if necessary, starting from a zero basis.

Summary

Frequently Asked Questions

What is the difference between flex: 1 and flexGrow: 1 in React Native?

Using flex: 1 sets three properties simultaneously: flexGrow: 1, flexShrink: 1, and flexBasis: 0. Writing only flexGrow: 1 leaves flexShrink and flexBasis at their default values, which may cause the component to behave differently when the container has constrained space or when calculating initial layout positions.

Why does flex: 1 fill the entire screen in React Native?

When a top-level component declares flex: 1 without siblings competing for space, it expands to occupy all available area in its parent. If this component is the root of your application, it fills the entire screen because there are no other flex siblings to share the space, and the Yoga engine allocates 100% of the container's dimensions to the single flex: 1 child.

How does flex: 1 interact with fixed dimensions like width or height?

Components with explicit width or height values do not participate in flex distribution along that axis. If a sibling has flex: 1 and another has height: 50, the flex component occupies all remaining space after the fixed-height component is positioned. The fixed dimension acts as a constraint that the Yoga engine satisfies before calculating flex distribution for remaining siblings.

Is flex: 1 in React Native the same as CSS flex: 1 in web development?

While the syntax is identical, the underlying implementation differs. React Native uses the Yoga layout engine, which interprets flex: 1 as flexGrow: 1, flexShrink: 1, and flexBasis: 0. Web browsers may handle the shorthand differently depending on the CSS specification version and vendor prefixes, though modern browsers typically align with the Yoga interpretation for simple cases.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →