npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

react-native-grid-system

v1.0.4

Published

The complete grid system for React Native - CSS Grid-inspired layout with responsive design, masonry support, and zero native dependencies

Readme

react-native-grid-system

The complete grid system for React Native - CSS Grid-inspired layout with responsive design, masonry support, and zero native dependencies. Works seamlessly across iOS, Android, and web (React Native Web).

npm version TypeScript License: MIT

Features

Familiar API - CSS Grid-inspired properties that web developers already know
🎯 Declarative - Define your layout, not the implementation
📱 Cross-Platform - Works on iOS, Android, and React Native Web
🪶 Lightweight - Zero native dependencies, pure JavaScript/TypeScript
🎨 Flexible - Supports fr units, percentages, auto, and fixed pixel values
📐 Spanning - Items can span multiple columns and rows
📲 Responsive - Built-in hooks and utilities for adaptive layouts
🎁 Grid Patterns - Pre-built patterns for common layouts
Performance - Efficient layout calculations with minimal re-renders
🔷 TypeScript - Full type safety with comprehensive type definitions

📸 Visual Examples

Dashboard Layout

A responsive dashboard that adapts seamlessly across devices with complex card layouts, charts, and statistics.

Product Grid

E-commerce product listings that automatically adjust columns based on screen size.

Masonry Photo Gallery

Pinterest-style dense packing with autoFlow="row-dense" for beautiful image galleries.

🎥 Live Demo

Watch the library in action across different screen sizes and orientations:

Note: All examples are fully responsive and work seamlessly on iOS, Android, and Web without any platform-specific code!

Installation

npm install react-native-grid-system

or

yarn add react-native-grid-system

Quick Start

import React from "react";
import { View, Text } from "react-native";
import { Grid, GridItem } from "react-native-grid-system";

const App = () => {
  return (
    <Grid columns={["1fr", "1fr", "1fr"]} gap={10}>
      <GridItem>
        <Text>Item 1</Text>
      </GridItem>
      <GridItem>
        <Text>Item 2</Text>
      </GridItem>
      <GridItem>
        <Text>Item 3</Text>
      </GridItem>
    </Grid>
  );
};

Core Concepts

Grid Container

The Grid component defines the layout structure:

<Grid
  columns={["1fr", "2fr", "1fr"]} // Column track sizes
  rows={[100, "auto", 100]} // Row track sizes (optional)
  gap={10} // Gap between items
  alignItems="center" // Vertical alignment
  justifyItems="stretch" // Horizontal alignment
>
  {/* Grid items */}
</Grid>

Grid Items

The GridItem component represents individual grid cells:

<GridItem
  colSpan={2} // Span 2 columns
  rowSpan={2} // Span 2 rows
  colStart={0} // Explicit column start
  rowStart={1} // Explicit row start
>
  {/* Content */}
</GridItem>

Track Sizing

Fixed Pixels

<Grid columns={[100, 200, 100]} />

Fractional Units (fr)

Distributes available space proportionally:

<Grid columns={["1fr", "2fr", "1fr"]} />
// First column: 25%, Second: 50%, Third: 25%

Auto

Automatically sizes based on content:

<Grid columns={["auto", "1fr", "auto"]} />

Percentages

<Grid columns={["25%", "50%", "25%"]} />

Mixed Units

<Grid columns={[100, "1fr", "2fr", "auto"]} />

Examples

Basic 3-Column Grid

import { Grid, GridItem } from "react-native-grid-system";

<Grid columns={[100, 100, 100]} gap={10}>
  <GridItem>
    <Text>1</Text>
  </GridItem>
  <GridItem>
    <Text>2</Text>
  </GridItem>
  <GridItem>
    <Text>3</Text>
  </GridItem>
  <GridItem>
    <Text>4</Text>
  </GridItem>
  <GridItem>
    <Text>5</Text>
  </GridItem>
  <GridItem>
    <Text>6</Text>
  </GridItem>
</Grid>;

Responsive Layout

<Grid columns={["1fr", "2fr", "1fr"]} gap={10}>
  <GridItem style={styles.sidebar}>
    <Text>Sidebar</Text>
  </GridItem>
  <GridItem style={styles.main}>
    <Text>Main Content</Text>
  </GridItem>
  <GridItem style={styles.aside}>
    <Text>Aside</Text>
  </GridItem>
</Grid>

Spanning Items

<Grid columns={["1fr", "1fr", "1fr"]} rows={[100, 100]} gap={10}>
  {/* Header spanning all columns */}
  <GridItem colSpan={3}>
    <Text>Header</Text>
  </GridItem>

  {/* Sidebar spanning two rows */}
  <GridItem rowSpan={2}>
    <Text>Sidebar</Text>
  </GridItem>

  {/* Main content spanning two columns */}
  <GridItem colSpan={2}>
    <Text>Main</Text>
  </GridItem>

  <GridItem>
    <Text>Footer 1</Text>
  </GridItem>
  <GridItem>
    <Text>Footer 2</Text>
  </GridItem>
</Grid>

Explicit Positioning

<Grid columns={["1fr", "1fr", "1fr"]} rows={[100, 100, 100]}>
  <GridItem colStart={1} rowStart={1}>
    <Text>Center Item</Text>
  </GridItem>
  <GridItem colStart={0} rowStart={0}>
    <Text>Top-Left</Text>
  </GridItem>
  <GridItem colStart={2} rowStart={2}>
    <Text>Bottom-Right</Text>
  </GridItem>
</Grid>

Gallery Layout

<Grid columns={["1fr", "1fr"]} gap={8}>
  {images.map((image, index) => (
    <GridItem key={index}>
      <Image source={image} style={styles.image} />
    </GridItem>
  ))}
</Grid>

API Reference

Grid Props

| Prop | Type | Default | Description | | ---------------- | ---------------- | --------------- | ----------------------------------- | | columns | TrackSize[] | [1] | Array of column track sizes | | rows | TrackSize[] | Auto-calculated | Array of row track sizes | | gap | number | 0 | Gap between all items | | columnGap | number | 0 | Gap between columns | | rowGap | number | 0 | Gap between rows | | alignItems | AlignmentValue | 'stretch' | Vertical alignment | | alignContent | AlignmentValue | 'start' | Content alignment along column axis | | justifyItems | JustifyValue | 'stretch' | Horizontal alignment | | justifyContent | JustifyValue | 'start' | Content alignment along row axis | | autoFlow | GridAutoFlow | 'row' | Auto-placement algorithm | | autoColumns | TrackSize | '1fr' | Auto-generated column size | | autoRows | TrackSize | '100' | Auto-generated row size | | style | ViewStyle | - | Additional container styles |

GridItem Props

| Prop | Type | Default | Description | | ------------- | ---------------- | ------- | ----------------------------------- | | colStart | number | Auto | Column start position (0-indexed) | | colEnd | number | Auto | Column end position | | colSpan | number | 1 | Number of columns to span | | rowStart | number | Auto | Row start position (0-indexed) | | rowEnd | number | Auto | Row end position | | rowSpan | number | 1 | Number of rows to span | | alignSelf | AlignmentValue | - | Override alignItems for this item | | justifySelf | JustifyValue | - | Override justifyItems for this item | | style | ViewStyle | - | Additional item styles |

Type Definitions

type TrackSize = number | string;
type AlignmentValue = "start" | "end" | "center" | "stretch" | "baseline";
type JustifyValue =
  | "start"
  | "end"
  | "center"
  | "stretch"
  | "space-between"
  | "space-around"
  | "space-evenly";
type GridAutoFlow = "row" | "column" | "row-dense" | "column-dense";

Advanced Features

Auto-Sizing Rows

Use autoRows="auto" to automatically calculate row heights based on content:

<Grid columns={["1fr", "1fr"]} autoRows="auto" gap={10}>
  <GridItem>
    <Text>Short content</Text>
  </GridItem>
  <GridItem>
    <Text>Much longer content that takes up more vertical space...</Text>
  </GridItem>
</Grid>

How it works: The Grid automatically measures each item's rendered height and calculates row heights based on the tallest item in each row. Multi-row items have their height distributed evenly across spanned rows.

Perfect for:

  • Mobile responsive layouts with varying content heights
  • Dynamic content that changes size
  • Cards with different amounts of text
  • Dashboard widgets with unpredictable content

Dense Packing (Masonry Layouts)

Enable autoFlow="row-dense" for Pinterest-style masonry layouts:

<Grid
  columns={["1fr", "1fr", "1fr"]}
  autoRows="120"
  autoFlow="row-dense"
  gap={10}
>
  {photos.map((photo) => (
    <GridItem key={photo.id} rowSpan={photo.height}>
      <Image source={photo.src} />
    </GridItem>
  ))}
</Grid>

How it works: The algorithm fills gaps by backtracking to find available space, creating a tight, compact layout instead of leaving diagonal gaps.

💡 Pro Tip for natural masonry layouts:

Vary your item heights for the best visual effect:

  • 50-60% short items (rowSpan={1})
  • 30-35% medium items (rowSpan={2})
  • 10-15% tall items (rowSpan={3})

This distribution gives the algorithm more opportunities to fill gaps and creates a natural Pinterest-style appearance.

📖 Full guide with troubleshooting

Responsive Design

Using the Responsive Hook

import { Grid, GridItem, useResponsiveGrid } from "react-native-grid-system";

function MyComponent() {
  // Automatically adapts to screen size with columns AND gap
  const gridConfig = useResponsiveGrid({
    xs: { columns: ["1fr"], gap: 10 }, // 1 column on mobile
    sm: { columns: ["1fr", "1fr"], gap: 12 }, // 2 columns on small tablets
    md: { columns: ["1fr", "1fr", "1fr"], gap: 15 }, // 3 columns on tablets
    lg: { columns: ["1fr", "1fr", "1fr", "1fr"], gap: 20 }, // 4 columns on desktop
  });

  return (
    <Grid {...gridConfig} autoRows="120">
      {/* Your items */}
    </Grid>
  );
}

Using Grid Patterns

Pre-built patterns for common layouts:

import { Grid, GridItem, GridPatterns } from 'react-native-grid-system';

// Sidebar layout
<Grid columns={GridPatterns.sidebar(200, 'left')} />

// Holy grail (3-column) layout
<Grid columns={GridPatterns.holyGrail(150, 200)} />

// Equal columns
<Grid columns={GridPatterns.equal(4)} />

// Gallery grid (auto-calculates columns)
<Grid columns={GridPatterns.gallery(120)} />

// Responsive columns
const responsiveConfig = GridPatterns.responsiveColumns(1, 2, 3, 4);

Breakpoint Detection

import { useBreakpoint } from "react-native-grid-system";

function MyComponent() {
  const breakpoint = useBreakpoint(); // 'xs' | 'sm' | 'md' | 'lg' | 'xl'

  return <Text>Current: {breakpoint}</Text>;
}

How It Works

Unlike CSS Grid which relies on browser layout engines, react-native-grid-system implements a grid layout algorithm in pure JavaScript:

  1. Track Sizing: Calculates actual pixel sizes for each column and row based on track definitions (fr, auto, %, px)
  2. Auto-Placement: Positions items that don't have explicit positioning using the specified autoFlow algorithm
  3. Layout Calculation: Computes absolute positions for each grid item based on the grid structure
  4. Rendering: Uses React Native's absolute positioning to place items accurately

This approach ensures consistent behavior across all platforms without requiring native modules.

Performance Considerations

  • Memoization: The layout calculation is optimized to minimize re-calculations
  • Layout Events: Uses React Native's onLayout to respond to container size changes
  • Efficient Updates: Only recalculates when props or container dimensions change

Differences from CSS Grid

While the API is inspired by CSS Grid, there are some differences due to React Native constraints:

  • No grid-template-areas: Use explicit positioning instead
  • Limited auto-flow: Dense packing is simplified
  • No implicit grids: Rows/columns must be explicitly defined or auto-generated
  • Positioning: Uses absolute positioning internally instead of CSS Grid layout

TypeScript Support

This package is written in TypeScript and includes full type definitions. All components and utilities are fully typed for the best development experience.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details

Roadmap

  • [x] Responsive utilities - Built-in breakpoint system ✅
  • [x] Grid patterns - Common layout helpers ✅
  • [ ] Virtualization support - Add optional FlatList integration for large datasets
  • [ ] minmax() function - For min/max track sizing
  • [ ] repeat() notation - Shorthand for repeating track patterns
  • [ ] Grid templates - Named grid areas (grid-template-areas)
  • [ ] Animation support - Smooth grid transitions
  • [ ] Performance optimizations - For very large grids

Support

For issues, feature requests, or questions, please file an issue on GitHub.


Made with ❤️ for the React Native community