Pinterest Style Home Feed (React Native)
Description
A Pinterest-style 2-column masonry feed built in React Native CLI. Supports image preloading, caching, and smooth infinite scrolling with FlashList. Ready to integrate into any e-commerce, social, or content-heavy app.
Tech Stack
- React Native CLI
- @shopify/flash-list
- react-native-nitro-image
Documentation
Pinterest Clone - Home Feed
A high-performance React Native Pinterest clone featuring a masonry layout home feed with optimized image loading, video playback, and smooth scrolling experience.
Experience the smooth scrolling, masonry layout, and smart video playback in action
⨠Features
- Masonry Layout: Pinterest-style staggered grid layout with dynamic item heights
- Mixed Media Support: Seamlessly displays both images and videos in the feed
- High Performance: Optimized for smooth scrolling with thousands of items
- Smart Video Playback: Auto-play videos when visible, pause when scrolled away
- Fast Image Loading: Cached image loading with placeholder states
- Responsive Design: Adapts to different screen sizes and orientations
š Quick Start
Prerequisites
Make sure you have completed the React Native Environment Setup guide.
Installation
-
Install dependencies:
npm install
-
iOS Setup (iOS only):
# Install CocoaPods dependencies bundle install bundle exec pod install
-
Run the app:
# Android npm run android # iOS npm run ios
šļø Architecture & Key Technologies
App Structure
The app follows a clean, scalable architecture organized in the src/
directory:
src/
āāā components/ # Reusable UI components
ā āāā types.ts # TypeScript interfaces and types
ā āāā data.ts # Mock data generation (1000+ items)
ā āāā Header.tsx # App header component
ā āāā PinterestItem.tsx # Item wrapper with layout logic
ā āāā PinterestImageItem.tsx # Image-specific rendering
ā āāā PinterestVideoItem.tsx # Video-specific rendering
āāā screens/ # Screen components
ā āāā OnBoard.tsx # Onboarding screen with preloading
ā āāā Home.tsx # Main Pinterest feed screen
āāā navigations/ # Navigation configuration
āāā Routes.tsx # Stack navigator setup
š Smart Preloading Strategy (OnBoard Screen)
The OnBoard screen implements intelligent preloading for optimal user experience:
Screen Preloading
useEffect(() => {
navigation.preload('Home'); // Preload Home screen bundle
}, []);
Benefits:
- Instant Navigation: Home screen loads immediately when user taps "Continue"
- Reduced Perceived Load Time: No loading spinner or blank screen
- Better First Impression: Seamless transition creates premium app feel
- Bundle Optimization: React Navigation loads and prepares the Home screen's JavaScript bundle
Image Preloading with Nitro Web Image
import { WebImages } from 'react-native-nitro-web-image';
useEffect(() => {
data.forEach((item: Item) => {
if(item.type === 'image' && item.url.includes('https')) {
console.log("preloading image", item.url)
WebImages.preload(item.url);
}
});
}, []);
Why This is Game-Changing:
- Instant Image Display: Images appear immediately when scrolling (no loading placeholders)
- Bandwidth Optimization: Downloads happen during onboard idle time, not during scrolling
- Memory Efficiency: Nitro Web Image's smart caching prevents duplicate downloads
- Better UX: Users see rich content immediately instead of loading states
- Reduced Bounce Rate: Fast, responsive feed keeps users engaged
Performance Impact:
- 50-80% Faster Feed Loading: Images are cached before user reaches Home screen
- Smooth Scrolling: No network requests during scroll = consistent 60fps
- Reduced Data Usage: Smart caching prevents re-downloading images
- Battery Savings: Bulk preloading is more efficient than scattered requests
Performance Optimizations
1. @shopify/flash-list - Ultra-Fast Scrolling
We use @shopify/flash-list
instead of React Native's default FlatList
for several critical performance reasons:
- 10x Better Performance: FlashList renders only visible items and a small buffer, dramatically reducing memory usage
- Masonry Layout Support: Built-in masonry layout with
masonry={true}
prop for Pinterest-style grids - Smooth Scrolling: Maintains 60fps even with thousands of items through advanced recycling
- Smart Item Arrangement:
optimizeItemArrangement={true}
automatically optimizes layout for better performance - Memory Efficient: Removes off-screen views with
removeClippedSubviews={true}
<FlashList
data={items}
renderItem={renderItem}
masonry // Pinterest-style layout
numColumns={2} // Two-column grid
optimizeItemArrangement={true} // Performance optimization
removeClippedSubviews={true} // Memory optimization
/>
Why this matters: With 1000+ items, FlashList uses ~50MB memory vs FlatList's ~500MB+, preventing crashes and ensuring smooth scrolling.
2. react-native-nitro-web-image - Lightning-Fast Image Loading
We use react-native-nitro-web-image
for superior image performance:
- Native Performance: Written in C++ for maximum speed
- Smart Caching: Automatic disk and memory caching with LRU eviction
- Preloading Support: Bulk image preloading with
WebImages.preload()
- Memory Efficient: Automatic image compression and memory management
- Lazy Loading: Images load only when needed (combined with preloading for best results)
<NitroImage
image={{ url: item.url }}
style={{ width: '100%', height: itemHeight }}
/>
Why this matters: Loads images 3-5x faster than standard Image component, with built-in caching that persists across app sessions.
Components Architecture
Component Responsibilities:
Components:
PinterestItem.tsx
: Layout calculations and item type routing (wrapper component)PinterestImageItem.tsx
: Optimized image rendering with NitroImagePinterestVideoItem.tsx
: Smart video playback with auto-play/pause logicHeader.tsx
: App header with search and navigationtypes.ts
: Centralized type definitions for type safetydata.ts
: Mock data generator (1000+ items: ~90% images, ~10% videos with varied heights)
Screens:
OnBoard.tsx
: Animated onboarding screen with preloading optimizationsHome.tsx
: Main Pinterest feed with FlashList, visibility tracking, and masonry layout
Navigation:
Routes.tsx
: Stack navigator configuration with header-less screens
š± Navigation Flow & User Experience
The app follows a simple but effective navigation pattern:
OnBoard Screen ā Home Screen
ā ā
Preloading Pinterest Feed
- Screen bundle - 1000+ items
- Image cache - Masonry layout
- Instant nav - Video playback
Navigation Benefits:
- Header-less Design: Full-screen immersive experience
- Preloaded Navigation: Zero loading time between screens
- Stack Navigation: Native iOS/Android navigation patterns
- Memory Efficient: Screens are properly unmounted when not visible
Critical Layout Logic:
// Dynamic height calculation based on aspect ratio
const itemHeight = COL_WIDTH * (item.h / item.w);
This ensures each item maintains its original aspect ratio while fitting the column width.
š Why Width/Height Must Come from Backend
The w
(width) and h
(height) properties in our data structure are critical for performance:
Layout Calculation Performance
// ā
FAST: Pre-calculated height, no layout shifts
const itemHeight = COL_WIDTH * (item.h / item.w);
// ā SLOW: Would require image loading to get dimensions
// This would cause layout shifts and poor UX
Why Backend Dimensions Matter:
- Prevents Layout Shifts: FlashList needs exact item heights upfront to calculate scroll positions
- Faster Initial Render: No waiting for images to load to determine layout
- Memory Efficiency: FlashList can pre-calculate total content height
- Smooth Scrolling: Consistent item heights prevent scroll jumping
- Better UX: Users see proper placeholders immediately
Backend Implementation Requirements:
{
"id": "123",
"url": "https://example.com/image.jpg",
"w": 800, // ā Must be actual image width
"h": 1200, // ā Must be actual image height
"type": "image"
}
Without proper dimensions: The app would experience layout thrashing, poor scroll performance, and memory issues as FlashList couldn't properly optimize rendering.
š Data Structure & Generation
The app generates 1000+ mixed media items with realistic Pinterest-like characteristics:
// From data.ts - Smart data generation
export const data: Item[] = Array.from({ length: 1000 }).map((_, i) => {
const w = 600; // Consistent width
const heightVariations = [200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800];
const h = heightVariations[i % heightVariations.length] + ((i * 47) % 300);
// Mix videos every 8-12 items (realistic Pinterest ratio)
const isVideo = i > 0 && i % (8 + (i % 5)) === 0;
return isVideo ? videoItem : imageItem;
});
Data Generation Features:
- Varied Heights: 13 different height variations + random offset for natural Pinterest look
- Smart Video Distribution: Videos appear every 8-12 items (not clustered)
- Consistent Width: All items use 600px width for predictable layout calculations
- Real URLs: Uses Picsum for images and sample MP4s for videos
- Type Safety: Full TypeScript support with
Item
interface
šÆ Key Features Implementation
Smart Video Playback
- Auto-play when visible: Videos automatically play when 50% visible for 100ms
- Auto-pause when scrolled away: Saves bandwidth and battery
- Manual controls: Tap to play/pause with visual feedback
- Loading states: Smooth loading indicators for better UX
Visibility Tracking
const viewabilityConfig = {
itemVisiblePercentThreshold: 50, // 50% visible
minimumViewTime: 100, // for 100ms
};
Responsive Design
- Dynamic column width: Adapts to screen size changes
- Consistent spacing: 8px gaps maintained across all screen sizes
- Safe area handling: Proper insets for notched devices
š§ Development Scripts
# Development
npm start # Start Metro bundler
npm run android # Run Android app
npm run ios # Run iOS app
# Production
npm run release # Build Android release APK
npm run clean # Clean Android build cache
š± Supported Platforms
- iOS: 13.0+
- Android: API level 21+ (Android 5.0)
š¤ Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
š License
This project is licensed under the MIT License.
š Related Resources
What our users say
No reviews yet. Be the first to review this module!
Module Information
Repository
View on GitHubLive Preview
View Live DemoTech Stack
Technologies used in this module