Now create desktop app with Next Js

Next.js is a popular JavaScript framework that allows developers to build server-rendered, statically generated and client-side web applications. While it is typically used for building web applications, it is also possible to use Next.js to create desktop apps.

In this tutorial, we will be showing you how to use Next.js and TailwindCSS to build a desktop app. We will be using Electron, which is a framework for building cross-platform desktop applications with web technologies, to package our Next.js app as a desktop app. Electron allows us to take our web app and wrap it in a native container, giving it the same functionality as a traditional desktop app.

By the end of this tutorial, you will have a basic understanding of how to use Next.js and Electron to build a desktop app. You will also have a working desktop app that you can run on your computer.

Initialize the project

To begin, copy and paste the following code into your terminal to initialize a new project using Next.js, TailwindCSS and ElectronJs

npx create-nextron-app my-app --example with-javascript-tailwindcss

This will create the folders of the app, cd into that directory and install the packages using npm install or yarn .

After that you will be able to see a folder structure that looks like this:

You can see a similar folder structure to that of a bare next js app in the renderer folder. And we will be working on that only

Write npm run dev or yarn dev in your terminal of vs code and you will be able to see your electron app pop out

Initial Configuration for Next Js

In the pages folder, you will see that there is a file named home.jsx , which is equivalent to index.js file in normal Next js applications. Go ahead and rename the home.jsx to index.jsx . You will see the default 404 page of Next js in the window.

To make this thing correct, we will navigate to the background.js file under the main folder and change the following lines:

Now, the renderer folder looks exactly like that of a new Next Js app.

Let's start coding 🫡🫡

What are we making

We will be making a simple javascript code editor. Here's a preview

Coding the app

Paste this code in the app.jsx file so that the layout looks pretty 💘

import React from "react";

import "../styles/globals.css";

function MyApp({ Component, pageProps }) {
  return (
    <div className="bg-gray-700 max-w-screen min-h-screen text-white">
      <Component {...pageProps} />
    </div>
  );
}

export default MyApp;

Now go to the global.css file in the styles folder and remove everything except these

@tailwind base;
@tailwind components;
@tailwind utilities;

Now you have your beautiful app layout. Head on to the index.jsx file and remove everything. Then paste the code below

import React from "react";
import Head from "next/head";

function Home() {
  return (
    <div className="w-screen h-screen flex items-center justify-center relative">
      <Head>
        <title>Code Editor</title>
      </Head>
    </div>
  );
}

export default Home;

Creating the code editor

In this tutorial, we will be utilizing the react-ace library to build a code editor component for our application. So, go ahead and install the react-ace package.

Create a folder named components inside the renderer folder and then create a new file. In my case, it is CodeEditor.js . Below is the given code of that file. To use any other language, you will need to import it using import "ace-builds/src-noconflict/mode-<language>" . Where <language> stands for the language you want to use. Now, for using any other theme, you have to import that using import "ace-builds/src-noconflict/theme-<theme>" .

import React, { useEffect, useState } from "react";
import AceEditor from "react-ace";

import "ace-builds/src-noconflict/mode-javascript";
import "ace-builds/src-noconflict/theme-twilight";
import "ace-builds/src-noconflict/ext-language_tools";

const CodeEditor = () => {
  const [code, setCode] = useState("");

  return (
    <div className="w-[90%] md:w-[70%] flex h-max items-center justify-center shadow-xl">
      <AceEditor
        mode="javascript"
        theme="twilight"
        onChange={(e) => setCode(e)}
        name="coding_area"
        editorProps={{ $blockScrolling: true }}
        value={code}
      />
    </div>
  );
};

export default CodeEditor;

Let's import this file into the index.jsx file and see how it looks

import React from "react";
import Head from "next/head";
import CodeEditor from "../components/CodeEditor";

function Home() {
  return (
    <div className="w-screen h-screen flex items-center justify-center relative">
      <Head>
        <title>Code Editor</title>
      </Head>
      <CodeEditor />
    </div>
  );
}

export default Home;

If you stop the server and restart it, you will see this error

This is coming due to server-side rendering of Next Js. The window object is only defined in the browser, so if you are trying to start the server on the server-side (e.g., using Node.js), the window object will not be defined.

We have to dynamically import the component inside the directory

import React from "react";
import Head from "next/head";
import Link from "next/link";
import dynamic from "next/dynamic";

// Dynamically importing the component
const Editor = dynamic(import("../components/CodeEditor"), { ssr: false });

function Home() {
  return (
    <div className="w-screen h-screen flex items-center justify-center relative">
      <Head>
        <title>Code Editor</title>
      </Head>
      <Editor />
    </div>
  );
}

export default Home;

Now, restart the server and you will see this beautiful screen

Styling the Editor

To customize the code editor, you may want to consider using various props provided by the react-ace library. For a complete list of available props, please see the documentation here: github.com/securingsincity/react-ace/blob/m... Below, we have provided the code to beautify the editor using some of these props:

// components/CodeEditor.jsx
import React, { useEffect, useState } from "react";
import AceEditor from "react-ace";

import "ace-builds/src-noconflict/mode-javascript";
import "ace-builds/src-noconflict/theme-twilight";
import "ace-builds/src-noconflict/ext-language_tools";

const CodeEditor = () => {
  const [code, setCode] = useState("");

  return (
    <div className="w-[90%] md:w-[70%] flex h-max items-center justify-center shadow-xl">
      <AceEditor
        mode="javascript"
        theme="twilight"
        onChange={(e) => setCode(e)}
        name="coding_area"
        editorProps={{ $blockScrolling: true }}
        setOptions={{
          enableBasicAutocompletion: true,
          enableLiveAutocompletion: true,
          enableSnippets: true,
        }}
        showGutter={false}
        className="rounded-lg"
        style={{ width: "100%" }}
        onLoad={(editor) => {
          editor.renderer.setPadding(20);
          editor.renderer.setScrollMargin(20);
        }}
        maxLines={100000}
        minLines={30}
        wrapEnabled
        value={code}
      />
    </div>
  );
};

export default CodeEditor;

Your app should look like this if you write the following stuff

Building the app for your pc

Go ahead and paste npm run build or yarn build in your terminal to start the build

A new dist directory has been built at the root of the project. Since I am using windows, it has created a setup.exe file for me. Install it and your app is ready

Conclusion

In this article, we walked through the steps of creating a desktop app using Next.js. From setting up a new project and installing the necessary dependencies to customizing the user interface and adding features like syntax highlighting, we covered all the basics of building a desktop app with Next.js. By following these steps, you should now have a solid foundation for creating your desktop apps with Next.js. Whether you are looking to build a simple app for personal use or a more complex app for professional purposes, Next.js provides all the tools you need to get started