React Native has emerged as one of the most popular frameworks for developing cross-platform mobile applications. Powered by JavaScript and React, it enables developers to construct native-like apps for iOS and Android from a single codebase, significantly decreasing development time and cost.
In this article, we'll go over the fundamentals of React Native, including navigation, state management, performance optimization, and more. Whether you're a newbie or an experienced developer, this article will help you get the most out of React Native.
1. React Native Basics
Developers all around the world use React Native because of its efficiency and versatility, making it one of the top frameworks for creating cross-platform mobile applications. Based on JavaScript and React, it enables developers to use a single codebase to create native-like, high-performing apps for iOS and Android. This special feature preserves the quality and user experience of completely native apps while significantly cutting down on development time and expenses.
Fundamentally, React Native blends the ease and adaptability of React, a JavaScript toolkit known for creating dynamic and interactive user interfaces, with the greatest features of native programming. Reusable components that are rendered using native platform elements are one of the framework's main tenets, guaranteeing a fluid user experience that feels natural on any device. By combining code into a single system, this method not only expedites the development process but also makes maintenance and updates easier.
We will examine the foundations of React Native in this extensive guide, beginning with the most fundamental concepts and working our way up to more complex subjects. From navigation and state management to performance optimisation and beyond, this article will take a close look at the key ideas that make React Native a top choice for mobile app development. Whether you're a beginner trying to get started or an experienced developer looking to improve your abilities, this guide will provide you with valuable insights and practical tips to help you realise the full potential of React Native.
Installation:
Use npx react-native init ProjectName
to get started quickly.
Hello World:
A simple Text
component can display your first "Hello, World!" app.
Example: A Simple Counter App
import React, { useState } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
const CounterApp = () => {
const [count, setCount] = useState(0);
return (
<View style={styles.container}>
<Text style={styles.text}>Hello, World!</Text>
<Text style={styles.text}>Count: {count}</Text>
<Button title="Increase" onPress={() => setCount(count + 1)} />
<Button title="Decrease" onPress={() => setCount(count - 1)} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
text: {
fontSize: 20,
marginBottom: 20,
},
});
export default CounterApp;
Key Concepts:
-
State (
useState
): Manages your app's dynamic data. - Props: Transfer data from parent to child components.
- StyleSheet: Handles styling similar to CSS but optimised for mobile.
Key Components:
- View: Container for other components.
- Text: Displays text.
- Image: Renders images.
- TouchableOpacity/Button: For interactive elements.
2. Navigation
Navigation helps users to move between screens inside your app. Navigation is a vital component of every project, and React Native provides various frameworks to handle it. React Native does not include built-in navigation, although tools such as React Navigation make it simple.
Installing React Navigation
npm install @react-navigation/native react-native-screens react-native-safe-area-context react-native-gesture-handler react-native-reanimated react-native-vector-icons
Example: Basic Stack Navigator
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { View, Text, Button } from 'react-native';
const HomeScreen = ({ navigation }) => (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home Screen</Text>
<Button title="Go to Details" onPress={() => navigation.navigate('Details')} />
</View>
);
const DetailsScreen = ({ navigation }) => (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details Screen</Text>
<Button title="Go Back" onPress={() => navigation.goBack()} />
</View>
);
const Stack = createStackNavigator();
const App = () => (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
export default App;
React Navigation Types:
- Stack Navigation: Screen-to-screen navigation (as above).
- Tab Navigation: Bottom or top tab-based navigation.
- Drawer Navigation: Sidebar navigation.
- React Native Navigation: A more native-like navigation experience.
Tips:
- Keep navigation configuration simple.
- Use deep linking to handle specific routes.
3. State Management
State management in React Native refers to the strategies and tools used to manage an application's state (data and user interface). Depending on an app's complexity and requirements, there are several techniques of managing state in React Native. These can be broadly classified as local state management and global state management.
The following are the primary forms of state management utilised in React Native:
1. Local State Management
Local state is managed directly within a component using React's built-in hooks, such as useState
. Use the useState
Hook to make simple and minor state changes within a single component.
Example:
import React, { useState } from 'react';
import { View, Text, Button } from 'react-native';
const Counter = () => {
const [count, setCount] = useState(0);
return (
<View>
<Text>Count: {count}</Text>
<Button title="Increase" onPress={() => setCount(count + 1)} />
<Button title="Decrease" onPress={() => setCount(count - 1)} />
</View>
);
};
export default Counter;
2. Global State Management
Data is shared across several components or screens via global state. It offers a consolidated mechanism to handle state.
a. Context API
What It Is: A built-in React feature that allows you to transmit data down the component tree without using prop digging.
When to Use: For medium-sized apps with shared state across numerous components that aren't overly complex.
Example:
import React, { createContext, useState, useContext } from 'react';
import { View, Text, Button } from 'react-native';
const CounterContext = createContext();
const CounterProvider = ({ children }) => {
const [count, setCount] = useState(0);
return (
<CounterContext.Provider value={{ count, setCount }}>
{children}
</CounterContext.Provider>
);
};
const HomeScreen = () => {
const { count, setCount } = useContext(CounterContext);
return (
<View>
<Text>Count: {count}</Text>
<Button title="Increase" onPress={() => setCount(count + 1)} />
</View>
);
};
const App = () => (
<CounterProvider>
<HomeScreen />
</CounterProvider>
);
export default App;
b. Redux
What It Is: A predictable state container used to manage global state.
When to Use: For medium-sized apps with shared state across numerous components that aren't overly complex.
Example:
import React, { createContext, useState, useContext } from 'react';
import { View, Text, Button } from 'react-native';
const CounterContext = createContext();
const CounterProvider = ({ children }) => {
const [count, setCount] = useState(0);
return (
<CounterContext.Provider value={{ count, setCount }}>
{children}
</CounterContext.Provider>
);
};
const HomeScreen = () => {
const { count, setCount } = useContext(CounterContext);
return (
<View>
<Text>Count: {count}</Text>
<Button title="Increase" onPress={() => setCount(count + 1)} />
</View>
);
};
const App = () => (
<CounterProvider>
<HomeScreen />
</CounterProvider>
);
export default App;
c. MobX
What It Is: A simpler, more reactive state management library.
When to Use: For medium to large-scale applications that require reactive state.
Features:
- Uses observable state.
- Less boilerplate than Redux.
Example:
import { makeAutoObservable } from 'mobx';
import { observer } from 'mobx-react';
import React from 'react';
import { View, Text, Button } from 'react-native';
class CounterStore {
count = 0;
constructor() {
makeAutoObservable(this);
}
increment = () => { this.count += 1; };
decrement = () => { this.count -= 1; };
}
const counterStore = new CounterStore();
const Counter = observer(() => (
<View>
<Text>Count: {counterStore.count}</Text>
<Button title="Increase" onPress={counterStore.increment} />
<Button title="Decrease" onPress={counterStore.decrement} />
</View>
));
const App = () => <Counter />;
export default App;
d. Recoil
What It Is: A modern state management library that integrates easily with React.
When to Use: In applications where state must be derived or shared between components.
Example:
import React from 'react';
import { RecoilRoot, atom, useRecoilState } from 'recoil';
import { View, Text, Button } from 'react-native';
const counterState = atom({
key: 'counterState',
default: 0,
});
const Counter = () => {
const [count, setCount] = useRecoilState(counterState);
return (
<View>
<Text>Count: {count}</Text>
<Button title="Increase" onPress={() => setCount(count + 1)} />
<Button title="Decrease" onPress={() => setCount(count - 1)} />
</View>
);
};
const App = () => (
<RecoilRoot>
<Counter />
</RecoilRoot>
);
export default App;
3. Async State Management
Libraries such as redux-thunk, redux-saga, or React's built-in hooks (useEffect and useState) can be used for state that is dependent on asynchronous actions (for example, API requests).
Example: Fetching Data with useEffect
import React, { useEffect, useState } from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
const FetchData = () => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => response.json())
.then((json) => {
setData(json);
setLoading(false);
});
}, []);
return (
<View>
{loading ? <ActivityIndicator /> : <Text>{data.title}</Text>}
</View>
);
};
export default FetchData;
Which State Management System Should You Use?
- Small Apps: useState and useReducer.
- Medium Apps: Context API or MobX.
- Large Apps: Redux or Recoil.
- Highly Reactive Apps: MobX.
Each solution involves trade-offs, and the ideal one is determined by your app's complexity and requirements.
4. Styling
React Native defines styles using JavaScript objects. Styles can be created either using the StyleSheet API or inline. Dynamic or utility-based styling can also be achieved using libraries such as Styled Components and Tailwind CSS.
a. Using the StyleSheet
API
- Recommended for creating reusable styles.
- Styles are comparable to CSS, except that property names are in camelCase.
Example: Basic Styling
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
const App = () => {
return (
<View style={styles.container}>
<Text style={styles.title}>Hello, World!</Text>
<Text style={styles.subtitle}>Welcome to React Native</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f0f0f0',
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#333',
},
subtitle: {
fontSize: 18,
color: '#666',
},
});
export default App;
b. Dynamic Styling with Props
Styles can change dynamically in response to component data or state.
Example: Dynamic Button Styling
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
const DynamicButton = () => {
const [isActive, setIsActive] = useState(false);
return (
<View style={styles.container}>
<TouchableOpacity
style={[styles.button, isActive && styles.activeButton]}
onPress={() => setIsActive(!isActive)}
>
<Text style={styles.buttonText}>{isActive ? 'Active' : 'Inactive'}</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
button: {
padding: 10,
backgroundColor: '#ddd',
borderRadius: 5,
},
activeButton: {
backgroundColor: '#4caf50',
},
buttonText: {
color: '#fff',
},
});
export default DynamicButton;
c. Using Styled Components
Allows React Native to use CSS-in-JS styling.
Example: Styled Components
import React from 'react';
import styled from 'styled-components/native';
const Container = styled.View`
flex: 1;
justify-content: center;
align-items: center;
background-color: #f0f0f0;
`;
const Title = styled.Text`
font-size: 24px;
font-weight: bold;
color: #333;
`;
const App = () => (
<Container>
<Title>Hello Styled Components</Title>
</Container>
);
export default App;
5. Performance Optimisation
If React Native apps are not optimised, they may experience performance concerns. Here are several significant strategies and code examples:
a. Use FlatList for Efficient Lists
FlatList is optimised for rendering large lists with lazy loading.
Example:
import React from 'react';
import { FlatList, Text, StyleSheet, View } from 'react-native';
const data = Array.from({ length: 100 }, (_, i) => `Item ${i + 1}`);
const App = () => {
return (
<FlatList
data={data}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item}</Text>
</View>
)}
/>
);
};
const styles = StyleSheet.create({
item: {
padding: 10,
borderBottomWidth: 1,
borderColor: '#ddd',
},
});
export default App;
b. Memoize Components
React.memo
and useMemo
help you avoid wasteful re-renders.
Example:
import React, { useState, useMemo } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';
const ExpensiveComponent = React.memo(({ count }) => {
console.log('Rendering Expensive Component');
return <Text>Count: {count}</Text>;
});
const App = () => {
const [count, setCount] = useState(0);
const [otherState, setOtherState] = useState(0);
return (
<View style={styles.container}>
<ExpensiveComponent count={count} />
<Button title="Increase Count" onPress={() => setCount(count + 1)} />
<Button title="Change Other State" onPress={() => setOtherState(otherState + 1)} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default App;
c. Optimize Images
Use optimized formats and libraries, such as react-native-fast-image.
Example:
import React from 'react';
import FastImage from 'react-native-fast-image';
const App = () => (
<FastImage
style={{ width: 200, height: 200 }}
source={{
uri: 'https://example.com/image.jpg',
priority: FastImage.priority.high,
}}
resizeMode={FastImage.resizeMode.cover}
/>
);
export default App;
6. Networking
React Native relies heavily on networking to facilitate API communication. For advanced use cases, React Native provides libraries such as axios in addition to JavaScript's fetch API.
a. Fetching Data with fetch
Example:
import React, { useEffect, useState } from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
const App = () => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => response.json())
.then((json) => {
setData(json);
setLoading(false);
});
}, []);
if (loading) {
return <ActivityIndicator />;
}
return (
<View>
<Text>{data.title}</Text>
</View>
);
};
export default App;
b. Using Axios for API Calls
Simplifies error handling and configuration.
Example:
import React, { useEffect, useState } from 'react';
import { View, Text } from 'react-native';
import axios from 'axios';
const App = () => {
const [data, setData] = useState(null);
useEffect(() => {
axios
.get('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => setData(response.data))
.catch((error) => console.error(error));
}, []);
return (
<View>
{data ? <Text>{data.title}</Text> : <Text>Loading...</Text>}
</View>
);
};
export default App;
c. Handling Authentication
To manage tokens, use AsyncStorage or SecureStorage.
Example:
import React, { useEffect, useState } from 'react';
import { View, Button, Text } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
const App = () => {
const [token, setToken] = useState('');
const saveToken = async () => {
await AsyncStorage.setItem('userToken', '12345');
setToken('12345');
};
const getToken = async () => {
const value = await AsyncStorage.getItem('userToken');
setToken(value);
};
return (
<View>
<Button title="Save Token" onPress={saveToken} />
<Button title="Get Token" onPress={getToken} />
<Text>Token: {token}</Text>
</View>
);
};
export default App;
7. Native Modules in React Native
Native Modules enable you to enhance React Native's functionality by creating custom modules in platform-specific languages (Java/Kotlin for Android, Objective-C/Swift for iOS). This is useful when you need to use device features or third-party libraries that are not supported by React Native.
When to Use Native Modules
- Accessing device hardware like Bluetooth or NFC.
- Integrating native SDKs or APIs.
- Improving performance for computationally heavy tasks.
Example: Creating a Native Module
Android Implementation:
- Create a Java module in
android/app/src/main/java/com/yourapp/CustomModule.java
:
package com.yourapp;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
public class CustomModule extends ReactContextBaseJavaModule {
public CustomModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "CustomModule";
}
@ReactMethod
public void showMessage(String message, Callback callback) {
callback.invoke("Message from Android: " + message);
}
}
- Register the module in MainApplication.java:
@Override
protected List<ReactPackage> getPackages() {
return Arrays.asList(
new MainReactPackage(),
new CustomReactPackage()
);
}
- Use it in JavaScript:
import { NativeModules } from 'react-native';
const { CustomModule } = NativeModules;
CustomModule.showMessage('Hello from React Native', (message) => {
console.log(message);
});
Similar steps apply for iOS using Objective-C/Swift.
8. Testing in React Native
Testing ensures that your program will function properly. React Native supports a variety of testing methodologies, including unit, integration, and end-to-end (E2E) tests.
a. Unit Testing with Jest
Jest is the default testing library for React Native.
Example:
import React from 'react';
import { render } from '@testing-library/react-native';
import App from '../App';
test('renders correctly', () => {
const { getByText } = render(<App />);
expect(getByText('Hello, World!')).toBeTruthy();
});
b. Integration Testing with React Native Testing Library
Integration tests check interactions between components.
Example:
import React from 'react';
import { render, fireEvent } from '@testing-library/react-native';
import Counter from '../Counter';
test('increments the counter', () => {
const { getByText } = render(<Counter />);
fireEvent.press(getByText('Increase'));
expect(getByText('Count: 1')).toBeTruthy();
});
c. End-to-End Testing with Detox
Detox allows you to test the entire program in the same way that a user would.
Setup:
npm install -g detox-cli
npm install detox --save-dev
Example: Detox Test
describe('App Launch', () => {
beforeAll(async () => {
await device.launchApp();
});
it('should show welcome screen', async () => {
await expect(element(by.id('welcome'))).toBeVisible();
});
});
9. Debugging in React Native
Debugging aids in the detection and resolution of problems during the development process.
a. Using React Native Debugger
React Native Debugger is a standalone tool that integrates with Chrome DevTools.
How to Use:
Install React Native Debugger:
brew install --cask react-native-debugger
Open the debugger and enable debugging in your app:
- Shake your device or press
Cmd+D
(iOS) orCmd+M
(Android). - Select "Debug JS Remotely".
b. Flipper for Debugging
Flipper is a platform for debugging React Native apps.
Features:
- Inspect layout.
- Debug Redux or MobX.
- Monitor network requests.
Setup:
- Install Flipper: Flipper Website.
- Enable the React Native plugin.
c. Debugging with Console Logs
Use console.log
, console.warn
, and console.error
to debug in the terminal or debugger.
d. Using Breakpoints
Set breakpoints in your code using a suitable editor, such as Visual Studio Code. Attach the debugger to your running application and pause it at important times.
10. Platform-Specific Code in React Native
React Native allows you to develop iOS or Android-specific code as needed.
a. Platform-Specific File Extensions
To define platform-specific logic, create files with the .ios.js
and the .android.js
extensions.
Example:
// Button.ios.js
import React from 'react';
import { Button } from 'react-native';
const PlatformButton = (props) => <Button {...props} color="blue" />;
export default PlatformButton;
// Button.android.js
import React from 'react';
import { Button } from 'react-native';
const PlatformButton = (props) => <Button {...props} color="green" />;
export default PlatformButton;
React Native will automatically select the appropriate file based on the platform.
b. Platform API
Use the Platform module to implement conditional logic.
Example: Conditional Styling
import React from 'react';
import { View, Text, StyleSheet, Platform } from 'react-native';
const App = () => {
return (
<View style={styles.container}>
<Text style={styles.text}>
Running on {Platform.OS === 'ios' ? 'iOS' : 'Android'}
</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: Platform.OS === 'ios' ? '#f0f0f0' : '#e0e0e0',
},
text: {
fontSize: 20,
color: Platform.OS === 'ios' ? 'blue' : 'green',
},
});
export default App;
c. Native Modules for Platform-Specific Features
As previously explained, use Native Modules to access platform-specific APIs.
11. Miscellaneous in React Native
The "miscellaneous" category contains extra concepts and packages that improve the React Native programming experience. These capabilities may not be central to the framework, but they are essential for developing modern, user-friendly applications.
a. Animations
Animations make your app more engaging and improve the user experience. React Native offers the Animated
API and packages such as react-native-reanimated
.
Example: Simple Fade-In Animation Using Animated
import React, { useRef, useEffect } from 'react';
import { Animated, View, StyleSheet } from 'react-native';
const FadeInView = ({ children }) => {
const fadeAnim = useRef(new Animated.Value(0)).current;
useEffect(() => {
Animated.timing(fadeAnim, {
toValue: 1,
duration: 2000,
useNativeDriver: true,
}).start();
}, [fadeAnim]);
return (
<Animated.View style={{ ...styles.container, opacity: fadeAnim }}>
{children}
</Animated.View>
);
};
const App = () => (
<FadeInView>
<View style={styles.box} />
</FadeInView>
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
box: {
width: 100,
height: 100,
backgroundColor: 'blue',
},
});
export default App;
b. Push Notifications
Push notifications can be used by React Native apps to engage their users. Libraries like react-native-push-notification and Firebase Cloud Messaging (FCM) are popular choices.
Example: Setting Up Push Notifications Using FCM
- Install Firebase:
npm install @react-native-firebase/app @react-native-firebase/messaging
- Configure Messaging:
import messaging from '@react-native-firebase/messaging';
messaging().onMessage(async (remoteMessage) => {
console.log('Received in foreground:', remoteMessage);
});
c. Deep Linking
Deep linking allows users to open specific screens in your app via URLs.
Example: Setting Up Deep Linking
- Configure deep linking in App.js:
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
const linking = {
prefixes: ['myapp://'],
config: {
screens: {
Home: 'home',
Profile: 'profile/:id',
},
},
};
const App = () => (
<NavigationContainer linking={linking}>
{/* Your navigators here */}
</NavigationContainer>
);
export default App;
- Open the app with
myapp://home
ormyapp://profile/123
.
d. Code Sharing Between Web and Mobile
React Native supports code sharing between React Native and React for the web.
Example: Shared Button Component
// Button.js
import { Platform } from 'react-native';
const Button = Platform.select({
ios: () => require('./Button.ios').default,
android: () => require('./Button.android').default,
web: () => require('./Button.web').default,
})();
export default Button;
12. Community and Resources
React Native has a robust and active community that contributes to the ecosystem. Here are some strategies for efficiently leveraging the community and its resources.
a. Documentation
React Native's official documentation is the go-to resource: React Native Docs
b. Communities
Engage with other developers:
- Discord: Reactiflux
- Reddit: r/reactnative
- StackOverflow: Find answers to specific issues.
c. Open Source Contributions
Contribute to or use open-source React Native projects:
d. Courses and Tutorials
Platforms like Udemy, FreeCodeCamp, and YouTube offer beginner to advanced React Native tutorials.
e. Tools and IDEs
- VSCode: Install extensions like "React Native Tools" for better development.
- Expo: A framework and platform for developing React Native apps faster.
f. Code Sharing with Monorepos
Monorepos allow you to share code between mobile and web platforms using tools like Nx or Yarn Workspaces.
Example: Nx Monorepo
npx create-nx-workspace@latest
Conclusion
React Native is a robust framework for creating cross-platform applications. You may construct efficient and user-friendly apps by grasping the fundamentals and digging into advanced concepts such as state management, native modules, and performance optimization. With the ecosystem constantly evolving, there's never been a better moment to use React Native for mobile development.
Feel free to leave your views, questions, or experiences in the comments area. Let's create something awesome with React Native!
About Me
I’m a Full-Stack Developer with over four years of experience building scalable and high-performance web and mobile applications. My expertise lies in frameworks like Next.js, Nest.js, and React Native, as well as technologies such as GraphQL, Stripe integration, and cloud platforms like Google Cloud and Microsoft Azure.
I’ve worked across diverse industries, including e-commerce and enterprise solutions, where I’ve consistently delivered user-friendly, responsive, and secure applications. Beyond development, I excel in team leadership, performance optimization, and troubleshooting complex technical challenges.
I’m passionate about exploring innovative technologies like serverless architectures and Large Language Models (LLMs), and I enjoy applying these to real-world problems. Whether collaborating with teams or tackling new challenges, I’m committed to continuous learning and contributing to impactful projects.
📧 Email: dev.asif.ae@gmail.com
🌐 Portfolio: https://www.asife.dev/
💼 LinkedIn: https://www.linkedin.com/in/asif-estiak/
🐙 GitHub: https://github.com/asif-ae
If you’re interested in API design, modern tech trends, or insights on scaling applications, let’s connect and share ideas! 🚀
Top comments (0)