A production-ready React Native package for your app
npm install akshay-khapare-react-native-responsive-size

A production-ready React Native package for creating responsive UIs across all device sizes. This package provides a comprehensive, efficient API to handle responsive sizing, with built-in caching for performance optimization and full TypeScript support.
- ๐ฏ Complete Responsive Solution: 15 functions covering all responsive design needs
- ๐ฑ Universal Device Support: Works seamlessly on phones, tablets, and all screen sizes
- ๐ Performance Optimized: Smart caching system with automatic memory management
- ๐ Auto Orientation Handling: Automatically adapts to orientation changes
- ๐ก๏ธ Safe Area Ready: Built-in support for notches, status bars, and home indicators
- ๐ Device Intelligence: Advanced device detection and categorization
- ๐จ Automatic Style Processing: Transform entire style objects with one function
- ๐ TypeScript Native: Fully typed for complete developer safety
- ๐งน Memory Safe: Automatic cleanup prevents memory leaks
---
``bash`
npm install akshay-khapare-react-native-responsive-size
`bash`These are likely already in your React Native project
npm install react react-native
`tsx
import {
scale,
wp,
hp,
fs,
spacing,
radius,
getSafeAreaTop,
getSafeAreaBottom,
} from 'akshay-khapare-react-native-responsive-size';
const styles = StyleSheet.create({
container: {
width: wp(100), // 100% width
height: hp(100), // 100% height
paddingTop: getSafeAreaTop(), // Safe for notches
padding: spacing(16), // Responsive padding
},
title: {
fontSize: fs(24), // Responsive font
marginBottom: spacing(12), // Responsive margin
},
button: {
height: scale(44), // Responsive height
borderRadius: radius(8), // Responsive radius
},
});
`
---
| Function | Purpose | Best For |
| -------------------------- | -------------------------- | --------------------------------- |
| scale() | Main responsive scaling | Button heights, icons, borders |wp()
| | Width percentage | Container widths, cards, columns |hp()
| | Height percentage | Headers, modals, sections |fs()
| | Font size with constraints | All text with min/max limits |spacing()
| | Padding & margin | All spacing between elements |radius()
| | Border radius | Rounded corners, circles |getSafeAreaTop()
| | Top safe area | Header padding for notches |getSafeAreaBottom()
| | Bottom safe area | Footer padding for home indicator |getScreenDimensions()
| | Screen info | Layout calculations |isTablet()
| | Tablet detection | Device-specific layouts |getDeviceSize()
| | Device category | Granular responsive design |responsiveSize()
| | Device-specific values | Different sizes per device type |createResponsiveStyles()
| | Auto-process styles | Batch style transformation |getCacheStats()
| | Performance monitoring | Debug & optimization |cleanup()
| | Memory cleanup | App lifecycle management |
---
๐ฏ Core Scaling Functions
#### scale(size: number, useWidth?: boolean): number
Purpose: The main responsive function that scales any value proportionally.
Parameters:
- size: Base size in pixels (designed for iPhone 12 Pro: 390x844)useWidth
- : Optional. Use width for scaling instead of height
When to use:
- Scaling button heights, image sizes, icon dimensions
- Any UI element that should grow/shrink with screen size
- When you want consistent proportions across all devices
Use Cases:
`tsx
// โ
Good use cases
scale(44); // Button height
scale(24); // Icon size
scale(100); // Image width/height
scale(2); // Border width
scale(50, true); // Scale based on width instead of height
// โ Avoid for
scale(16); // Font size (use fs() instead)
scale(20); // Padding (use spacing() instead)
`
Real Examples:
`tsx`
const styles = StyleSheet.create({
avatar: {
width: scale(60),
height: scale(60),
borderRadius: scale(30),
},
iconButton: {
width: scale(44),
height: scale(44),
},
progressBar: {
height: scale(4),
borderRadius: scale(2),
},
});
---
#### wp(percentage: number): number
Purpose: Converts width percentage to pixels.
When to use:
- Container widths, card widths, grid columns
- When you think in percentages: "I want this 80% wide"
- Creating responsive layouts without flexbox
Use Cases:
`tsx
// โ
Perfect for
wp(90); // Card that's 90% of screen width
wp(48); // Two columns with 48% each (+ 4% gap)
wp(100); // Full width container
// โ Don't use for
wp(1); // Very small values (use scale() instead)
`
Real Examples:
`tsx`
const styles = StyleSheet.create({
card: {
width: wp(90), // 90% width card
alignSelf: 'center',
},
twoColumnItem: {
width: wp(48), // Two items per row
},
threeColumnItem: {
width: wp(30), // Three items per row
},
fullWidthHeader: {
width: wp(100), // Full width
},
});
---
#### hp(percentage: number): number
Purpose: Converts height percentage to pixels.
When to use:
- Header heights, modal heights, section heights
- When you want consistent height ratios
- Creating layouts that adapt to screen height
Use Cases:
`tsx
// โ
Great for
hp(10); // Header that's 10% of screen height
hp(80); // Modal that takes 80% of screen
hp(25); // Four equal sections
// โ Avoid for
hp(1); // Very small values (use scale() instead)
`
Real Examples:
`tsx`
const styles = StyleSheet.create({
header: {
height: hp(12), // 12% screen height
},
heroSection: {
height: hp(40), // 40% for hero image
},
bottomSheet: {
height: hp(60), // 60% modal height
},
tabBar: {
height: hp(8), // 8% for tab navigation
},
});
๐ Typography & Spacing Functions
#### fs(size: number, minSize?: number, maxSize?: number): number
Purpose: Responsive font size with minimum/maximum constraints for accessibility.
Parameters:
- size: Base font sizeminSize
- : Optional minimum font sizemaxSize
- : Optional maximum font size
When to use:
- All text elements where you want responsive sizing
- When you need to ensure readability on all devices
- Accessibility compliance with font size limits
Use Cases:
`tsx
// โ
Essential for
fs(16); // Body text
fs(24, 20, 28); // Heading with min/max limits
fs(12, 10); // Small text with minimum size
fs(32, undefined, 36); // Large title with max limit
// โ Don't use for
fs(44); // Large UI elements (use scale() instead)
`
Real Examples:
`tsx`
const styles = StyleSheet.create({
heading: {
fontSize: fs(28, 24, 32), // Never smaller than 24, max 32
},
bodyText: {
fontSize: fs(16, 14), // Never smaller than 14
},
caption: {
fontSize: fs(12, 10, 14), // Between 10-14
},
largeTitle: {
fontSize: fs(34, 28, 40), // Large but limited
},
});
---
#### spacing(size: number): number
Purpose: Responsive spacing for padding and margins.
When to use:
- All padding and margin values
- Consistent spacing system across your app
- When elements need to breathe more/less on different screens
Use Cases:
`tsx
// โ
Perfect for
spacing(16); // Standard padding
spacing(8); // Small margins
spacing(24); // Large padding
spacing(4); // Tight spacing
// โ Avoid for
spacing(100); // Large distances (use scale() or hp()/wp())
`
Real Examples:
`tsx`
const styles = StyleSheet.create({
container: {
padding: spacing(16),
marginBottom: spacing(20),
},
card: {
margin: spacing(12),
padding: spacing(16),
},
buttonGroup: {
gap: spacing(8), // React Native 0.71+
},
section: {
marginVertical: spacing(24),
paddingHorizontal: spacing(16),
},
});
---
#### radius(size: number): number
Purpose: Responsive border radius for consistent rounded corners.
When to use:
- All border radius values
- Buttons, cards, images, input fields
- Maintaining visual consistency across screen sizes
Use Cases:
`tsx
// โ
Ideal for
radius(8); // Standard button radius
radius(12); // Card corners
radius(50); // Circular elements (with equal width/height)
radius(4); // Small input corners
// โ Avoid for
radius(0); // No radius (just use 0)
`
Real Examples:
`tsx`
const styles = StyleSheet.create({
button: {
borderRadius: radius(8),
},
card: {
borderRadius: radius(12),
},
avatar: {
width: scale(60),
height: scale(60),
borderRadius: radius(30), // Perfect circle
},
input: {
borderRadius: radius(6),
},
});
๐ก๏ธ Safe Area Functions
#### getSafeAreaTop(): number
Purpose: Get safe area top padding with accurate device detection for notches and status bars.
When to use:
- Header components that need to avoid status bar/notch
- Fixed positioned elements at the top
- Full-screen modals or overlays
Device Handling:
- iOS: Detects notch devices (iPhone X+) vs older devices
- Android: Uses StatusBar.currentHeight with fallback
- Landscape: Returns 0 on iOS landscape mode
Use Cases:
`tsx
// โ
Essential for
paddingTop: getSafeAreaTop(); // Headers
top: getSafeAreaTop(); // Fixed positioned elements
marginTop: getSafeAreaTop(); // Full-screen content
// โ Don't add to
// Normal screen content (StatusBar handles this automatically)
`
Real Examples:
`tsx`
const styles = StyleSheet.create({
header: {
paddingTop: getSafeAreaTop(),
height: scale(60) + getSafeAreaTop(),
backgroundColor: '#007AFF',
},
overlay: {
position: 'absolute',
top: getSafeAreaTop(),
left: 0,
right: 0,
},
fullScreenModal: {
flex: 1,
paddingTop: getSafeAreaTop(),
},
});
---
#### getSafeAreaBottom(): number
Purpose: Get safe area bottom padding for home indicator on newer devices.
When to use:
- Tab bars, bottom navigation
- Fixed positioned elements at the bottom
- Modals with bottom buttons
- Any content that should clear the home indicator
Device Handling:
- iPhone X+ Portrait: Returns 34 for home indicator
- iPhone X+ Landscape: Returns 21 for side home indicator
- Older devices: Returns 0
- Android: Returns 0 (handled by system)
Use Cases:
`tsx
// โ
Critical for
paddingBottom: getSafeAreaBottom(); // Tab bars
bottom: getSafeAreaBottom(); // Fixed bottom elements
marginBottom: getSafeAreaBottom(); // Bottom content
// โ Don't add to
// Mid-screen content
`
Real Examples:
`tsx`
const styles = StyleSheet.create({
tabBar: {
paddingBottom: getSafeAreaBottom(),
height: scale(60) + getSafeAreaBottom(),
},
bottomButton: {
position: 'absolute',
bottom: spacing(16) + getSafeAreaBottom(),
left: spacing(16),
right: spacing(16),
},
modalFooter: {
paddingBottom: spacing(16) + getSafeAreaBottom(),
},
});
๐ฑ Device Detection Functions
#### getScreenDimensions(): object
Purpose: Get current screen dimensions with additional device characteristics.
Returns:
`tsx`
{
width: number;
height: number;
isLandscape: boolean;
aspectRatio: number;
diagonal: number;
}
When to use:
- Complex layout calculations
- Custom responsive logic
- Orientation-specific layouts
- Performance monitoring
Use Cases:
`tsx
// โ
Useful for
const { width, isLandscape } = getScreenDimensions();
const { aspectRatio } = getScreenDimensions(); // Layout decisions
const { diagonal } = getScreenDimensions(); // Size categorization
// โ Avoid for
// Simple responsive sizing (use scale/wp/hp instead)
`
Real Examples:
`tsx
import { getScreenDimensions } from 'akshay-khapare-react-native-responsive-size';
const CustomComponent = () => {
const { width, height, isLandscape, aspectRatio } = getScreenDimensions();
const dynamicStyle = {
flexDirection: isLandscape ? 'row' : 'column',
aspectRatio: aspectRatio > 2 ? 1.5 : 1.2, // Adjust for very tall screens
};
return
};
`
---
#### isTablet(): boolean
Purpose: Enhanced tablet detection with multiple criteria for better accuracy.
Detection Logic:
- Aspect ratio < 1.8 (tablets are less elongated)
- Minimum dimension โฅ 600px
- Diagonal size consideration
- Multiple criteria prevent false positives
When to use:
- Showing different layouts for tablets vs phones
- Conditional rendering based on device type
- Adjusting grid columns or navigation patterns
Use Cases:
`tsx
// โ
Perfect for
const columns = isTablet() ? 3 : 2; // Grid columns
const showSidebar = isTablet(); // Tablet-specific UI
const fontSize = isTablet() ? 18 : 16; // Different base sizes
// โ Avoid for
// Fine-grained responsive sizing (use scale() instead)
`
Real Examples:
`tsx`
const styles = StyleSheet.create({
container: {
flexDirection: isTablet() ? 'row' : 'column',
},
gridItem: {
width: isTablet() ? wp(30) : wp(48), // 3 vs 2 columns
},
modal: {
width: isTablet() ? wp(70) : wp(90), // Smaller modal on tablets
},
});
---
#### getDeviceSize(): 'small' | 'medium' | 'large' | 'tablet'
Purpose: Device size category for more granular responsive design.
Categories:
- 'small': Height < 700 (iPhone SE, etc.)'medium'
- : Height 700-850 (iPhone 12, 13, etc.)'large'
- : Height > 850 (iPhone 12 Pro Max, etc.)'tablet'
- : Detected as tablet device
When to use:
- Fine-tuned responsive design
- Different layouts for device categories
- Accessibility improvements for small screens
Use Cases:
`tsx
// โ
Excellent for
const deviceSize = getDeviceSize();
const padding = deviceSize === 'small' ? 12 : 16; // Less padding on small devices
const gridCols = deviceSize === 'tablet' ? 4 : 2; // More columns on tablets
// โ Don't use for
// Simple scaling (use scale() instead)
`
Real Examples:
`tsx
const getResponsiveStyles = () => {
const deviceSize = getDeviceSize();
return StyleSheet.create({
container: {
padding: deviceSize === 'small' ? spacing(12) : spacing(16),
},
grid: {
flexDirection: deviceSize === 'tablet' ? 'row' : 'column',
},
text: {
fontSize: {
small: fs(14),
medium: fs(16),
large: fs(18),
tablet: fs(20),
}[deviceSize],
},
});
};
`
๐ Advanced Functions
#### responsiveSize(phoneSize: number, tabletSize?: number, deviceSizes?: object): number
Purpose: Responsive value with device-specific scaling and custom sizes per device type.
Parameters:
- phoneSize: Base size for phonestabletSize
- : Optional size for tablets (defaults to phoneSize \* 0.8)deviceSizes
- : Optional custom sizes for each device category
When to use:
- When you need completely different values per device type
- Complex responsive designs with device-specific requirements
- Fine-tuning user experience per device category
Use Cases:
`tsx
// โ
Perfect for
responsiveSize(40); // Auto tablet adjustment
responsiveSize(40, 50); // Custom tablet size
responsiveSize(40, 50, { small: 35, large: 45 }); // Per-device customization
// โ Overkill for
// Simple proportional scaling (use scale() instead)
`
Real Examples:
`tsx`
const styles = StyleSheet.create({
button: {
height: responsiveSize(44, 52), // Taller buttons on tablets
},
avatar: {
width: responsiveSize(60, 80, {
small: 50, // Smaller on small phones
medium: 60, // Standard size
large: 70, // Larger on big phones
tablet: 90, // Much larger on tablets
}),
},
card: {
padding: responsiveSize(16, 24, {
small: 12, // Less padding on small screens
tablet: 32, // More padding on tablets
}),
},
});
---
#### createResponsiveStyles
Purpose: Create responsive styles object with automatic processing of numeric values.
Auto-Processing Rules:
- Properties with 'padding'/'margin'/'spacing' โ spacing()fs()
- Properties with 'fontSize'/'size' โ radius()
- Properties with 'radius'/'border' โ scale()
- Properties with 'width'/'height' โ
- Other numbers remain unchanged
- Nested objects are processed recursively
When to use:
- Processing entire style objects at once
- Reducing repetitive function calls
- Consistent responsive styling across components
Use Cases:
`tsx
// โ
Time-saving for
const baseStyles = {
padding: 16, // โ spacing(16)
fontSize: 18, // โ fs(18)
borderRadius: 8, // โ radius(8)
width: 100, // โ scale(100)
};
// โ Not needed for
// Single values or when you need specific functions
`
Real Examples:
`tsx
// Input styles
const baseStyles = {
container: {
padding: 16,
marginBottom: 20,
borderRadius: 12,
},
title: {
fontSize: 24,
marginBottom: 8,
},
button: {
height: 44,
paddingHorizontal: 20,
borderRadius: 8,
},
};
// Auto-processed output
const responsiveStyles = createResponsiveStyles(baseStyles);
// Result:
// {
// container: {
// padding: spacing(16),
// marginBottom: spacing(20),
// borderRadius: radius(12),
// },
// title: {
// fontSize: fs(24),
// marginBottom: spacing(8),
// },
// button: {
// height: scale(44),
// paddingHorizontal: spacing(20),
// borderRadius: radius(8),
// },
// }
`
โก Performance & Debugging Functions
#### getCacheStats(): { size: number; maxSize: number }
Purpose: Get cache statistics for performance monitoring and debugging.
Returns:
- size: Current number of cached valuesmaxSize
- : Maximum cache size (100 entries)
When to use:
- Performance debugging
- Memory usage monitoring
- Development/testing phases
- Optimization analysis
Use Cases:
`tsxCache: ${size}/${maxSize}
// โ
Useful for
const { size, maxSize } = getCacheStats();
console.log(); // Monitor cache usage
// โ Don't use in
// Production unless for performance monitoring
`
Real Examples:
`tsx
// Development helper
const PerformanceMonitor = () => {
const [cacheStats, setCacheStats] = useState(getCacheStats());
useEffect(() => {
const interval = setInterval(() => {
setCacheStats(getCacheStats());
}, 5000);
return () => clearInterval(interval);
}, []);
return __DEV__ ? (
Cache: {cacheStats.size}/{cacheStats.maxSize}
) : null;
};
// Performance logging
const logPerformance = () => {
const stats = getCacheStats();
console.log('Responsive Size Cache Stats:', stats);
if (stats.size === stats.maxSize) {
console.warn('Cache is full - consider monitoring usage patterns');
}
};
`
---
#### cleanup(): void
Purpose: Clean up resources and remove listeners to prevent memory leaks.
What it does:
- Removes dimension change listeners
- Clears the cache
- Prevents memory leaks
When to use:
- App unmounting/cleanup
- Memory optimization
- Testing teardown
- Development hot reloads
Use Cases:
`tsx
// โ
Essential for
useEffect(() => {
return () => cleanup(); // Component cleanup
}, []);
// App-level cleanup
AppState.addEventListener('change', (state) => {
if (state === 'background') cleanup();
});
// โ Don't call
// During normal app usage (it will re-initialize automatically)
`
Real Examples:
`tsx
// React component cleanup
const MyComponent = () => {
useEffect(() => {
return () => {
// Cleanup when component unmounts
cleanup();
};
}, []);
return
};
// App-level cleanup
const App = () => {
useEffect(() => {
const handleAppStateChange = (nextAppState: string) => {
if (nextAppState === 'background') {
cleanup(); // Clean up when app goes to background
}
};
const subscription = AppState.addEventListener(
'change',
handleAppStateChange
);
return () => {
subscription?.remove();
cleanup(); // Final cleanup
};
}, []);
return
};
// Test cleanup
afterEach(() => {
cleanup(); // Clean up between tests
});
`
---
๐ฑ Basic Responsive Layout
`tsx
import React from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import {
scale,
wp,
hp,
fs,
spacing,
radius,
getSafeAreaTop,
getSafeAreaBottom,
} from 'akshay-khapare-react-native-responsive-size';
const ResponsiveScreen = () => {
return (
This layout adapts to all screen sizes
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
header: {
height: scale(60) + getSafeAreaTop(),
paddingTop: getSafeAreaTop(),
backgroundColor: '#007AFF',
justifyContent: 'center',
alignItems: 'center',
},
headerTitle: {
fontSize: fs(20),
color: 'white',
fontWeight: 'bold',
},
content: {
flex: 1,
padding: spacing(16),
justifyContent: 'center',
},
card: {
backgroundColor: 'white',
padding: spacing(24),
borderRadius: radius(12),
width: wp(90),
alignSelf: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: scale(2) },
shadowOpacity: 0.1,
shadowRadius: radius(4),
elevation: scale(3),
},
cardTitle: {
fontSize: fs(28),
fontWeight: 'bold',
marginBottom: spacing(8),
textAlign: 'center',
},
cardSubtitle: {
fontSize: fs(16),
color: '#666',
textAlign: 'center',
marginBottom: spacing(24),
},
button: {
backgroundColor: '#007AFF',
height: scale(48),
borderRadius: radius(8),
justifyContent: 'center',
alignItems: 'center',
},
buttonText: {
color: 'white',
fontSize: fs(16),
fontWeight: '600',
},
footer: {
height: scale(50) + getSafeAreaBottom(),
paddingBottom: getSafeAreaBottom(),
backgroundColor: '#333',
justifyContent: 'center',
alignItems: 'center',
},
footerText: {
color: 'white',
fontSize: fs(14),
},
});
export default ResponsiveScreen;
`
๐ Auto-Processing Style Objects
`tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import {
createResponsiveStyles,
isTablet,
getDeviceSize,
} from 'akshay-khapare-react-native-responsive-size';
const AutoProcessingExample = () => {
// Define base styles with raw numbers
const baseStyles = {
container: {
padding: 16,
backgroundColor: '#fff',
},
header: {
height: 60,
marginBottom: 20,
paddingHorizontal: 16,
borderRadius: 8,
backgroundColor: '#007AFF',
},
title: {
fontSize: 24,
marginBottom: 8,
},
subtitle: {
fontSize: 16,
marginBottom: 16,
},
card: {
padding: 20,
marginBottom: 16,
borderRadius: 12,
backgroundColor: '#f9f9f9',
},
button: {
height: 44,
paddingHorizontal: 20,
borderRadius: 8,
backgroundColor: '#007AFF',
},
buttonText: {
fontSize: 16,
},
};
// Auto-process all numeric values
const styles = StyleSheet.create(createResponsiveStyles(baseStyles));
return (
Auto-Processed Layout
Device: {getDeviceSize()} {isTablet() && '(Tablet)'}
All numeric values in styles are automatically processed:
);
};
export default AutoProcessingExample;
`
๐ Device-Specific Layouts
`tsx
import React from 'react';
import { View, Text, ScrollView, StyleSheet } from 'react-native';
import {
wp,
hp,
fs,
spacing,
radius,
isTablet,
getDeviceSize,
responsiveSize,
getSafeAreaTop,
} from 'akshay-khapare-react-native-responsive-size';
const DeviceSpecificLayout = () => {
const deviceSize = getDeviceSize();
const tablet = isTablet();
// Device-specific configurations
const gridColumns = tablet ? 3 : 2;
const cardWidth = tablet ? wp(30) : wp(45);
const renderCard = (title: string, index: number) => (
);
return (
contentContainerStyle={styles.scrollContent}
>
Device: {deviceSize} {tablet && '(Tablet)'}
Button Height: {responsiveSize(44, 52)}px
{Array.from({ length: 6 }, (_, i) => renderCard(Card ${i + 1}, i))}
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f5f5f5',
},
scrollContent: {
paddingTop: getSafeAreaTop(),
padding: spacing(16),
},
header: {
backgroundColor: '#007AFF',
padding: spacing(20),
borderRadius: radius(12),
marginBottom: spacing(20),
},
headerTitle: {
fontSize: fs(24),
color: 'white',
fontWeight: 'bold',
textAlign: 'center',
},
headerSubtitle: {
fontSize: fs(16),
color: 'rgba(255,255,255,0.8)',
textAlign: 'center',
marginTop: spacing(8),
},
infoCard: {
backgroundColor: 'white',
padding: spacing(16),
borderRadius: radius(8),
marginBottom: spacing(20),
},
infoTitle: {
fontSize: fs(18),
fontWeight: 'bold',
marginBottom: spacing(8),
},
infoText: {
fontSize: fs(14),
color: '#666',
marginBottom: spacing(4),
},
sectionTitle: {
fontSize: fs(20),
fontWeight: 'bold',
marginBottom: spacing(16),
},
grid: {
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-between',
},
card: {
backgroundColor: 'white',
padding: spacing(16),
borderRadius: radius(8),
marginBottom: spacing(12),
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 2,
},
cardTitle: {
fontSize: fs(16),
fontWeight: 'bold',
marginBottom: spacing(8),
},
cardText: {
fontSize: fs(12),
color: '#666',
},
});
export default DeviceSpecificLayout;
`
---
- Use specific functions: fs() for fonts, spacing() for padding/margin, radius() for bordersgetSafeAreaTop()
- Implement safe areas: Always use and getSafeAreaBottom() for headers and footersisTablet()
- Test on multiple devices: Verify your layouts on different screen sizes
- Cache-friendly patterns: Reuse the same values to benefit from caching
- Device-specific optimizations: Use and getDeviceSize() for tailored experiences
- Don't mix units: Avoid mixing responsive functions with fixed pixel values
- Don't ignore safe areas: Never assume headers/footers work without safe area handling
- Don't over-optimize: Start with basic functions before using advanced features
- Don't forget cleanup: Call cleanup() when appropriate to prevent memory leaks
- Don't cache bust unnecessarily: Avoid random values that prevent cache hits
---
Layout not responsive on certain devices
Cause: Using fixed pixel values instead of responsive functions.
Solution:
`tsx
// โ Wrong
const styles = StyleSheet.create({
button: {
height: 44, // Fixed pixels
padding: 16, // Fixed pixels
},
});
// โ
Correct
const styles = StyleSheet.create({
button: {
height: scale(44), // Responsive
padding: spacing(16), // Responsive
},
});
`
Text too small/large on some devices
Cause: Not using font size constraints or wrong base size.
Solution:
`tsx
// โ Wrong
fontSize: scale(16), // Uses height scaling, not font scaling
// โ
Correct
fontSize: fs(16, 14, 20), // Font scaling with min/max limits
`
Content hidden behind notch/status bar
Cause: Not accounting for safe areas.
Solution:
`tsx
// โ Wrong
const styles = StyleSheet.create({
header: {
height: 60,
backgroundColor: '#007AFF',
},
});
// โ
Correct
const styles = StyleSheet.create({
header: {
height: scale(60) + getSafeAreaTop(),
paddingTop: getSafeAreaTop(),
backgroundColor: '#007AFF',
},
});
`
Performance issues with many calculations
Cause: Cache misses due to dynamic values or cache is full.
Solution:
`tsx
// Check cache performance
const stats = getCacheStats();
console.log('Cache usage:', stats);
// Ensure consistent values for better caching
const STANDARD_PADDING = 16;
const buttonPadding = spacing(STANDARD_PADDING); // Good for caching
// Clean up if needed
cleanup();
`
Inconsistent spacing across the app
Cause: Using different base values instead of a consistent spacing system.
Solution:
`tsx
// โ
Create a spacing scale
const SPACING = {
xs: 4,
sm: 8,
md: 16,
lg: 24,
xl: 32,
};
// Use consistently throughout the app
const styles = StyleSheet.create({
container: {
padding: spacing(SPACING.md),
marginBottom: spacing(SPACING.lg),
},
});
`
---
MIT License - see LICENSE file for details.
1. Fork the repository
2. Create your feature branch (git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature'
3. Commit your changes ()git push origin feature/amazing-feature`)
4. Push to the branch (
5. Open a Pull Request
- ๐ง Email: your-email@example.com
- ๐ Issues: GitHub Issues
- ๐ Documentation: GitHub Wiki
---
Made with โค๏ธ for the React Native community