What is NextOP?
NextOP bundles Next.js + Electron to build desktop applications for the React ecosystem.
The goal is to combine the Next.js developer experience (App Router, SSR, Server Components, API
routes, next/image) with Electron's native capabilities (filesystem, shell, notifications,
clipboard, secure storage, native menus, multi-window).
The fullstack React framework for the desktop. Real Next.js on the inside, a native Electron shell on the outside.
- Repository: github.com/FlyingTurkman/nextop-app
- Packages:
create-nextop-app(scaffolder),nextop-app(runtime library +nextopCLI) - Status: early / experimental —
1.0.0line, API may still change. - Platform focus: Windows (PowerShell). macOS/Linux work but are less validated.
The key idea: a live Next.js server, not a static export
NextOP does not statically export Next.js. Instead it runs a live Next.js HTTP server inside the Electron main process:
Electron app.whenReady()→ startNextServer(): next({ dir, dev }) + http.createServer → 127.0.0.1:<port>→ BrowserWindow.loadURL("http://127.0.0.1:<port>")
Consequence: every Next.js feature works — App Router, SSR, Server Components, Route Handlers,
Server Actions, middleware, next/image. This is the differentiator versus static-export-based
desktop wrappers.
Cost: Chromium + Node + a live Next server is the heaviest runtime profile among comparable frameworks. This weight is inherent to the design, not a bug.
Same runtime model for dev and production
main.ts runs the Next server in-process for both modes:
- dev →
next({ dir: process.cwd(), dev: true }) - production →
next({ dir: app.getAppPath(), dev: false })against the prebuilt.nextoutput.
The server binds to 127.0.0.1 only (never the LAN), and loadURL uses 127.0.0.1 to match
(avoiding IPv4/IPv6 mismatch). Port preference is 3000, falling back to an OS-assigned free port
on EADDRINUSE (race-free — the server binds the port itself and reports the actual one).