A comprehensive utility to scale sizes, fonts, spacing, radius, and layout based on device screen dimensions with advanced accessibility support and pixel-perfect rendering. Built to match your Figma design on any screen size while respecting user preferences.
Use any package manager:
# npm
npm install @shayrn/react-native-scaler
# yarn
yarn add @shayrn/react-native-scaler
# pnpm
pnpm add @shayrn/react-native-scaler
# bun
bun add @shayrn/react-native-scaler
#expo
npx expo install @shayrn/react-native-scaler
If your Figma design uses different base dimensions than 402x874
, configure it like this:
import { configureScaler } from '@shayrn/react-native-scaler';
configureScaler({
referenceWidth: 390,
referenceHeight: 844,
});
Call this once before using any scaling functionsβtypically in your root file (App.tsx
or _layout.tsx
).
import { scale } from '@shayrn/react-native-scaler';
const padding = scale(16); // Basic scaling
const constrainedPadding = scale(16, { min: 12, max: 24 }); // With constraints
const widthBasedPadding = scale(16, { useUniform: false }); // Width-based scaling
import { scaleFont } from '@shayrn/react-native-scaler';
const fontSize = scaleFont(14); // Respects accessibility settings
const constrainedFont = scaleFont(14, { min: 12, max: 18 }); // With min/max
const normalizedFont = scaleFont(14, { respectAccessibility: false }); // Ignore user settings
import { scaleLineHeight } from '@shayrn/react-native-scaler';
const lineHeight = scaleLineHeight(20);
const constrainedLineHeight = scaleLineHeight(20, { min: 16, max: 28 });
import { scaleWidth, scaleHeight } from '@shayrn/react-native-scaler';
const cardWidth = scaleWidth(300);
const cardHeight = scaleHeight(200, { min: 150, max: 250 });
import { scaleRadius } from '@shayrn/react-native-scaler';
const borderRadius = scaleRadius(12);
const constrainedRadius = scaleRadius(12, { min: 8, max: 16 });
Quick access utility with advanced options:
import { responsive } from '@shayrn/react-native-scaler';
const styles = {
container: {
padding: responsive.adaptiveSpacing(16), // Adapts to device type
margin: responsive.spacing(20, { min: 16, max: 24 }),
borderRadius: responsive.radius(8, { min: 4, max: 16 }),
gap: responsive.spacing(10),
},
text: {
fontSize: responsive.font(14, { min: 12, max: 18 }),
lineHeight: responsive.lineHeight(20, { min: 16, max: 24 }),
},
pixelPerfectBorder: {
borderWidth: responsive.pixelPerfect(1), // Pixel-perfect rendering
},
};
import { deviceInfo } from '@shayrn/react-native-scaler';
console.log(deviceInfo.isTablet); // true/false
console.log(deviceInfo.isSmallDevice); // true/false
console.log(deviceInfo.pixelRatio); // 2.0, 3.0, etc.
console.log(deviceInfo.fontScale); // User's accessibility font scale
console.log(deviceInfo.aspectRatio); // Screen aspect ratio
import { responsive, deviceInfo } from '@shayrn/react-native-scaler';
const adaptiveStyles = {
// Different styles for tablets vs phones
title: {
fontSize: deviceInfo.isTablet ? responsive.font(24) : responsive.font(18),
lineHeight: deviceInfo.isTablet ? responsive.lineHeight(32) : responsive.lineHeight(24),
},
// Adaptive spacing
container: {
padding: responsive.adaptiveSpacing(16), // Auto-adjusts for device type
},
};
import { onOrientationChange } from '@shayrn/react-native-scaler';
const subscription = onOrientationChange(() => {
// Recalculates all scales automatically
console.log('Screen orientation changed');
});
// Clean up when component unmounts
subscription?.remove();
import { responsive, getPixelSize } from '@shayrn/react-native-scaler';
const styles = {
// Ensures crisp 1px borders on all devices
separator: {
height: responsive.pixelPerfect(1),
backgroundColor: '#E0E0E0',
},
// Alternative method
border: {
borderWidth: getPixelSize(1),
},
};
import { responsive, deviceInfo, onOrientationChange } from '@shayrn/react-native-scaler';
import { View, Text, useEffect } from 'react-native';
export function EnhancedCard() {
useEffect(() => {
const subscription = onOrientationChange(() => {
// Handle orientation changes
console.log('Orientation changed, scales recalculated');
});
return () => subscription?.remove();
}, []);
return (
<View style={{
padding: responsive.adaptiveSpacing(16),
margin: responsive.spacing(12, { min: 8, max: 20 }),
borderRadius: responsive.radius(12, { min: 8, max: 16 }),
borderWidth: responsive.pixelPerfect(1),
borderColor: '#E0E0E0',
}}>
<Text style={{
fontSize: responsive.font(16, {
min: 14,
max: deviceInfo.isTablet ? 20 : 18,
respectAccessibility: true
}),
lineHeight: responsive.lineHeight(24, { min: 18, max: 28 }),
marginBottom: responsive.spacing(8),
}}>
Enhanced Scaled Content
</Text>
<Text style={{
fontSize: responsive.font(14, { min: 12, max: 16 }),
lineHeight: responsive.lineHeight(20, { min: 16, max: 22 }),
color: '#666',
}}>
This text adapts to screen size, respects accessibility settings,
and maintains pixel-perfect rendering across all devices.
</Text>
</View>
);
}
Access current scale factors for debugging or advanced usage:
import { scales, screenWidth, screenHeight } from '@shayrn/react-native-scaler';
console.log('Screen dimensions:', screenWidth, 'x', screenHeight);
console.log('Width scale:', scales.width);
console.log('Height scale:', scales.height);
console.log('Uniform scale:', scales.uniform);
console.log('Pixel ratio:', scales.pixel);
console.log('Font scale:', scales.font);
import { responsiveStyles } from '@shayrn/react-native-scaler';
// Use pre-configured responsive styles
const MyComponent = () => (
<View style={responsiveStyles.container}>
<Text style={responsiveStyles.text}>Standard text</Text>
<Text style={responsiveStyles.adaptiveText}>Adaptive text</Text>
</View>
);
- Width:
402
- Height:
874
- You can override these via
configureScaler()
.
- β iOS (full support with platform-specific optimizations)
- β Android (full support with platform-specific optimizations)
- β Tablets and phones
- β High-density displays (Retina, AMOLED)
- β Accessibility settings (font scaling, text size)
- β Orientation changes
- Matches your Figma design on any screen size
- Respects user accessibility settings (font scaling, text size)
- Pixel-perfect rendering for crisp UI elements
- Device-aware scaling (tablets vs phones vs small devices)
- Orientation support with automatic recalculation
- Constraint system prevents extreme scaling
- TypeScript support with full type definitions
- Performance optimized with efficient calculations
- Future-proof with comprehensive React Native PixelRatio API usage
If you're upgrading from the basic version:
- No breaking changes - all existing functions work as before
- Enhanced options - add optional parameters for constraints and accessibility
- New utilities - use
deviceInfo
,responsive.adaptiveSpacing()
, etc. - Better defaults - fonts now respect accessibility settings by default
// v1.x (still works)
fontSize: responsive.font(14)
// v2.x (enhanced)
fontSize: responsive.font(14, { min: 12, max: 18, respectAccessibility: true })
scale(size, options?)
- Universal scaling with constraintsscaleFont(size, options?)
- Font scaling with accessibility supportscaleLineHeight(size, options?)
- Line height scalingscaleRadius(size, options?)
- Border radius scalingscaleWidth(size, options?)
- Width-based scalingscaleHeight(size, options?)
- Height-based scaling
responsive.*
- Quick access helper objectdeviceInfo.*
- Device information and capabilitiesgetPixelSize(size)
- Pixel-perfect size calculationonOrientationChange(callback)
- Orientation change handlerconfigureScaler(config)
- Configure reference dimensions
screenWidth
,screenHeight
- Device dimensionsscales.*
- Current scale factorsresponsiveStyles.*
- Pre-built responsive styles