React Native QR Code SVG Generator
react-native-qrcode-svg is an actively maintained library for generating QR codes directly within React Native applications. It leverages `react-native-svg` for efficient vector-based rendering and `javascript-qrcode` (or `node-qrcode` since v5.0.0) for the underlying QR matrix generation. The current stable version is 6.3.21, with a release cadence that indicates active development and feature enhancements, as seen in recent updates like v6.1.1 and v5.2.0. This package differentiates itself by offering features specific to mobile UI, such as embedding custom logos (from base64 strings or local files), supporting linear gradients for QR code styling, and providing an API to extract the QR code as a base64 Data URL. It is a robust solution for integrating scannable QR codes directly into React Native projects, without relying on webviews or complex native modules beyond `react-native-svg`.
Common errors
-
Invariant Violation: requireNativeComponent: "RNSVGPath" was not found in the UIManager.
cause This error typically indicates that `react-native-svg`'s native modules are not correctly linked or installed for your project's platform.fixFor React Native 0.60+ (iOS): navigate to your `ios` directory and run `pod install`. For Android: ensure `new SvgPackage()` is added to `MainApplication.java`. For React Native <= 0.59: run `react-native link react-native-svg`. -
Error: Value too big for QR code.
cause The input `value` string or data array is too large to be encoded into a QR code with the current `size` and `ecl` (Error Correction Level) settings. Higher error correction levels reduce the data capacity.fixTry reducing the length of the `value` string, increasing the `size` prop of the `QRCode` component, or lowering the `ecl` prop (e.g., from 'H' to 'M' or 'L'). -
TypeError: Cannot read property 'toDataURL' of null
cause This usually happens when you try to call `this.svg.toDataURL()` before the `QRCode` component has mounted and assigned its ref, or if the ref assignment failed.fixEnsure that the `getRef` prop correctly assigns the component instance (e.g., `getRef={(c) => (this.svg = c)}`). If calling `toDataURL` in a function, add a check `if (this.svg)` before calling the method. For functional components, use `useRef` and ensure the ref is assigned to a mutable object.
Warnings
- breaking Version 5.0.0 changed the underlying matrix generator from `javascript-qrcode` to `node-qrcode`. While generally compatible, this could subtly alter QR code output for specific inputs or introduce different error correction behaviors. Always test thoroughly after upgrading to v5.x or higher.
- breaking Peer dependency `react-native-svg` has had significant minimum version bumps (e.g., to `^6.5.2` and then `>=14.0.0`). Running with an older version of `react-native-svg` will likely result in runtime errors or compilation failures due to incompatible APIs or missing features.
- gotcha The `logoBorderRadius` prop for rounding the logo corners is currently only supported on iOS. On Android, the logo will render without rounded corners.
- gotcha The `toDataURL` method, used to get a base64 string of the QR code, currently does not include the embedded logo in the generated image. Only the QR code matrix is captured.
Install
-
npm install react-native-qrcode-svg -
yarn add react-native-qrcode-svg -
pnpm add react-native-qrcode-svg
Imports
- QRCode
const QRCode = require('react-native-qrcode-svg');import QRCode from 'react-native-qrcode-svg';
- QRCodeProps
import { QRCodeProps } from 'react-native-qrcode-svg';import type { QRCodeProps } from 'react-native-qrcode-svg'; - toDataURL callback
svgRef.toDataURL((dataURL: string) => { /* handle dataURL */ });
Quickstart
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, Alert, StyleSheet } from 'react-native';
import QRCode from 'react-native-qrcode-svg';
class QRCodeGenerator extends Component {
constructor(props) {
super(props);
this.state = {
qrValue: 'https://checklist.day/example-qr-code',
dataURL: '',
};
this.svg = null; // Ref to the QRCode component
}
// Callback for when the data URL is generated
callback = (dataURL) => {
console.log('Generated Data URL (first 100 chars):', dataURL.substring(0, 100) + '...');
this.setState({ dataURL });
Alert.alert('QR Code Data URL Generated', 'Check console for base64 string.');
};
// Function to trigger data URL generation
generateDataURL = () => {
if (this.svg) {
// The toDataURL method does not include the logo by default.
this.svg.toDataURL(this.callback);
} else {
Alert.alert('Error', 'QR Code ref not available. Ensure component is mounted.');
}
};
render() {
// For a local image, ensure the path is correct, e.g., require('../assets/logo.png');
// For this example, we'll use a placeholder for `logo` prop
const logoPlaceholder = { uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=' }; // Tiny transparent base64 image
return (
<View style={styles.container}>
<Text style={styles.title}>Dynamic QR Code Example</Text>
<QRCode
value={this.state.qrValue}
size={250}
color="#003366"
backgroundColor="#F0F8FF"
enableLinearGradient={true}
linearGradient={['#0000FF', '#ADD8E6']}
gradientDirection={[0, 0, 1, 1]}
logo={logoPlaceholder}
logoSize={50}
logoBorderRadius={10}
logoBackgroundColor="transparent"
quietZone={10}
ecl="H"
getRef={(c) => (this.svg = c)}
onError={(error) => console.error('QR Code rendering error:', error)}
/>
<TouchableOpacity
onPress={this.generateDataURL}
style={styles.button}>
<Text style={styles.buttonText}>Get QR Code Data URL</Text>
</TouchableOpacity>
{this.state.dataURL ? (
<Text style={styles.dataUrlStatus}>
Data URL generated (check console for full string).
</Text>
) : null}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: '#fff',
},
title: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 25,
color: '#333',
},
button: {
marginTop: 30,
paddingVertical: 12,
paddingHorizontal: 25,
backgroundColor: '#007bff',
borderRadius: 8,
elevation: 2,
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: '600',
},
dataUrlStatus: {
marginTop: 20,
fontSize: 14,
color: '#555',
textAlign: 'center',
},
});
export default QRCodeGenerator;