
Building a desktop application with Next.js and Electron is a game-changer for developers who want to create fast, scalable, and engaging experiences.
With Next.js, you can build server-side rendered (SSR) and statically generated websites, but did you know that you can also use it to build desktop applications with Electron?
Electron is a framework for building cross-platform desktop applications using web technologies such as JavaScript, HTML, and CSS. Next.js and Electron can be used together to create desktop applications that are fast, scalable, and easy to maintain.
By using Next.js and Electron, you can leverage the strengths of both frameworks to build desktop applications that are highly performant and engaging.
Check this out: Nextjs App
Setup and Configuration
To set up your project, start by opening the package.json file with your preferred text editor or IDE. You'll need to modify the build and dev scripts, and add the main property.
The concurrently package will be used to run both Next.JS and Electron in parallel during development, so point the main script to the entrypoint of your Electron application. You'll also need to add "author" and "description" attributes for building application executables.
When developing with npm run dev, both Next.JS and Electron will start, and when building your application with npm run build, it will build the Next.JS files first, then the Electron application.
You might enjoy: Start Next Js App
Install Other Dependencies
To set up your project, you'll need to install Electron and other dependencies. Install Electron by running `npm install electron` in your project folder.
Navigate to your project folder, which in this example is electron-nextjs-project.
Next, install the project dependencies using npm install.
Consider reading: Npm Next Js
Setup
To start setting up your project, navigate into your project folder and install the necessary dependencies. Install Electron and other dependencies using the following commands:
cd into your project folder and install the following dependencies, with both following commands:
Dev dependencies:
Project dependencies:
Open the package.json file with your preferred text editor or IDE and modify the build and dev scripts, as well as add the main property. You need to point the main script to the entrypoint of your Electron application.
Modify the package.json file to add "author" and "description" attributes, both needed when building the application executables.
Related reading: Add Image to Next Js
Making Things Native
Making things native is a crucial step in creating a seamless user experience. To achieve this, you can start by fixing the default window title bar, which looks rather ugly. This can be done by adding a new option when creating the window in main/background.ts.
Vadim Demendes' article "Making Electron apps feel native on Mac" is a great resource for learning more about making things native. It's a great primer on the subject and worth checking out.
Adding a single line of code to customize the window title bar can make a huge difference.
Worth a look: Title of Specific Page Nextjs
Building and Publishing
Building the application executables is a crucial step in the Electron Next.js process. You'll need to create a file called electron-builder.yaml on the root of your project and specify the necessary options according to the official electron-builder documentation.
To build the application, run npm run build on your terminal, and the Next.JS static files will be generated and exported to the out/ directory. The Electron application will then be compiled and saved to the dist/ directory.
Electron Builder is a great tool for bundling the Electron app, and you can add some configuration to electron-builder.yml for convenience. You can also add scripts to package.json to simplify the process.
You might like: How to Run Next Js App
Expose Minimal API to Renderer
You can't just import the ipcRenderer object directly inside your Next.js code, because it relies on privileged filesystem access which the renderer is not granted.
To expose a bridge between the processes, you need to set up a preload script. Nextron comes with a basic preload script, but you can replace it with your own to define a more concrete API.
Don't be tempted to expose the ipcRenderer object directly, run business logic, or expose a 'catch-all' method in your preload script, as this increases the attack surface for potential bad actors.
In our example, we're going to define a more concrete API to keep our application secure and maintainable.
Recommended read: Api Directory Nextjs
Building Executives

To build our application executables, we'll use electron-builder. This tool will handle the process for us.
Start by creating a file called electron-builder.yaml on the root of our project. Inside this file, specify the configuration for building the application, according to the official electron-builder documentation.
After properly specifying the needed options in the electron-builder.yaml file, run npm run build in your terminal. This will generate the Next.JS static files, export them to the out/ directory, and compile the Electron application, saving it to the dist/ directory.
You can add a script to package.json for convenience, which will help streamline the process.
The build process will create a bunch of assets in the dist directory, including a binary that can be run to test our application.
If this caught your attention, see: What Is Src Directory in Next Js
Development and Testing
Electron Next.js applications can be developed and tested using a variety of tools and techniques.
To get started with development, you can use the built-in development server provided by Next.js, which allows for hot reloading and live reloading.
Intriguing read: Nextjs Development Company
For testing, Jest is a popular choice for Electron Next.js applications, as it provides a lot of built-in support for testing React components and can also be used for testing Electron-specific code.
By using Jest, you can write unit tests and integration tests for your application, and run them with a single command.
Readers also liked: Electron with Nextjs
Development Mode
Development Mode is a great way to get started with building your Electron app. Run npm run dev, and nextron automatically launches an electron app.
To take it to the next level, you can run your app in development mode with a simple command. This will give you a seamless testing experience.
In development mode, you'll get instant feedback on any changes you make to your code. This is especially useful when you're experimenting with new features or bug fixes.
Running your app in development mode also allows you to quickly identify and fix any issues that arise. This saves you time and effort in the long run.
Readers also liked: Next Js Strict Mode
Navigating Between Pages

Navigating between pages is crucial for giving your app more interactivity and purpose. In our example, we used a React Context Provider to solve this problem.
Implementing navigation between pages allows users to move through your app with ease. This was achieved by using a React Context Provider, as shown in part two of our example.
A React Context Provider is a powerful tool for managing state across your app. By using it to implement navigation, you can create a seamless user experience.
In our example, the React Context Provider was used to manage navigation between pages. This allowed us to create a more interactive and engaging app for our users.
With navigation in place, your app will feel more like a living, breathing entity. Users will be able to move through your app with ease, discovering new features and functionality along the way.
By leveraging the power of a React Context Provider, you can create a navigation system that's both efficient and effective. This will help you build a better app, faster.
A fresh viewpoint: Next Js App vs Pages
But..
But there are some potential issues to consider. NextJS has a possibility to use custom servers, but it may be more difficult to integrate with Electron in a good way.
This could add extra complexity to your project. Integrating custom servers with Electron can be tricky, and it may require some extra effort to get it right.
Using custom servers with NextJS will also make your app more heavy. This is because the custom server will run a NodeJS server behind the scenes, which can add to the overall size and weight of your application.
Your users will be able to access your front-end outside of your desktop app. For example, NextJS will run on localhost:3000 and your Electron will render that URL on the BrowserWindow, but it also allows your users to open a browser and access localhost:3000 directly.
Take a look at this: How to Run Nextjs to Build
Conclusion
In conclusion, development and testing are crucial steps in the development process.
Using Next.JS to build desktop applications with Electron is a good idea, especially when you want to use React alongside with Next.JS features.
It shouldn't be a pain, and using Nextron it could be, but starting from scratch is the best approach.
This guide has provided an approach to handle the challenges of building desktop applications with Electron and Next.JS.
Starting from scratch allows you to take full advantage of Next.JS features, such as easy routing, without any hassle.
I personally believe that this approach is the way to go, and I hope that this guide may help somebody else who is facing similar challenges.
Related reading: Using State in Next Js
Repository Files Navigation
Repository Files Navigation is an essential part of any development project. To navigate through your repository files efficiently, you should be aware of the key files to look out for.
The Next.js App has a crucial file called next.config.mjs that you should familiarize yourself with. This file is often overlooked but is vital for customizing your Next.js application.
Explore further: Next Js Directory Structure

Electron App, on the other hand, relies heavily on its package.json file, which contains metadata and scripts for your project. Having a clear understanding of this file will help you manage your dependencies and scripts effectively.
Here are some key repository files to keep an eye on:
- Next.js App - next.config.mjs
- Electron App - package.json
Security and Updates
Security and updates are crucial aspects of building a robust Electron app. You should treat the user's computer as you would a business-critical server, except with even more care and attention.
To ensure the security of your Electron app, you should consider implementing the four applicable recommendations from the Electron Security Checklist: defining a Content Security Policy, disabling or limiting navigation, disabling or limiting creation of new windows, and validating the sender of all IPC messages.
These enhancements might not be necessary for a proof of concept, but they're essential for any distributed application. You can find the full list of recommendations on the Electron Security Checklist.
Here are the four security recommendations in a concise format:
- Define a Content Security Policy
- Disable or limit navigation
- Disable or limit creation of new windows
- Validate the sender of all IPC messages
Enabling application auto-updates is also a must-have for a seamless user experience. This will allow you to ship small, incremental updates as often as you like without inconveniencing your users.
Security Note
Security is a top priority when developing applications, especially those that interact with a user's file system. We have a responsibility to our users to ensure their security.
The browser sandbox can only protect us to a certain extent, so we need to take extra steps to prevent malicious exploitation. This is why checking against the Electron Security Checklist is crucial.
There are four key recommendations from this checklist that we should consider implementing: Define a Content Security Policy, Disable or limit navigation, Disable or limit creation of new windows, and Validate the sender of all IPC messages.
These enhancements may not be implemented today, but it's essential to keep security at the forefront of our minds as we develop applications.
Distribution and Updates via GitHub
Distribution and updates via GitHub are crucial for a seamless user experience.
Enabling application auto-updates is a must, allowing you to ship small, incremental updates without inconveniencing your users.
This process isn't particularly intuitive, but it's easy enough once you know what you're doing.
Users don't have to go looking for new versions of your application when they're available, which is a huge advantage.
Calling it a day with just a proof of concept might be tempting, but it's worth getting auto-updates set up early on.
Expand your knowledge: Next Js Single Page Application
Background and Motivation
Electron's native way of providing access to system APIs is via IPC or Electron Remote, but these methods can be cumbersome and heavy to maintain, especially in large apps.
This led to the search for a more elegant solution, which is where React Server Components (RSC) come in. RSC allows developers to colocate all logic in the Web app, making Electron a thin layer that just opens a window.
With RSC, you can use Electron APIs directly from server components, removing the need for IPC or Remote, and allowing for much more rapid development and less maintenance of the protocol between Web and Electron apps.
Here's an interesting read: Rsc Nextjs
Background: Why?

I wanted to keep sensitive data like encryption keys on the user's computer, where the operating system could handle it securely. This is because the operating system is built and battle-tested by experts who know more about encryption than I do.
I had been looking for an excuse to try out Electron, and this project provided the perfect opportunity.
Electron is a great tool for building cross-platform desktop applications, and I wanted to see how much of the stack I was familiar with could be brought over to a new platform.
Here's an interesting read: Cms System Next Js
Motivation for React Server Components
React Server Components offer a more elegant solution to accessing system APIs in Electron, compared to traditional IPC or Electron Remote. This is because they eliminate the need for complex handshake protocols and error handling.
The absence of a dedicated RESTful API or GraphQL API is a key benefit of RSC in client-server web development, allowing developers to skip designing, maintaining, and interacting with these APIs.
In traditional Electron development, you'd need to design and maintain APIs, which can become cumbersome and heavy in large apps. With RSC, all logic can be colocated in the Web app, making Electron a thin layer that just opens a window.
Using Electron's safe storage and reading from/writing to the file system directly in a React Component is a great example of colocation in action. This approach reduces the need for complex protocols and makes development and maintenance much easier.
By running an RSC server in Electron, you can remove the boundary between the Renderer and Main processes, while still keeping everything secure. This also allows you to shift heavy tasks from the browser to Node.js, making load distribution more flexible.
Next.js App Router
Next.js App Router is a powerful tool that allows you to use the same codebase for both web and desktop applications.
This boilerplate demonstrates a turborepo setup combining Next.js with Electron, enabling you to use the same codebase with SSR (Server-Side Rendering) and React Server Components (RSC) for Electron applications.
With Next.js App Router, you can take advantage of its features such as server components and static site generation to create fast and efficient desktop applications.
For more insights, see: Nextjs App Folder
Next.js App Router with SSR and Server Components
The Next.js App Router supports Server-Side Rendering (SSR) and React Server Components (RSC) for Electron applications.
This means you can use the same codebase for both web and desktop applications.
With SSR, your application can render on the server, improving performance and SEO.
Server Components in Next.js App Router allow for faster and more efficient rendering of components.
This setup is made possible by a turborepo setup combining Next.js with Electron.
A unique perspective: Next Js Client Side Rendering
What Is Nextron?
Nextron is a preconfigured, opinionated Electron app that uses Next.js for the Electron renderer process.
It saves developers from making common mistakes and setting up boilerplate, providing sensible defaults to get them up and running quickly.
In development mode, Nextron starts two processes: a vanilla Next.js development server and an Electron process that loads the localhost URL of the Next.js development server into a browser window.
Production builds bundle a Next.js Static Export into the distributed application, which are loaded into the Electron window using electron-serve – no external server required.
As of April 2024, Nextron v8.15.0 ships with Next.js 13.5.6, so you can skip the following configuration updates.
Running and Testing
To run the Electron app, you need to have built the Next.js app first, as Electron expects the production output to be present and copied to the Electron app.
You can build the Electron app using a command, but you'll need to ensure you have the Next.js app built before running the Electron app.
To build the application, you can use a command that invokes electron-builder to package everything up into distributable artifacts.
The build process will create a static export of the "frontend" application and build the main "backend" process. When it completes, you'll end up with a bunch of assets in the dist directory.
Lurking in the mac-arm64 directory is a binary which you can run to test your application.
You can run this binary to test your application, and voila! You'll have a desktop application you can click on rather than run from a terminal.
Going Beyond
The app will only show a feed of the most recent commits across all repositories, in date order, like a Twitter timeline for nerds. This is the very basic functionality outlined in the article.
To achieve this, the preload script creates a global ipc object which can be accessed from the Next.js renderer code via window.ipc. This is a crucial step in implementing the app's functionality.
The app will select folders on their filesystem representing one or more git repositories. This is the first step in showing the feed of recent commits.
Here's a list of what the app will do:
- Select folders on their filesystem representing one or more git repositories
- Show a feed of the most recent commits across all repositories, in date order
It would be pretty easy to make the app do a lot more, like allowing users to pull changes from remote repositories and updating the user's feed accordingly.
Frequently Asked Questions
What is the replacement for Electronjs?
If you're looking for alternatives to Electronjs, consider frameworks like Tauri, Proton Native, and Avalonia, which offer similar cross-platform desktop app development capabilities. Each has its own strengths and use cases, so explore them to find the best fit for your project.
Featured Images: pexels.com


