---
title: React Native
pagination_prev: demos/frontend/index
pagination_next: demos/desktop/index
sidebar_position: 1
sidebar_custom_props:
  summary: React + Native Rendering
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
The [NodeJS Module](/docs/getting-started/installation/nodejs) can be imported
from the main `App.js` entrypoint or any script in the project.
The "Complete Example" creates an app that looks like the screenshots below:
  | iOS | Android | 
|  |  | 
## Native Libraries
:::warning
React Native does not provide a native file picker or a method for reading and
writing data from documents on the devices. A third-party library must be used.
Since React Native internals change between releases, libraries may only work
with specific versions of React Native.  Project documentation should be
consulted before picking a library.
:::
The following table lists tested file plugins.  "OS" lists tested platforms
("A" for Android and "I" for iOS).  "Copy" indicates whether an explicit copy
is needed (file picker copies to cache directory and file plugin reads cache).
| File system Plugin         | File Picker Plugin             |  OS  | Copy |
|:---------------------------|:-------------------------------|:----:|:-----|
| `react-native-file-access` | `react-native-document-picker` | `AI` |      |
| `react-native-blob-util`   | `react-native-document-picker` | `AI` | YES  |
| `rn-fetch-blob`            | `react-native-document-picker` | `AI` | YES  |
| `react-native-fs`          | `react-native-document-picker` | `AI` | YES  |
| `expo-file-system`         | `expo-document-picker`         | ` I` | YES  |
### RN File Picker
The following libraries have been tested:
#### `react-native-document-picker`
Selecting a file (click to show)
When a copy is not needed:
```js
import { pickSingle } from 'react-native-document-picker';
const f = await pickSingle({allowMultiSelection: false, mode: "open" });
const path = f.uri; // this path can be read by RN file plugins
```
When a copy is needed:
```js
import { pickSingle } from 'react-native-document-picker';
const f = await pickSingle({allowMultiSelection: false, copyTo: "cachesDirectory", mode: "open" });
const path = f.fileCopyUri; // this path can be read by RN file plugins
```
Selecting a file (click to show)
When using `DocumentPicker.getDocumentAsync`, enable `copyToCacheDirectory`:
```js
import * as DocumentPicker from 'expo-document-picker';
const result = await DocumentPicker.getDocumentAsync({
  // highlight-next-line
  copyToCacheDirectory: true,
  type: ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
});
const path = result.uri;
```
Reading and Writing snippets (click to show)
The snippets use `rn-fetch-blob`.  To use `react-native-blob-util`, change the
`import` statements to load the module.
_Reading Data_
```js
import * as XLSX from "xlsx";
import RNFetchBlob from 'rn-fetch-blob'; // or react-native-blob-util
const { readFile } = RNFetchBlob.fs;
const res = await readFile(path, 'ascii');
const wb = XLSX.read(new Uint8Array(res), {type:'buffer'});
```
:::caution
On iOS, the URI from `react-native-document-picker` must be massaged:
```js
import { pickSingle } from 'react-native-document-picker';
import RNFetchBlob from 'rn-fetch-blob'; // or react-native-blob-util
const { readFile, dirs: { DocumentDir } } = RNFetchBlob.fs;
const f = await pickSingle({
// highlight-start
  // Instruct the document picker to copy file to Documents directory
  copyTo: "documentDirectory",
// highlight-end
  allowMultiSelection: false, mode: "open" });
// highlight-start
// `f.uri` is the original path and `f.fileCopyUri` is the path to the copy
let path = f.fileCopyUri;
// iOS workaround
if (Platform.OS === 'ios') path = path.replace(/^.*\/Documents\//, DDP + "/");
// highlight-end
const res = await readFile(path, 'ascii');
```
:::
_Writing Data_
```js
import * as XLSX from "xlsx";
import RNFetchBlob from 'rn-fetch-blob'; // or react-native-blob-util
const { writeFile, readFile, dirs:{ DocumentDir } } = RNFetchBlob.fs;
const wbout = XLSX.write(wb, {type:'buffer', bookType:"xlsx"});
const file = DocumentDir + "/sheetjsw.xlsx";
const res = await writeFile(file, Array.from(wbout), 'ascii');
```
Reading and Writing snippets (click to show)
_Reading Data_
```js
import * as XLSX from "xlsx";
import { FileSystem } from "react-native-file-access";
const b64 = await FileSystem.readFile(path, "base64");
/* b64 is a Base64 string */
const workbook = XLSX.read(b64, {type: "base64"});
```
_Writing Data_
```js
import * as XLSX from "xlsx";
import { Dirs, FileSystem } from "react-native-file-access";
const DDP = Dirs.DocumentDir + "/";
const b64 = XLSX.write(workbook, {type:'base64', bookType:"xlsx"});
/* b64 is a Base64 string */
await FileSystem.writeFile(DDP + "sheetjs.xlsx", b64, "base64");
```
Reading and Writing snippets (click to show)
_Reading Data_
```js
import * as XLSX from "xlsx";
import { readFile } from "react-native-fs";
const bstr = await readFile(path, "ascii");
/* bstr is a binary string */
const workbook = XLSX.read(bstr, {type: "binary"});
```
_Writing Data_
```js
import * as XLSX from "xlsx";
import { writeFile, DocumentDirectoryPath } from "react-native-fs";
const bstr = XLSX.write(workbook, {type:'binary', bookType:"xlsx"});
/* bstr is a binary string */
await writeFile(DocumentDirectoryPath + "/sheetjs.xlsx", bstr, "ascii");
```
Reading and Writing snippets (click to show)
_Reading Data_
Calling `FileSystem.readAsStringAsync` with `FileSystem.EncodingType.Base64`
encoding returns a promise resolving to a string compatible with `base64` type:
```js
import * as XLSX from "xlsx";
import * as FileSystem from 'expo-file-system';
const b64 = await FileSystem.readAsStringAsync(uri, { encoding: FileSystem.EncodingType.Base64 });
const workbook = XLSX.read(b64, { type: "base64" });
```
_Writing Data_
The `FileSystem.EncodingType.Base64` encoding accepts Base64 strings:
```js
import * as XLSX from "xlsx";
import * as FileSystem from 'expo-file-system';
const b64 = XLSX.write(workbook, {type:'base64', bookType:"xlsx"});
/* b64 is a Base64 string */
await FileSystem.writeAsStringAsync(FileSystem.documentDirectory + "sheetjs.xlsx", b64, { encoding: FileSystem.EncodingType.Base64 });
```