Over the years, we’ve had creatives develop different methods for creating desktop applications using web technologies. Successful frameworks such as Electron and Tauri have aimed to fix the drawbacks of previous options.
To this end, we now have Gluon, a new promising framework for creating desktop apps with web technologies. Gluon was built to fix a particularly prominent issue with previous solutions — the bundled application size.
Throughout this article, we’ll explore:
We will be using the Gluon examples repo to explore its various features and use cases.
Gluon is a new framework that lets you build desktop applications with HTML, CSS, and JavaScript.
Unlike other desktop frameworks for web development, Gluon doesn’t bundle your application with the Chromium engine or browser webview. It instead uses the client’s installed browsers to render its application.
Gluon’s tiny bundle size is one of its major edges. A typical application weighing around 220 MB when bundled with Electron.js and about 1.8 MB when built with Tauri might weigh a little less than 1 MB when bundled with Gluon.
Additionally, Gluon is pretty easy to use. You don’t have to learn any additional languages or patterns to start building desktop applications. In comparison, Tauri requires having at least a little Rust knowledge.
Finally, like other solutions, Gluon also lets you bundle applications for different platforms. Gluon currently supports Chromium-based browsers and Firefox and lets you build with Node.js, Bun, and Deno, which is not currently available in other major frameworks.
Gluon doesn’t currently support hot reload. For any changes you make, you’d need to restart your application to reflect the changes.
Additionally, Gluon will currently execute any browser command you run in its app window. For example:
And so on. While this may seem useful, it can also limit Gluon’s ability to provide users with a consistent, native desktop experience.
You also can’t work with Gluon if you don’t have a supported browser installed. However, this may be a negligible issue, considering almost everyone is likely to have at least one of the supported browsers installed.
Again, Gluon is in its early stages, and its drawbacks will undoubtedly be addressed in future releases.
Gluon is still in its alpha testing phase. For this reason, there’s no official installation medium yet. However, you can try the example bundled with it by following the steps below.
First, clone the Gluon examples repo using the following command:
git clone https://github.com/gluon-framework/examples.git
This repository contains different Gluon example apps. Move into the gluworld
example and install the required packages with the commands below:
cd gluworld npm install
Once the packages are installed, you can now start the application:
node .
After running the command above, you should see an output similar to the image below:
Gluon’s architecture is pretty simple, divided into two components — a Node.js and Deno script to manage your app windows, and the web frontend to build your application interface.
If you open the gluworld
project in your text editor, you should see the following:
index.html
fileindex.js
filenode_module
folderThe index.js
file serves as the entry file. It imports Gluon, which contains a function that lets us create new windows via the Gluon.open()
method. Here, we can set the markup file our window should open, the window’s default size, and many other configurations:
import * as Gluon from "@gluon-framework/gluon"; (async () => { const Window = await Gluon.open("index.html", { windowSize: [800, 500], }); })();
Furthermore, our new application can’t access external content by default for security reasons. However, there are cases where we want to override this setting. Gluon lets us do this easily by simply adding the allowHTTP
option to its initialization as shown below:
const Window = await Gluon.open("index.html", { allowHTTP: true, // other options? });
Gluon already provides support for different methods, events, and APIs that are necessary when building desktop applications. Some of these include the page, controls, and the IPC API.
The page API lets us retrieve information about the current page we’re on and additionally lets us enhance this page as preferred. Currently, we’re able to minimize and maximize a page dynamically, alter the page title, and sleep or hibernate a page to save memory:
// PAGE API: Update page title let newTitle = "New Page Title" await Window.page.title(newTitle); // CONTROL API: Minimize and Maximize the window Window.minimize(); Window.maximize(); // Hibernate the window Window.idle.hibernate();
Gluon also features an inter-process communication (IPC) API that lets you communicate with your application from the main window process:
Window.ipc.on('someEvent', (data) => { // action on someEvent triggered }); // Trigger event from front-end Window.ipc.send('someEvent', { foo: 'bar' });
Additionally, the IPC API lets you expose functions between your application and share common data:
Window.ipc.myFunc = (...args) => { // some action }; // OR Window.ipc.expose('myFunc', (...args) => { // some action });
Another major use case of the IPC API is that you’re able to trigger Node.js-related code directly from your application frontend. Below is an example from Gluon docs of how the IPC API is used to expose the filesystem writeFile()
method to the frontend:
import * as Gluon from '@gluon-framework/gluon'; const Window = await Gluon.open('https://gluonjs.org'); // Expose our own function to write messages to a log file import { writeFile } from 'fs/promises'; let log = ''; Window.ipc.log = async msg => { log += msg; // Add to log return await writeFile('app.log', log) // Write to log file .catch(() => false) // Return false on error .then(() => true); // Return true on success };
Since Gluon directly uses the system browser, browser APIs are most definitely supported, and can be utilized like you would in a normal web application. Update your index.html
file with the code below to see this in action:
<!DOCTYPE html> <html> <head> <title>Battery Level Demo</title> </head> <body> <div class="con"> <div> <h1 id="battery-level"></h1> <br /> <progress id="battery-progress" value="0" max="100"></progress> </div> </div> <script> navigator.getBattery().then((battery) => { var batteryLevel = document.getElementById("battery-level"); var progressBar = document.getElementById("battery-progress"); batteryLevel.innerHTML = "Battery Level: " + Math.round(battery.level * 100) + "%"; progressBar.value = Math.round(battery.level * 100); battery.addEventListener("levelchange", function () { batteryLevel.innerHTML = "Battery Level: " + Math.round(battery.level * 100) + "%"; progressBar.value = Math.round(battery.level * 100); }); }); </script> </body> </html>
In the code above, we’re using the native Battery Status API to get the current percentage of our device battery and display it in our application. Running this code, you should see an output like the one below, with the battery information updating in real-time:
In contrast to other major desktop frameworks, Gluon is already promising. As highlighted in the benchmark table on GitHub and shown in the screenshot below, Gluon has the advantage over Electron, Tauri, and Neutralinojs in terms of build size, memory usage, and build time:
However, other things you might want to put into consideration are the features and community support you get from the other frameworks.
For example, when building applications with Electron, you’ll have additional features such as in-app purchases, auto-updates, and touch bar configuration, as well as a robust community. Meanwhile, Tauri provides an upper hand for developers already familiar with the Rust language.
Throughout this article, we explored Gluon, a new framework for building desktop applications with web technologies. We covered how it works, how to get started using it, and how it compares with other web-desktop development frameworks.
Gluon is still pretty new and has a lot of potential to grow into something bigger in the near future!
Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third-party services are successful, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens while a user interacts with your app. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.
LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. Start monitoring for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowCompare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.