What Does “Offline-First” Mean?
-
Your app works even without the internet
-
Data is saved locally in the browser
- When online again, the app syncs that data to the server
Real-World Examples
-
Google Docs - lets you write and edit offline, and syncs changes later.
-
Spotify - allows you to download songs and listen offline.
- Notion - lets you create and edit notes offline; once online, it updates automatically.
Tools You Will Use to Build an Offline-First React App
1. IndexedDB
-
Can store large amounts of data (more than localStorage)
-
Works great for caching and offline queues
- Supports complex data (objects, arrays, etc.)
2. Service Workers
-
Cache files (like HTML, JS, images) for offline use
-
Handle push notifications
- Manage background sync tasks
3. React + Hooks
Step 1: Set Up IndexedDB in React
npm install idb
Now, create a file db.js inside your src folder.
This file will handle all local database operations, like creating the database, adding data, and fetching data.
import { openDB } from 'idb';
const DB_NAME = 'offlineAppDB';
const STORE_NAME = 'users';
export const initDB = async () => {
return await openDB(DB_NAME, 1, {
upgrade(db) {
if (!db.objectStoreNames.contains(STORE_NAME)) {
db.createObjectStore(STORE_NAME, { keyPath: 'id', autoIncrement: true });
}
},
});
};
export const addUser = async (user) => {
const db = await initDB();
await db.add(STORE_NAME, user);
};
export const getUsers = async () => {
const db = await initDB();
return await db.getAll(STORE_NAME);
};
Explanation:
-
initDB() creates or opens a database named offlineAppDB.
-
upgrade() runs the first time and sets up a store named users.
- addUser() saves a new record.
- getUsers() fetches all stored users.
Step 2: Using IndexedDB Inside Your React App
App.js like this:import React, { useEffect, useState } from "react";
import { addUser, getUsers } from "./db";
function App() {
const [users, setUsers] = useState([]);
const [name, setName] = useState("");
useEffect(() => {
loadUsers();
}, []);
const loadUsers = async () => {
const storedUsers = await getUsers();
setUsers(storedUsers);
};
const handleAddUser = async () => {
await addUser({ name, createdAt: new Date() });
setName("");
loadUsers();
};
return (
<div>
<h1>Offline-First React App</h1>
<input value={name} onChange={(e) => setName(e.target.value)} />
<button onClick={handleAddUser}>Add User</button>
<ul>
{users.map((u) => (
<li key={u.id}>{u.name} - {u.createdAt.toString()}</li>
))}
</ul>
</div>
);
}
export default App;
How It Works:
-
When the app loads, it calls getUsers() to show saved users.
-
When you add a new user, it’s stored in IndexedDB, not on a server.
- Even if you disconnect from the internet, the data remains available.
Step 3: Add a Service Worker for Caching
service-worker.js file in your public folder.const CACHE_NAME = "offline-cache-v1";
const urlsToCache = ["/", "/index.html", "/favicon.ico"];
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => cache.addAll(urlsToCache))
);
});
self.addEventListener("fetch", (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});
Then register the service worker inside index.js:
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker.register("/service-worker.js");
});
}
What It Does:
-
The install event caches your app files.
-
The fetch event intercepts network requests and serves cached files when offline.
Step 4: Sync Data When the Internet Returns
Now, let’s make your app smart; it should automatically sync data to the server when you are back online.
window.addEventListener("online", async () => {
const pendingUsers = await getUsers();
pendingUsers.forEach(async (user) => {
await fetch("/api/users", {
method: "POST",
body: JSON.stringify(user),
headers: { "Content-Type": "application/json" },
});
});
});
How It Works:
-
When the browser goes online, this event triggers.
-
It checks for locally saved users.
- It sends them to your backend API automatically.
Step 5: Make It a Progressive Web App (PWA)
manifest.json file inside public.{
"name": "Offline React App",
"short_name": "OfflineApp",
"start_url": ".",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#317EFB",
"icons": [
{
"src": "/icon.png",
"sizes": "192x192",
"type": "image/png"
}
]
}
Now your app can be installed on mobile or desktop like a native app!
Final Thoughts
-
Store data locally when offline
-
Cache assets for faster load times
- Sync data automatically when online
- Deliver a native-like PWA experience
Collaboration with us
-
45% of users abandon apps that don’t work offline.
-
PWAs boost user engagement by 52%.
- Companies using offline-first apps see 2x higher user retention.
That’s why businesses worldwide trust Sparkle Web to deliver fast, reliable, and scalable web solutions. Whether you want an offline React app, a cross-platform mobile app, or a real-time dashboard, Sparkle Web delivers end-to-end development, testing, and optimization services. Contact Us.

Vaishali Gaudani
Skilled React.js Developer with 3+ years of experience in creating dynamic, scalable, and user-friendly web applications. Dedicated to delivering high-quality solutions through innovative thinking and technical expertise.
Reply