Create a Typing Speed Monitor App using React-Native
A typing speed monitor app using React-Native is a software application designed to assess and track a user's typing speed and accuracy. These apps are often used for educational purposes, professional development, or personal improvement in typing skills.
Preview of final output: Let us have a look at how the final application will look like.

Prerequisites:
Approach to create Typing Speed Monitor App:
- The typing speed monitor app is designed to monitor and evaluate the user's typing speed.
- The app has a timer set initially to 60 seconds which provides a time constraint for typing.
- Typing speed is calculated based on the number of words typed within the given time.
- Users can start typing by clicking the "Start Typing" button.
- The app allows users to input text in a multiline TextInput component.
- Users can end their typing session with the "End Typing" button, which stops the timer.
- The app tracks errors made during typing by comparing the entered text with the provided sample.
- Error count and typing speed are displayed once the typing session ends.
- Users can reset the app using the "Reset" button.
Steps to Create React Native App:
Step 1: Create a react native application by using this command in the command prompt
React-native init TypingApp
Step 2: We will use some Icons in our app so, we will install dependency for icon.
npm i react-native-vector-icons
npm i react-native-fontawesome
Project Structure:

The updated dependencies in package.json file will look like:
"dependencies": {
"mobx": "4.1.0",
"mobx-react": "5.0.0",
"@expo/vector-icons": "^13.0.0",
"react-native-elements": "0.18.5",
"react-native-vector-icons/FontAwesome": "*",
"react-native-vector-icons": "10.0.3"
}
Example: Below is the source code of Typing Speed Monitor the React-Native
import React,
{
useState,
useEffect
} from 'react';
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
ScrollView,
} from 'react-native';
const TypingSpeedMonitorApp = () => {
const sampleText =
`GeeksforGeeks is a computer science portal
that provides a wide variety of resources
for programmers and computer science
enthusiasts. It was created with the
goal of providing high-quality educational
content to help individuals learn and improve
their programming and computer science skills.`;
const [text, setText] = useState('');
const [startTime, setStartTime] = useState(0);
const [endTime, setEndTime] = useState(0);
const [typingSpeed, setTypingSpeed] = useState(0);
const [isTyping, setIsTyping] = useState(false);
const [timer, setTimer] = useState(60);
const [errors, setErrors] = useState(0);
useEffect(() => {
let timerInterval;
if (isTyping) {
timerInterval =
setInterval(() => {
setTimer((prevTimer) => {
if (prevTimer === 1) {
clearInterval(timerInterval);
handleEndTyping();
return 60;
}
return prevTimer - 1;
});
}, 1000);
}
return () => {
clearInterval(timerInterval);
};
}, [isTyping]);
useEffect(() => {
if (startTime && endTime
&& text.trim().length > 0) {
const timeDiffInSeconds =
(endTime - startTime) / 1000;
const wordsPerMinute =
(text.split(' ').length /
timeDiffInSeconds) * 60;
setTypingSpeed(wordsPerMinute.toFixed(2));
}
}, [endTime]);
const handleStartTyping = () => {
setText('');
setStartTime(new Date().getTime());
setIsTyping(true);
setErrors(0);
};
const handleEndTyping = () => {
setEndTime(new Date().getTime());
setIsTyping(false);
setTimer(60);
if (text.trim().length > 0) {
calculateErrors();
}
};
const calculateErrors = () => {
const sampleWords =
sampleText.split(' ');
const enteredWords =
text.split(' ');
let errorCount = 0;
for (let i = 0; i < sampleWords.length; i++) {
if (sampleWords[i] !==
enteredWords[i]) {
errorCount++;
}
}
setErrors(errorCount);
};
const handleReset = () => {
setText('');
setStartTime(0);
setEndTime(0);
setTypingSpeed(0);
setIsTyping(false);
setTimer(60);
setErrors(0);
};
return (
<ScrollView
contentContainerStyle={styles.container}>
<Text style={styles.heading}>
Typing Speed Monitor
</Text>
<Text style={styles.timer}>
Timer:- {timer}s
</Text>
<Text style={styles.sampleText}>
{sampleText}
</Text>
<TextInput
style={styles.input}
multiline
placeholder="Type here..."
value={text}
onChangeText=
{
(value) => setText(value)
}
editable={isTyping} />
<View style={styles.buttonsContainer}>
{isTyping ? (
<TouchableOpacity
style={styles.endButton}
onPress={handleEndTyping}>
<Text style={styles.buttonText}>
End Typing
</Text>
</TouchableOpacity>
) : (
<TouchableOpacity
style={styles.startButton}
onPress={handleStartTyping}>
<Text style={styles.buttonText}>
Start Typing
</Text>
</TouchableOpacity>
)}
<TouchableOpacity
style={styles.resetButton}
onPress={handleReset}>
<Text style={styles.buttonText}>
Reset
</Text>
</TouchableOpacity>
</View>
{endTime > 0 && (
<View style={styles.result}>
<Text style={styles.resultText}>
Typing Speed: {typingSpeed}
words per minute
</Text>
<Text style={styles.resultText}>
Error Count: {errors}
</Text>
</View>
)}
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
flexGrow: 1,
padding: 16,
backgroundColor: '#f8f8f8',
},
heading: {
fontSize: 24,
fontWeight: 'bold',
marginTop: 30,
marginBottom: 16,
justifyContent: 'center',
},
timer: {
fontSize: 26,
fontWeight: 'bold',
marginBottom: 16,
marginLeft: 10,
backgroundColor: 'yellow',
marginRight: 130,
borderRadius: 20,
},
sampleText: {
marginBottom: 16,
fontStyle: 'italic',
textAlign: 'center',
color: '#555',
backgroundColor: 'lightgreen',
borderRadius: 20,
padding: 30,
fontWeight: 'bold',
},
input: {
height: 100,
borderColor: '#3498db',
borderWidth: 1,
marginBottom: 16,
padding: 8,
fontSize: 16,
color: '#333',
},
buttonsContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 16,
},
startButton: {
flex: 1,
backgroundColor: '#2ecc71',
padding: 12,
borderRadius: 8,
alignItems: 'center',
marginRight: 8,
},
endButton: {
flex: 1,
backgroundColor: '#e74c3c',
padding: 12,
borderRadius: 8,
alignItems: 'center',
marginRight: 8,
},
resetButton: {
flex: 1,
backgroundColor: '#3498db',
padding: 12,
borderRadius: 8,
alignItems: 'center',
},
buttonText: {
color: '#fff',
fontWeight: 'bold',
},
result: {
marginTop: 16,
backgroundColor: '#fff',
padding: 16,
borderRadius: 8,
},
resultText: {
fontSize: 16,
marginBottom: 8,
fontWeight: 'bold',
},
});
export default TypingSpeedMonitorApp;
Step to Run the Project:
Step 1: Depending on your operating system, type the following command
- For android:
React-native run-android
- For IOS:
React-native run-ios
Output: