React Native UI Scaling Utility
react-native-size-matters is a lightweight utility library for React Native designed to simplify the scaling of UI elements across various device screen sizes. It helps developers avoid manually adjusting layouts for different screen dimensions by providing a set of robust scaling functions (e.g., `scale`, `verticalScale`, `moderateScale`, `moderateVerticalScale`) and a `ScaledSheet` API that automatically processes style annotations. The library is currently stable at version `0.4.2`, with recent minor updates suggesting an active development and maintenance cadence. Its key differentiators include being lightweight with zero external dependencies beyond `react-native` itself, and offering flexible scaling options, including linear and moderate scaling with adjustable factors. It promotes a "develop once" approach, aiming for consistent UI appearance starting from a standard ~5-inch mobile device.
Common errors
-
Module not found: Can't resolve 'react-native-dotenv' in ...
cause This error typically occurs after upgrading to `react-native-size-matters@0.4.0` or higher, where the configuration for custom guideline sizes switched from `react-native-dotenv` to `babel-plugin-dotenv-import`.fixRemove `react-native-dotenv` from your project and replace its usage in your Babel configuration with `babel-plugin-dotenv-import`. Refer to the `react-native-size-matters` documentation for the correct setup of `babel-plugin-dotenv-import`. -
Type 'string' is not assignable to type 'number' in JSX attribute 'style'.
cause This TypeScript error indicates you might be passing a string value (e.g., `'10@s'`) to a style property that expects a number, without using `ScaledSheet.create`. It can also occur in older versions (<0.1.4) even with `ScaledSheet` due to type inference issues.fixEnsure you are wrapping your style definitions with `ScaledSheet.create({})` when using string-based scaling annotations (e.g., `'10@s'`). If the error persists, especially with older versions, upgrade `react-native-size-matters` to `v0.1.4` or higher. -
Invariant Violation: `style` prop value must be an object.
cause This runtime error often means that you've attempted to use `ScaledSheet`'s annotation syntax directly within a `StyleSheet.create` call, or you've forgotten to wrap your style object with `ScaledSheet.create()` altogether.fixAlways use `const styles = ScaledSheet.create({ /* ... */ })` when defining styles that include scaling annotations like `'10@s'`. Do not try to apply the annotations within a standard `StyleSheet.create` call.
Warnings
- breaking Version `0.4.0` introduced a breaking change for configuring "Changing the Default Guideline Sizes". The environment library used for this configuration was switched from `react-native-dotenv` to `babel-plugin-dotenv-import`.
- gotcha Prior to `v0.4.1`, there were issues where certain style values provided as strings could lead to errors or unexpected behavior. This was addressed in `v0.4.1`.
- gotcha In versions prior to `0.1.4`, some styles caused TypeScript errors when provided with string values, particularly if not correctly interpreted by the scaling logic.
Install
-
npm install react-native-size-matters -
yarn add react-native-size-matters -
pnpm add react-native-size-matters
Imports
- scale, verticalScale, moderateScale
import scale from 'react-native-size-matters'; // Or for CJS (less common in modern RN): const scale = require('react-native-size-matters').scale;import { scale, verticalScale, moderateScale } from 'react-native-size-matters'; - ScaledSheet
import ScaledSheet from 'react-native-size-matters';
import { ScaledSheet } from 'react-native-size-matters'; - All exports (CommonJS)
const { scale, verticalScale, ScaledSheet } = require('react-native-size-matters');
Quickstart
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { scale, verticalScale, moderateScale, ScaledSheet } from 'react-native-size-matters';
const App = () => {
return (
<View style={styles.container}>
<Text style={styles.scaledText}>Scaled Text (Width based: 20@s)</Text>
<View style={styles.box}>
<Text style={styles.boxText}>Box</Text>
</View>
<Text style={{ fontSize: moderateScale(16, 0.3), marginTop: verticalScale(10) }}>
Moderately Scaled Text
</Text>
<Text style={rawStyles.normalText}>Normal Text (No Scaling)</Text>
</View>
);
};
const rawStyles = StyleSheet.create({
normalText: {
fontSize: 16,
color: '#666',
marginTop: 20
}
});
const styles = ScaledSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
padding: '20@ms'
},
scaledText: {
fontSize: '20@s',
color: '#333',
marginBottom: '10@vs'
},
box: {
width: '150@s',
height: '100@vs',
backgroundColor: 'lightblue',
justifyContent: 'center',
alignItems: 'center',
borderRadius: '8@ms0.3',
marginVertical: '20@vs'
},
boxText: {
fontSize: '18@ms',
color: 'darkblue'
}
});
export default App;