Skip to content

Learn

React Native fs: How to use fs to read and write files

Learn how to use react-native-fs to read and write files in a React Native app, and discover how Testim Mobile simplifies comprehensive mobile testing.

react native fs

We need to access locally stored data from our phones for a variety of reasons. For this, we can use the awesome react-native-fs package. Now, this package is a bit difficult to install and use, so we are going to look into the issues, as well as the ways to fix them.

In this post, we are going to create a small app in React Native. We are going to add the feature to write, read, and delete a file using react-native-fs. We will be using a Mac with an M1 chip and an iOS emulator for this project. The errors and the steps to fix them will be different for other platforms.

In today’s fast-paced digital world, the ability to efficiently manage locally stored data on mobile devices is crucial. Whether you’re developing a new app feature or ensuring seamless data access, using the react-native-fs package can be a game-changer. However, integrating this package can pose challenges. This guide will walk you through building a small app using React Native and react-native-fs to handle file operations. But the real highlight? Discover how Testim Mobile can revolutionize your app testing process, making it faster and more reliable.

Initial setup

We’ll be using the React Native CLI. Here we are using Xcode. The steps for the environment variables and Android Studio are documented in the official docs.

First, we’ll create a new React Native project. Go to any directory in the terminal. Use the command npx react-native init <project-name> to create a new project.

React Native fs: How to Use fs to Read and Write Files

npx react-native init FileSystemProject

 

We will also install the react-native-fs file system package in our application with the below command:

npm install react-native-fs

 

Running the file system project

We need to first navigate to the folder containing the project in the terminal. After that, we need to run the command npx react-native start.

run the command npx react-native start

Now we need to run the npx react-native run-ios command in another terminal. It will also open the basic app on the iOS emulator.

More setup

We need to do more setup through the command line. In the project directory, run the below command. This command automatically does the manual setup for react-native-fs.

npx react-native link react-native-fs

 

the manual setup for react-native-fs.

The Mac M1 requires additional setup for every project in React Native. So we need to run these below commands in the project directory:

sudo arch -x86_64 gem install ffi
cd ios && arch -x86_64 pod install

 

more setup for react native fs

Initial code

We will first create two components, which we are going to use in our project. Create a components folder in the root directory. Create a file ButtonText.js inside it and put the below code in it. It contains a Text field with a props of name. The props of name is shown in the Text field.

import { StyleSheet, Text } from 'react-native'
import React from 'react'
const ButtonText = ({ name }) => {
return (
    <Text style={styles.buttonTextStyle}>{name}</Text>
  )
}
const styles = StyleSheet.create({
    buttonTextStyle: {
       color: 'black',
       textAlign: 'center',
       fontSize: 18,
       fontWeight: 'bold',
    }
})
export default ButtonText

 

Now also create a file AppText.js inside the components folder. It contains a styled Text component. We are using the children props here.

import { StyleSheet, Text } from 'react-native'
import React from 'react'
const AppText = ({ children }) => <Text style={styles.textStyle}>{children}</Text>
const styles = StyleSheet.create({
textStyle: {
fontSize: 22,
fontWeight: 'bold',
textAlign: 'center',
paddingVertical: 20,
}
})
export default AppText

 

Using components

Now we will use the newly created components in our App.js file. Remove all the content from the App.js file and add the below content in it. We are first importing the required things, which includes the RNFS module.

Here we have created the buttons using TouchableOpacity. Inside the buttons, we are using the component of ButtonText to show the Text. We will also use the AppText component to show the Text.

import React, { useState } from 'react';
import * as RNFS from 'react-native-fs';
import { SafeAreaView, StyleSheet, View, TouchableOpacity } from 'react-native'
import ButtonText from './components/ButtonText';
import AppText from './components/AppText';
const App = () => {
return (
  <SafeAreaView style={{ flex: 1 }}>
   <View style={styles.container}>
    <TouchableOpacity onPress={writeFile} style={styles.buttonStyle}>
      <ButtonText name="WRITE" />
    </TouchableOpacity>
    <TouchableOpacity onPress={readFile} style={styles.buttonStyle}>
     <ButtonText name="READ" />
   </TouchableOpacity>
  <TouchableOpacity onPress={deleteFile} style={styles.buttonStyle}>
   <ButtonText name="DELETE" />
  </TouchableOpacity>
  <AppText>{content}</AppText>
  </View>
 </SafeAreaView>
 )
}
const styles = StyleSheet.create({
  container: {
   flex: 1,
   padding: 10,
   backgroundColor: '#98DBC6',
 },
  buttonStyle: {
   backgroundColor: '#F18D9E',
   padding: 10,
   marginTop: 32,
   minWidth: 250,
   borderRadius: 5
 },
})
export default App

 

Main logic

Now we will add the main logic in our app to use the RNFS. We have to first create a state variable of content. After that, in the writeFile(), we are using RNFS.writeFile to write content in the test.txt file.

Next, in readFile(), we are using RNFS.readDir to read the content from the device. If we are getting the file, we are printing in the then statement. We are also using setContent(contents) to set it in the state variable of content. This will also re-render our component, and the data will be shown on the mobile device.

In deleteFile(), we are using RNFS.unlink to delete the file. After deleting, we are doing setContent(null), which will make the content disappear from the mobile screen.

const [content, setContent] = useState(null);
const writeFile = () => {
   var path = RNFS.DocumentDirectoryPath + '/test.txt';
   RNFS.writeFile(path, 'This is a content from Waldo', 'utf8')
    .then(() => console.log('FILE WRITTEN!'))
    .catch((err) => console.log(err.message));
}
const readFile = () => {
   RNFS.readDir(RNFS.DocumentDirectoryPath)
    .then((result) => {
    console.log('GOT RESULT', result);
    return Promise.all([RNFS.stat(result[0].path), result[0].path]);
  })
  .then((statResult) => {
   if (statResult[0].isFile()) {
    return RNFS.readFile(statResult[1], 'utf8');
 }
 return 'no file';
 })
 .then((contents) => {
  setContent(contents);
  console.log(contents);
 })
  .catch((err) => {
   console.log(err.message, err.code);
  });
}
const deleteFile = () => {
    var path = RNFS.DocumentDirectoryPath + '/test.txt';
    return RNFS.unlink(path)
      .then(() => {
        console.log('FILE DELETED');
        setContent(null);
      })
      .catch((err) => {
        console.log(err.message);
      });
  };

We have to add the above code inside the app, as shown below:

main logic

Running the app

With this code, our app is complete. Now click on the WRITE button in the iOS emulator, and it will show the log of FILE WRITTEN.

When we click on the READ button, it will show as the log and also the content on the screen.

running the app

Clicking on the DELETE button will delete the content from the mobile device. It will also show us the log of FILE DELETED.

log of file deleted in react native fs

App testing

In most companies, it’s mandatory to test your apps. Testing helps us catch errors during development and fix them. There are many ways to test our app, some of which are complicated.

Testing helps us catch errors during development and fix them.

We will be using the snapshot way to test our app. The best thing about creating apps with the React Native app is that it comes with a built-in Jest framework. The Jest testing framework is used for writing automation testing and many other types of tests.

In the __tests__ folder, remove the earlier App-test.js file. After that, add two files inside it: ButtonText-test.js and AppText-test.js.

Next, in the AppText-test.js file, we will add the below content. We are using a simple snapshot test to check whether the tags match with those rendered on mobile.

import React from 'react';
import renderer from 'react-test-renderer';
import AppText from '../components/AppText';
describe('<AppText />', () => {
    const tree = renderer.create(<AppText />).toJSON();
      it('AppText Component rendered', () => {
      expect(tree).toMatchSnapshot();
   });
});

 

In the ButtonText-test.js file, we will add the below content. Again, we are testing the mobile layout to see if it matches our code.

import React from 'react';
import renderer from 'react-test-renderer';
import ButtonText from '../components/ButtonText';
describe('<ButtonText />', () => {
    const tree = renderer.create(<ButtonText />).toJSON();
      it('ButtonText Component rendered', () => {
      expect(tree).toMatchSnapshot();
   });
});

 

To run the tests, we need to run npm run test from the command line. This will run all the test cases written in both files.

In the above screenshot, we can see that all of our test cases ran successfully. As we can see from writing these simple test cases, we have to learn a new kind of format. And we also need to write a lot of code. If we add React Native file system (RNFS) to the testing, the test cases will be more complicated. While Jest provides basic testing capabilities within React Native, Testim Mobile takes your testing to the next level. Instead of manually writing extensive test cases, Testim Mobile allows you to conduct automated tests across your entire mobile application with ease.

To begin, generate your app’s APK or IPA file and upload it to Testim Mobile. The platform simplifies testing through intuitive user interactions, eliminating the need for complex test scripts. This no-code solution accelerates your testing workflow, ensuring your app meets the highest quality standards before deployment.

Conclusion: Simplify your testing workflow

Integrating react-native-fs into your React Native app opens up powerful file handling capabilities, but testing those features can be time-consuming and complex. With Testim Mobile, you can bypass these challenges, allowing you to focus on innovation rather than manual testing. Testim Mobile’s robust automation capabilities support your entire application lifecycle, from development to delivery, making it an indispensable tool for any mobile app developer.

Try Testim Mobile today and experience how it can streamline your testing process, ensuring your apps are bug-free and ready for the market.

The author of the post is Nabendu Biswas. Nabendu has been working in the software industry for the past 15 years, starting as a C++ developer, then moving on to databases. For the past six years he’s been working as a web-developer working in the JavaScript ecosystem, and developing web-apps in ReactJS, NodeJS, GraphQL. He loves to blog about what he learns and what he’s up to.

Author:

Guest Contributors

Date: Jan. 29, 2026

You might also be interested in...