Next.js, Capacitor, and Electron: Cross-Platform with a Single Codebase
In today's digital landscape, existing only in web browsers can fall short. Users want to access your apps from their phones (Android/iOS), or run them with seamless performance on their desktop (Windows/macOS). Writing separate native apps in different languages (Java/Kotlin, Swift, C#) for each platform is devastating in terms of time and budget, especially for small studios. At Polimelo studio, we solve this problem using a modern hybrid architecture: React/Next.js, Capacitor.js, and Electron integration.
Technological Architecture
At the center of our system is a single Next.js project that handles the user interface (UI) and all business logic. We distribute this project to three different platforms as follows:
- Web: By utilizing Next.js's
output: 'export'config, we produce static HTML/JS/CSS files. We can distribute these assets globally at high speeds on Cloudflare Pages or Vercel. - Mobile (Android): With the help of Capacitor.js, we take our static web build and embed it inside a native Android project (WebView). Capacitor establishes bridges that let our web code access the phone's native APIs (notifications, file system, etc.).
- Desktop: Using Electron, we turn our static build into a desktop application powered by Chromium and Node.js. This allows our game Syncron to run as a native game on Steam.
Next.js and Static Export Challenges
Next.js defaults to focusing on server-side rendering (SSR). However, since mobile and desktop packagers (Capacitor/Electron) do not have a Node.js server, they require completely static assets. Consequently, we had to avoid dynamic server-side routing in our Next.js project. For our dynamic pages (such as the detail of this blog post under /blog/[slug]), we used the generateStaticParams function to generate all pages as static HTML files during the build phase.
Another critical bottleneck we encountered during static exports was Next.js's built-in image optimization (next/image). This engine relies on an active Node.js server running in the background to resize and serve images dynamically. Since the offline WebView wrapper has no local Node.js server environment, the build script fails. To resolve this, we configured next.config.js with images: { unoptimized: true }. This forces the engine to bypass dynamic processing and package images as-is, preventing runtime image load crashes inside the native frames.
Data Sharing and Offline Support Across Platforms
Another major challenge was local database management. Storing data in a browser is easy, but data must be preserved on mobile and desktop when the app closes or the internet connection drops. We solved this issue by using Dexie.js (IndexedDB wrapper). Since IndexedDB is standardly supported in modern browsers, Capacitor WebViews, and Electron environments, we built a local, offline-first database that works across all platforms using a single codebase. This offline-first approach caches user achievements locally and syncs them seamlessly with Firebase Firestore in the background as soon as network availability is restored, ensuring zero data loss and conflict-free resolutions.
Establishing a Cross-Platform Native Bridge
For platform-specific features (such as triggering haptic feedback on mobile or writing files directly to the OS on desktop), we built a wrapper interface. This isolates device runtime configurations under a unified service API:
async function triggerHapticFeedback() {
if (Capacitor.isNativePlatform()) {
await Haptics.vibrate();
} else if (process.versions && process.versions.electron) {
console.log("Electron: vibration not supported on PC");
} else if (navigator.vibrate) {
navigator.vibrate(100);
}
}
This abstraction layers prevents client-side execution errors when working with WebViews. Next.js outputs the unified index build which automatically detects environment headers at runtime and calls the native hardware APIs accordingly, securing smooth cross-platform delivery.
If you are an independent developer looking to quickly deploy your products to all devices, the Next.js + Capacitor + Electron trio is an excellent choice that minimizes code duplication and accelerates product development speed by 3x.