How to Create Custom Wavy Headers with React Native SVG
Note: This tutorial was published in 2020.
The
react-native-svgand Expo ecosystem have evolved. While the core concepts of using SVG paths remain the same, the specific installation and setup steps may have changed. Always refer to the officialreact-native-svgdocumentation for the most up-to-date practices.
The react-native-svg library provides comprehensive SVG support for React Native applications, allowing developers to create resolution-independent graphics and intricate designs. Unlike raster image formats (like PNG or JPEG), SVGs are vector-based, meaning they can be scaled indefinitely without any loss of quality. This makes them an ideal choice for creating dynamic and responsive UI elements.
This tutorial demonstrates how to use react-native-svg within an Expo application to build a custom, reusable wavy header component.
Requirements
Ensure your development environment includes the following:
- Node.js (version 12.x.x or higher)
expo-cliinstalled globally or accessible vianpx
Installing react-native-svg
Start by creating a new project using expo-cli. Once the project is generated, navigate into the directory and install the react-native-svg library.
expo init custom-wavy-header
cd custom-wavy-header
expo install react-native-svg
Using expo install ensures you get a version of the library that is compatible with your project's Expo SDK version.
Creating a Basic Screen
First, create a simple screen component at src/screens/ScreenOne.js. This will serve as the container for our custom header.
// src/screens/ScreenOne.js
import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
export default function ScreenOne() {
return (
<View style={styles.container}>
<View style={styles.headerContainer}>
<Text style={styles.headerText}>Custom Header</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#fff' },
headerContainer: { marginTop: 50, marginHorizontal: 10 },
headerText: {
fontSize: 30,
fontWeight: 'bold',
color: '#333',
textAlign: 'center',
marginTop: 35
}
});
Render this component in your main App.js file to see the initial output.
Creating the Wavy Header Component
The wavy effect will be created using an SVG Path component. A Path is an outline of a shape that can be filled or stroked, defined by a series of commands.
To easily generate complex wave patterns, you can use a web tool like getwaves.io. This tool provides the SVG path data (d attribute) that you can copy and use directly in your component.
Create a new file src/components/WavyHeader.js. This component will render the SVG background.
// src/components/WavyHeader.js
import React from 'react';
import { View } from 'react-native';
import Svg, { Path } from 'react-native-svg';
export default function WavyHeader({ customStyles }) {
return (
<View style={customStyles}>
<View style={{ backgroundColor: '#5000ca', height: 160 }}>
<Svg
height="60%"
width="100%"
viewBox="0 0 1440 320"
style={{ position: 'absolute', top: 130 }}
>
<Path
fill="#5000ca"
d="M0,96L48,112C96,128,192,160,288,186.7C384,213,480,235,576,213.3C672,192,768,128,864,128C960,128,1056,192,1152,208C1248,224,1344,192,1392,176L1440,160L1440,0L1392,0C1344,0,1248,0,1152,0C1056,0,960,0,864,0C768,0,672,0,576,0C480,0,384,0,288,0C192,0,96,0,48,0L0,0Z"
/>
</Svg>
</View>
</View>
);
}
Now, import and use this WavyHeader component in ScreenOne.js.
// src/screens/ScreenOne.js
import { Dimensions } from 'react-native';
import WavyHeader from '../components/WavyHeader';
// ...
export default function ScreenOne() {
return (
<View style={styles.container}>
<WavyHeader customStyles={styles.svgCurve} />
<View style={styles.headerContainer}>
<Text style={styles.headerText}>Custom Header</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
// ... other styles
svgCurve: {
position: 'absolute',
width: Dimensions.get('window').width
},
headerText: {
// ...
color: '#fff', // Change color to be visible on the new background
}
});
The position: 'absolute' style ensures that the SVG background sits behind the header text content.

Making the Header Component Reusable
To make the WavyHeader component reusable, we can parameterize its properties by passing them as props. Modify WavyHeader.js to accept props for the background color, height, and SVG path data.
// src/components/WavyHeader.js
export default function WavyHeader({
customStyles,
customHeight,
customTop,
customBgColor,
customWavePattern
}) {
return (
<View style={customStyles}>
<View style={{ backgroundColor: customBgColor, height: customHeight }}>
<Svg
height="60%"
width="100%"
viewBox="0 0 1440 320"
style={{ position: 'absolute', top: customTop }}
>
<Path fill={customBgColor} d={customWavePattern} />
</Svg>
</View>
</View>
);
}
Now, you can pass different values from any screen component to create unique header designs.
// src/screens/ScreenOne.js
<WavyHeader
customStyles={styles.svgCurve}
customHeight={160}
customTop={130}
customBgColor="#5000ca"
customWavePattern="M0,96L48,112C96,128,192,160,288,186.7..."
/>
Conclusion
This tutorial demonstrated how to create a reusable, customizable header component with SVG waves using the react-native-svg library. By parameterizing properties such as color, height, and the SVG path itself, you can easily create a variety of unique designs for different screens in your application. This approach highlights the power of SVG for creating dynamic and visually appealing user interfaces in React Native.
The complete source code for this project can be found at this GitHub repository.