Here are few ways to launch your new desktop applicating built with swing-ui GUI for each operating system.
On Windows
In Terminal
The simplest way to launch the app is in terminal. Use it to see the console output. Example:
node index.jsWith VB Script (without terminal)
Create a VB Script file, such as start.vb with the following script (adjust command for your project):
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run "node ""index.js""", 0, FalseSimply double-clicking the script file should start the script and launch your app. Make sure your application already works and shows a window before doing this, otherwise it will be running in the background you may not even know it.
Other Executable Launcher
- A simple C++ or C# application can be made that runs the command
node index.js. - A Bat To Exe Converter can convert your
start.batscript to an executable that starts your custom command. - Your custom windows shortcut can launch a nircmd.exe file, which can start your node application without a terminal window.
On Linux
In Terminal
While developing the app, it can be started from a command line in terminal, such as node index.js, but soon you may want to create an app launcher icon for it.
Here is how to do it:
App Launcher Icon
Create a my-app.desktop text file that will become an app launcher icon for your application in ~/.local/share/applications directory (a common directory of application icons that appear in standard menu.
For StartupWMClass field enter your appplication name just like it appears in your package.json file. This will make the icon specified in this file associate with your application’s WM_CLASS, which is same as you application name. For Exec field enter the command to run to execute your application. For Icon field use an absolute path to a PNG image icon. For Categories field enter the categories related to your application. Look up full list of category names. Here is an example:
[Desktop Entry]
Type=Application
Name=My Calculator
Icon=/absolute/path/to/icon.png
Exec=/usr/bin/node /absolute/path/to/your/project/index.js
StartupWMClass=my-calculator
Categories=Development;IDE;
NoDisplay=trueYou may need to run this command to force reload app icons for the icon to appear in menu and show correct icon for your application:
update-desktop-database ~/.local/share/applicationsOn macOS
A macOS .app file is actually a directory containing a specific folder structure and an Info.plist file that describes the application.
In this tutorial, we will create a simple application called My App from scratch.
1. Create the .app directory
Open Terminal in your desired directory and create a directory named My App.app.
The .app extension is important. macOS recognizes directories with this extension as application bundles.
Run these command to create more required directories inside .app directory:
mkdir -p "My App.app/Contents/MacOS"
mkdir -p "My App.app/Contents/Resources"We now have:
My App.app/
└── Contents/
├── MacOS/
└── Resources/
The three most important parts of a basic application bundle are:
Contents/MacOS– contains the executable that macOS launches.Contents/Resources– contains application resources such as icons.Contents/Info.plist– contains the application’s metadata and configuration.
2. Create the application launcher
Inside My App.app/Contents/MacOS/ create a text file named My App without any extension.
For your Node.js application, we can make this file a shell script that starts Node.js.
Put the following into My App:
#!/bin/bash
# sets working directory to application's root directory
APP_DIR="$(cd "$(dirname "$0")/../Resources/app" && pwd)"
cd "$APP_DIR"
exec node index.jsThis launcher determines the location of the application and then executes node app.js.
The resulting structure is:
My App.app/
└── Contents/
├── MacOS/
│ └── My App
└── Resources/
Make the launcher executable:
chmod +x "My App.app/Contents/MacOS/My App"3. Add the Node.js application
For this example, let’s put the Node.js application inside the application bundle.
Create:
My App.app/Contents/Resources/app/
and put your Node.js application there:
My App.app/
└── Contents/
├── MacOS/
│ └── My App
│
└── Resources/
└── app/
└── index.js
The important thing is that the launcher we created earlier looks for Contents/Resources/app/index.js and executes it with Node.js.
4. Create Info.plist
Now create this file:
My App.app/Contents/Info.plist
Info.plist is one of the most important files in a macOS application bundle. It tells macOS what the application is called, which executable to launch, what its bundle identifier is, which icon to use, and what permissions the application requires. Modify it for your application:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>My App</string>
<key>CFBundleDisplayName</key>
<string>My App</string>
<key>CFBundleIdentifier</key>
<string>com.example.myapp</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleExecutable</key>
<string>My App</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIconFile</key>
<string>MyApp.icns</string>
<key>NSCameraUsageDescription</key>
<string>My App needs access to the camera.</string>
<key>NSMicrophoneUsageDescription</key>
<string>My App needs access to the microphone.</string>
</dict>
</plist>5. Create the application icon
macOS uses the .icns format for application icons.
Start with a square PNG image, preferably 1024×1024 pixels.
For example MyApp.png.
Create a temporary iconset directory on your Desktop named MyApp.iconset.
A complete iconset should contain multiple resolutions:
MyApp.iconset/
├── icon_16x16.png
├── icon_16x16@2x.png
├── icon_32x32.png
├── icon_32x32@2x.png
├── icon_128x128.png
├── icon_128x128@2x.png
├── icon_256x256.png
├── icon_256x256@2x.png
├── icon_512x512.png
└── icon_512x512@2x.png
The @2x images contain twice as many pixels as their corresponding normal-resolution images.
6. Convert the iconset to .icns
macOS provides a command-line utility called iconutil for creating .icns files.
Run:
iconutil -c icns MyApp.iconsetThis creates MyApp.icns file. Copy it into My App.app/Contents/Resources/.
The application now has:
My App.app/
└── Contents/
├── MacOS/
│ └── My App <-- text file with a file extension
│
├── Resources/
│ ├── MyApp.icns
│ └── app/
│ └── index.js
│
└── Info.plist
Because Info.plist contains CFBundleIconFile key, macOS knows that MyApp.icns is the application’s icon.
7. Launch the application
The application can now be launched from Terminal with open "My App.app" command. You can also double-click My App.app in Finder.
8. The final application structure
At this point, our complete application looks like this:
My App.app/
└── Contents/
│
├── Info.plist
│
├── MacOS/
│ └── My App
│
└── Resources/
│
├── MyApp.icns
│
└── app/
└── app.js
The important concept to remember is that .app** is not a special executable file format**. It is a directory with a specific structure that macOS recognizes as an application bundle.
The Info.plist describes the application, the executable in Contents/MacOS starts the application, and Contents/Resources contains the application’s supporting files.
For a Node.js application using swing-ui, the Node.js application can live inside Resources/app, while the launcher provides the bridge between macOS and the Node.js process.
Important
The camera and microphone entries in Info.plist declare the application’s intended access, and they are optional (only needed if your application will be using those devices). They do not automatically grant access. macOS still controls access through its privacy system and will ask the user for permission when the application attempts to access those resources.
This basic .app bundle is suitable for understanding how macOS applications are structured. Before distributing a production application, additional steps such as code signing and notarization should be added.

