Hacker News new | past | comments | ask | show | jobs | submit login
NeutralinoJS: Lightweight Electron alternative using native browser controls (neutralino.js.org)
347 points by api 43 days ago | hide | past | web | favorite | 190 comments

I feel like nobody cares too much if they’re running one Electron app; people do have the headroom for an extra 1-2GB of RAM usage. The problem comes when they run several Electron apps at once, and each comes with its own “base” overhead (i.e. the runtime memory consumption of the browser-runtime as a whole, independent of how many render contexts are open.)

Chromium is built to share a lot of things between tabs efficiently, but this economy-of-scale doesn’t translate over into having multiple instances of Chromium running. Each instance gets its own GPU renderer process + font-glyph tile cache, its own network-request cache (i.e. its own in-memory key-value store with its own LRU limit), etc. Running multiple Chromium instances at once is a bit like running multiple copies of an RDBMS on the same machine and expecting them to not fight over memory.

Does anyone know what exactly this “base” overhead in Chromium consists of; and, more importantly, how often it changes relative to Chromium releases? Because I’m wondering whether it’d be possible to factor most of it out into a separate layer from the highly-iterated-on “browser engine” DLL stuff (the renderer + DOM + JS layer) into its own sort of “Chromium Core Services” DLL, which could be relatively-more ABI-stable.

If you had that factoring-out, you could achieve a pretty good memory + CPU savings just by having Chromium + application frameworks like Electron all share one copy of the Chromium Core Services between them, while keeping their own higher-level “renderer+VM” DLL on top (which would hopefully be pretty stateless in terms of shared state, only adding the ~50MB mmap(2) overhead of the DLL-image itself, and then whatever memory the individual render-contexts consume.)

Alternately, of course, you could build Electron as a pseudo-browser where Electron “apps” are just separate windows running in its memory space, and the native Node processes are all just distinct V8 Execution Contexts in the same process. But 1. this would lose you the ability to develop for a particular version of the renderer, which is what Electron gains you over projects like Neutralino in the first place; and 2. this wouldn’t give you the benefit of Electron sharing service-memory with Chrome itself.

i believe (but may be mistaken) that this was a goal of mozilla's positron project -- an electron-compatible runtime that uses firefox instead of chromium, but shares most resources across all of the positron apps running on your system so that it's more like having multiple tabs open rather than having multiple distinct instances open.

This paradigm is already supported by Container Tabs. It seems like Firefox is really close to the ideal of sharing memory without sharing user data.

Where is this 1-2GB number coming from? I'm running a fairly large Electron app and the combined memory usage of its processes is about 250-300MB.

I’m currently running three Electron apps: Spotify, Skype, and VS Code.

Spotify: 1083.7 MB. VS Code: 890.9 MB. Skype: 406 MB.

In the past, I’ve had projects open in VS Code which have caused that number to shoot up into the multi-gigabyte range.

Of course this is all anecdotal but I am pretty sure these numbers come from actual experiences that people are having with Electron apps.

I wish this urban legend would just stop: the Spotify desktop client is NOT an Electron app, it's a CEF (Chromium Embedded Framework) app.

Well, it runs an instance of Chromium. So basically the same thing in this context.

seems like the same shit to me, uses a lot of RAM, lags randomly, yup I usually call that electron :>

Same thing, just another name.

Wow. I've got Apple Music/iTunes running for a week or so on this Catalina macOS and the process viewer reports 300MB (including sub-processes). I assume it's a native application. How does Spotify manage to use so much RAM??

The Spotify desktop client is architected such that each pane in the main window is essentially its own separate webapp, complete with duplicate (and triplicate, quadruplicate, etc) dependencies. They did this so their various teams don’t have to talk to each other.

Desktop Spotify has been a resource hungry mess for years now. It used to be known for prematurely wearing out SSDs by constantly writing stuff (cache I think?) to disk.

> It used to be known for prematurely wearing out SSDs by constantly writing stuff (cache I think?) to disk.

They were constantly vacuuming some SQLite database.[0]

[0] https://arstechnica.com/information-technology/2016/11/for-f...

Does anybody know if this was fixed?

Yes, it was.

They also have this problem where a "Spotify Helper" can crash constantly, and you won't notice it unless you look at the process tree.

On macOS, this will start a ReportCrash process, and end up taking up an entire CPU core just repeatedly crashing, reporting a crash, restarting, etc. It also significantly impacts battery life.

This happens every day for me. It's arguably worse than the SSD-killing SQLite vacuum problem they had.

I haven't seen this one personally, but I get the same crash-loop from the Discord app.

Weirdly enough, the crashes don't seem to affect any of the app's functionality.

> They did this so their various teams don’t have to talk to each other.

This is absolutely dreadful. I've unfortunately worked in multiple organisations where teams deconstructed their web-based products into microservices for this very reason.

I have found it to be rather buggy. I sometimes can't get songs to play, and other times can't get them to pause :) I switched to using their web interface in Firefox which has been totally rock solid.

> They did this so their various teams don’t have to talk to each other.

This is just insane.

Keybase also uses in the range of 600MB-1GB, and 8 processes, most of which don't exit when you exit the application. I'm not sure what Discord uses because I only run it in the browser, but I'm sure it's in the same range as all of the above.

I've come up with a powershell snippet to fully quit keybase and reclaim ~1GB RAM:

get-process | Where-Object {$_.path -match "keybase"} | Stop-Process

>I'm not sure what Discord uses because I only run it in the browser

Me too, and you just made me realize, there already exists a system for running Electron apps in a shared instance of Chrome, and it's installed on almost everyone's computer! You just... open the web version, in Chrome :)

Mind you, there's (sometimes a little, sometimes a lot) more to Electron than a webview. Some apps are running quite a bit of un-sandboxed native code—sometimes even forking off other native processes†—to do what they do. Keybase is, IIRC, one of the apps that are quite large on the "native" side.

† I once designed a system that has Electron install an Erlang release to the client, register it as a service, and start it. The Erlang node runs a locally-bound web server; the Electron app then visits that web server. All the data-wrangling happens in Erlang land, with Electron just serving as an HTML renderer for the pages coming from the local server. And yet Electron's native side is essential, here, because it ultimately manages the Erlang release (installing it, updating it, etc.) Erlang doesn't have any good tooling for doing client-native stuff on its own; Erlang devs find the whole idea of deploying an Erlang release to a client machine funny.

That's fantastic. I wonder if an elixir Phoenix / liveview use case with such a setup is reasonable now that elixir has releases. I think client native nifs are also not out of the question with the better tooling that comes out of modern langs like rust, nim, and my favorite zig.

The irony about that, is that not all electron apps are available from an URL. (now I know there is more than a webpage in a electron app, but with modern browsers you can have the same experience in a electron app or from a webapp pretty easily)

The shorter form, before people complain again that PowerShell is too verbose:

   gps | ? path -m keybase | kill

Discord seems surprisingly efficient for an Electron app.


That's ~230 MB. I can get it up to ~275 MB but it seems to return to normal pretty quickly.

I have VSCode running and it takes up only 166MB or RAM.

Proof: https://i.imgur.com/nKenjcw.png

Over here, the base overhead of an Electron window is around 60MB. How do you know it's not those applications allocating a lot of memory that is causing all this usage?

Of course I don’t know that since I don’t have the time or ability to inspect what the apps are doing. :-) The best I can do is give comparisons to the old non-Electron versions of Spotify and Skype, which had all the same core features as the Electron versions and used less memory for the whole app than you’re saying a base Electron window costs.

It is difficult for me to lay blame at the feet of application developers (assuming they didn’t make the choice to use Electron) when the platform itself is so bad at giving developers ways to manage their apps’ memory usage.

If you want to listen for an event on a global object like `window`, the platform could give a way to do this using a weak reference, but it doesn’t, so you have to make sure to always remember to manually remove the listener yourself or else you’ve just leaked a bunch of stuff.

If you want to load an image, or some other media, the platform could give a way to control the runtime’s internal caches so you aren’t retaining data in memory that you don’t need—but it doesn’t, so you have to hope that the generic runtime memory cache from Chromium is intelligent enough not to retain unimportant things (and, in my experience, it’s not).

This problem has existed in one form or another in every Electron app I’ve ever used. Some are certainly worse than others, but I don’t think I’ve ever seen one come within even an order of magnitude of the memory usage of similar apps written natively.

What's the uptime on that "base application" and what does it do?


~60mb memory usage at startup.

So an "application" that literally just displays Hello World and no indication of uptime.

Right, I'm convinced.

It shows that the framework itself only uses 60MB and implies any higher usage is due to the application built on top of electron. I'm not sure why uptime matters unless you're assuming there are memory leaks?

The context here is that "the framework" does things 'for' the application it is hosting that the application cannot control, caching various things in memory in a way that makes sense for a browser, but not very much sense for a custom application.

Try this: open a new Chrome instance; look at its memory usage; then load a bunch of tabs (try an Open All on a bookmarks folder), close them all again, and then look at Chrome's memory usage again. It will have increased.

Chrome isn't leaking memory; instead, it is doing the same thing that an Operating System does: weakly reserving memory to optimistically cache stuff, releasing it again if there's enough memory pressure.

This works okay if you only have Chrome itself running. (Even then, its cache fights a bit with the OS page cache. It's certainly no Postgres, intentionally getting the OS page-cache to do its caching for it.) But as soon as you have two separate Chromium instances running (e.g. Chrome itself, plus an Electron app), then each one is going to try to "optimistically" cache as much stuff as it can, until it runs into the memory pressure created by the other instance caching as much stuff as it can, and so each instance will unload just a bit to let the other one cache just a bit more—back and forth—forever. Together, they thrash memory, and it becomes much harder for them to actually accomplish the "weak" part of "weak reservation", instead ending up hoarding all the memory between them.

This is the pretty much the same problem you see if you try to e.g. run two memory-heavy JVM processes (e.g. ElasticSearch) on the same system. Chrome is just one of the few times you'll see this "recapitulation of memory management within the runtime" effect client-side, rather than server-side.

Great points, thank you!

What derefr said about Chrome holding on to memory, and additionally memory leaks are absolutely a concern for related reasons.

(Regarding uptime, it's not at all uncommon for Chrome's memory usage to double or even triple overnight. Partially a function of the websites you have open, sure, but also partially a function of Chrome itself).

What’s its uptime? A lot of Electron apps—even ones that use minimal local JS, serving mostly as a webview—accrue base overhead as you use them, then keep it around even when you close their main window (and thus release their main Chromium-side render context), as long as the process stays alive. They’re caching stuff (like, as I said, rendered font glyphs, or network responses.)

I have a copy of Slack running that’s using 2GB right now, with no window open.

They might call this "caching" but it's still a memory leak. Over time, the application consumes increasing amounts of a finite global resource while not appreciably advancing its own progress, and negatively affecting the whole system. That's a memory leak.

The solution is for operating systems to inject deliberate back pressure on memory allocations for user-selectable applications to stop them from behaving this way. "No memory for you. Try mallocing smaller chunk. Maybe I grant; maybe I don't. Maybe I just kill -9 you if you bug me too much." This is exactly how I wish my OS would treat web browsers.

Multiple weeks of uptime (on a laptop that is used daily and hibernates at night).

Currently Slack is taking ~1.2GB on my laptop

I’m spitballing, but Chrome does have issues with high memory usage[0]. But also, VS Code can take up multiple gigabytes[1] on a large project.

[0]: https://lifehacker.com/why-chrome-uses-so-much-freaking-ram-...

[1]: https://stackoverflow.com/questions/53658769/why-vscode-requ...

Given that everyone brings this up every time Electron is mentioned, and Electron apps keep proliferating, I expect a future version of Windows and macOS to have Chromium bundled with the OS. There will be some platform independent open standard that Electron will use under the covers.

Native desktop apps are never coming back. It will either be Electron or mobile apps emulated on desktops.

Behind my two Safari windows is the text editor I use for my technical writing job: BBEdit, a native desktop app. (For coding, though, I prefer to use MacVim, a native desktop app, although I've lately been trying out a beta of the forthcoming Panic Nova, a native desktop app.) I also use Marked, a native desktop app, for Markdown previewing occasionally. Of course, I spend a lot of time in the Terminal, a native desktop app, running command line programs and shell scripts, which are not native desktop apps but are certainly native apps. When I need to run a diff or merge tool, I tend to use Kaleidoscope, a native desktop app. Because I'm in an open office, I sometimes have to resort to headphones, which I primarily use with iTunes, a native desktop app.

Now, as I finish up this response to you in Safari, a native desktop app, remind me what were you saying about native desktop apps again?

Offtopic, but if you’d like an elegant hybrid† Markdown viewing/editing experience, I’d suggest https://typora.io/, another nicely-polished low-memory-consumption native app.

† I don’t know what to call this editing paradigm. It’s somewhere between source-editing and WYSIWYG. Document markup nodes are rendered as their source syntax when your cursor is “inside” them, allowing for plaintext modification of the syntax; but then, when your cursor leaves a node, it switches to rendering as its formatted output instead. You can cursor back into the node to edit it more at any time. It’s pretty unique. It’s the editing style that Slack’s new input box wishes it had.

I use Typora myself, but it's definitely an Electron app (neither native, nor lightweight).


I don’t see Apple going the route of bundling Chromium. Catalyst does allow porting iOS apps to macOS but it’s been not great so far.

I think there will always be a category of people who prefer using native apps for performance, security, or access to OS features. Anecdotally I looked at the apps I have installed and I found out that I don’t have many electron apps on my Mac beside chat apps and VS Code. I suspect non tech-savvy people might have even less, since they do a lot more inside their browsers compared to before.

I’m not sure what you refer to when you say “native desktop apps aren’t coming back”, given that they never left t begin with.

It doesn’t have to be Chromium. It just needs to be a browser that can be linked and launched as an app.

It’s called a “web view” and it already exists in all of the platforms.

WebView is Chromium on Windows now. The holdout is Apple. They are not known to capitulate to industry trends. Maybe this will be the first one they are forced into by popular demand.

Good thing the web is still based on open standards instead of an (advertising) industry trend. We need more viable browser engines, not less.

Current version of Windows already have Chromium in the form of new Edge and Microsoft seems to start pushing progressive web applications. At least they made good integration with system for them.

So, perhaps, soon we will have PWAs instead of bunch of electron apps each carrying its own Chromium.

PWAs can never fully substitute native applications. It's difficult to access hardware and impossible to call operating system functions from a PWA. Applications that do something interesting tend to have a native library behind the frontend that does performance-sensitive work.

Quite the contrary, one of the benefits of PWAs is exactly that when they are distributed via app stores they get access to native APIs without any kind of manual FFI.

That is how they work across ChromeOS, Android and Windows, with Apple being the outlier for obvious reasons.

I didn't know this. If this is true then it's more powerful than Electron, which requires you exchange IPC messages from a separate process. The fact that you have to use the app store is a major disadvantage though.

We had that in Windows 98, it was Active Desktop. It was bloatish and a lot of people disabled it in order to get far more cycles. Heck, IE and Explorer.exe were the same. http://toastytech.com/files/throboff.html

KDE3 did the same with KParts, but it was several times better.

Microsoft was ahead of its time in this. In 2020 we are ready for it. Moore's law has caught up.

It would be less efficient and more wasteful to continue things as normal where every program has its own Electron. People already use Electron type apps. New ones are being made every day. That's not going away. If Microsoft and Apple put this in the OS, it would decrease the user's resource utilization. It's a net win for everyone except maybe chip manufacturers.

As for desktop Linux, GNOME3 already works like Active Desktop did. The whole shell is JS (and the GObject mess down below). I have used a lot of desktop environments. I've been skeptical of the JS eating the world trend. But I have to admit it's smooth. I had bad experiences with KDE (Qt/C++). Not only does it look ugly, it segfaults constantly.

Would it have been better to make a desktop environment in something more, uhh, professional like Go or Java? Of course. But that's not what the crowd decided. There's nothing quite like React for native desktop GUIs. Regardless of your opinion of JS, you have to admit that the React way was a game changer. Since there are no alternatives, the path of least resistance is to simply use React as is for desktop applications, which is exactly what has happened.

If you think this is smooth, you must be new on IT. Xfce already was blazing fast in 2005, even against GNOME 2. Shell is a bloat disaster, and KDE > 3.5.10, a segfaulting fest, but 3.5.10 was rock solid.

I've literally been using desktop Linux since I installed Ubuntu in 2006 in the spinning cubes era. It was never good. Windows (except Vista) always had a snappier interface. Xfce and GNOME2 are fast, I'll give it that, but don't have any animations or aesthetics whatsoever (and yes that does matter--it makes you happy to use your machine). If all I cared about was resource usage, I'd not use a DE at all and only use something like dwm. GNOME3 is polished and works, the best and only free contender to Apple and Windows desktops.

Bloat is something only insiders care about. I care more about adoption of free software than I do about its quality in the academic sense. The way to get adoption is UX and looking nice. If you're trying to convince someone to switch from Windows, what would you show them, Xfce or GNOME3?

Myself, since Debian Woody, when 2.4 was an _optional_ kernel. On snappiness, it depends. On multitasking, KDE3 run circles over XP.

>GNOME3 is polished and works, Not even close. It uses huge loads of RAM while Budgie, while using the same technology, is far snappier. For a current user, I'd suggest Solus with Budgie.

Smooth?! I gave up on it and installed XFCE to get CPU cycles back.

I've only ever used it on expensive hardware so maybe I'm biased.

I have to kill gnome-shell maybe once a week. That's a huge improvement over KDE.

Xfce to me is just too ugly to use. And it messes up my system with all these trash Xfce-only applications and mime associations (seriously what's exo-open and why is it still causing problems 2 years after I uninstalled xfce?).

Everything you've written here presents a nightmarish vision of the computing future. Ethical and privacy considerations play a large role in my decision making process on which software I use. I don't want to use Chromium at all, if possible. I use one Electron app, Slack, on account of requiring it for work.

> Native desktop apps are never coming back

I really hope you're wrong. This would be a terrible outcome for so many reasons. I refuse to use Electron apps on my personal laptop on account of the absolutely noticeable degradation of performance and battery life from using these Electron apps. Using vscode literally halved my battery life.

Gnome already is based on html/js. There is no need for 10 different UI toolkits if one standard can be optimized. The problem is html/js are far from well designed but due to their popularity a lot of time and money has been spent optimizing them.

GNOME makes use of JavaScript, not HTML.

> Native desktop apps are never coming back.

They never went away to start with, it is just a couple of Electron outliers out there.

It's called a browser.

There's Carlo [1], which is an alternative to Electron that uses locally installed Chrome.

1: https://github.com/GoogleChromeLabs/carlo

The problem with this is that is requires people to have Chrome installed. That's a awkward dependency to require for a stand alone app.

Found this in Carlo to issue 90 [2]:

>If one chooses a chromium channel in the launch options, then carlo calls puppeteer createBrowserFetcher which will download the chromium revision compatible with Puppeteer or even a specific revision. sunglasses

In regular ElectronJS you have the same Chromium bundled with the app. Not sure if puppeteer installs a local or system wide Chromium.

2: https://github.com/GoogleChromeLabs/carlo/issues/90

Windows 10 (Edge), Chrome OS and Android all now bundle Chromium, while it's packaged in desktop Linux. That really leaves only macos.

VSCode, say, as a slimmer download sans web runtime is a possible outcome.

"While it's packaged in desktop Linux" you are using the wrong distro(s).

And node!

> I’m wondering whether it’d be possible to factor most of it out into a separate layer

We've done this. The layer is called a web browser. You deliver runnable code to it using something called HTTP.

I think the underlying motivation in this comment is that there are very many technical application development challenges which can be solved simply by web developers paying close attention to the fundamentals of their craft rather than relying on "fancy tricks" to speed up the development process. Plugins like Flash used to be one kind of "fancy trick" to offload into another layer, but there were many developers who stayed faithful to the process of working with everyday browser capabilities (and all of the politics that these capabilities entail), so that the wrinkles could eventually be ironed out. I think that so many who go the "Electron"-ic development route are afraid of getting their hands dirty with the question of in-browser client-side storage, ie, they want to be able to get their hands quickly on the files in the user's native file system.

There are, however, very stable in-browser ways of dealing with the question of client-side storage. IndexedDB is one. But there is another that I am quite partial to, called the File System API. I use it to locally store the files and code in the browser-based OS called Linux on the Web (https://dev.lotw.xyz/desk.os).

Even in the browser itself, there's a clear delineation between the set of components that change quickly, and the set of components that change slowly—a factoring of layers calling out to be done, that everyone is ignoring. There's no reason for a whole new web browser to be shipped if only the quickly-changing part has changed.

Analogy: why would you ship a new copy of X/Wayland just because your Desktop Environment has a new release? The new DE version uses the same old compositor, because the compositor doesn't change much. So why would it make sense for a compositor to be part of the DE and embedded in the release package for the DE, rather than just requesting the OS to make available to it the services of a compositor of a specific [ABI protocol] version? Even if the compositor and the DE have the same maintainers, it'd make far more sense for them to be two separate projects, with one just depending on the other.

Or, to put this another way: why should ChromeOS devices (= another build target of the Chromium codebase) replace the whole OS image every time some new namespaced CSS layout rule is being incubated? That stuff has nothing to do with running an OS. The parts of Chrome that are an OS—which includes a lot of the stuff that gets installed as "browser" on other OSes!—should really live as OS services, separate from "the browser" (really just the renderer + VM.)

Microsoft took a while but eventually learned their lesson about this, and these days Edge is just an app and updating it doesn't require a restart of your computer. Part of what enabled that was delineating the slower-moving parts of the browser (e.g. the network stack) from the faster-moving parts, and letting the slower-moving parts live in the OS while the faster-moving parts lived in the app. "Edge" is just a renderer+VM. So is Safari, for that matter—what you download when you download "Safari Technology Preview" on macOS is just a renderer+VM, which relies on the same OS-provided libraries for e.g. network caching that the system Safari installation does.

Did you even read the comment? GP literally addresses deficiencies in this layer when running multiple instances of the browser.

i did, and found them unconvincing

> 1. this would lose you the ability to develop for a particular version of the renderer

html and css are standards, if you are developing for a version, you are wrong. full stop.

> 2. this wouldn’t give you the benefit of Electron sharing service-memory with Chrome itself

there would be no electron so point is irrelevant

> html and css are standards, if you are developing for a version, you are wrong. full stop.

Who said anything about HTML and CSS?

Apps like VS Code create and manipulate a DOM directly in JS, or more often these days, WASM. To these apps, Electron is just a virtual machine with a lot of browser-like multimedia APIs attached. You pin the exact version of the renderer just like you pin the exact version of your dependencies in a server-side app, or the exact version of the OS in a virtual-appliance VM image.

Electron has nothing to do with "the web" or "web standards" other than borrowing technologies originally developed for those. Electron competes with things like Unity and https://love2d.org/, not with browsers. It's in a category of frameworks with the goal of giving the developer pixel-perfect control over what the user sees, where apps are separately developed, tested, and tweaked, for each target (e.g. each OS, each kind of display/interaction methodology, etc.)

With this category of framework, you don't build your app as generic code targeting a standard; rather, you build, and test, your product against a specific "engine." (Imagine for a moment that people could take Unity apps and run them against any old version of the Unity engine, or even against Amazon's Lumberyard fork of the same. Would anything work?)

> Electron competes with things like Unity

in much the same that sharpened sticks compete with power tools, yes

If your goal is picking your teeth, a sharpened stick is all you need, and any other tool you use is going to be being used as a glorified sharpened stick.

Similarly, if your goal is drawing the views of a CRUD app, any tool you use is going to be used as a glorified version of Display Postscript.

It has side effects, too. For example, I wanted to record a new screencast with OBS Studio (fantastic free software), but couldn’t capture any chromium-based application without disabling GPU-acceleration.

Only happens with electron apps.

> Chromium is built to share a lot of things between tabs efficiently

yey, currently using 6.6 gigabytes on my machine (RSS)... efficient...

firefox is no better, sitting at 4.8 gigabytes...

I see projects like this pop up every once in a while and get abandoned.

A simpler approach may be to just publish a basic web server as your app (express on top of node would do) that runs on the local machine on some random port and have users just go to that URL with their regular installed browser. Bonus points for no leakage of security / CORS / etc. issues from the UI side of things, every unsafe thing needs to be node-side where it can be better controlled. Also enforces asynchronous and efficient communication between the UI and the "local backend".

Does the browser really have access to all the same apis as electron? Doesn't electron have broader access to the file system (e.g. all the stuff that vscode does).

What the parent posted is stating is that the local web server has that system-level access, which the browser doesn't need in order to access the app.

The "back end" web server can be running on whatever language stack you like, be it Go, Rust, Haskell, Common Lisp or whatever. Syncthing is one example, where it's nominally headless, but there is a local web server that can be pulled up to set preferences, monitor status and so on. Works great.

oh yes you're right. i got confused for a moment. thanks!

Electron does, but you need to consider security. Malicious apps or ill-designed architectures can leak openings where a bad actor can attack your OS.

I'm the author of secure-electron-template, a template with secure practices baked-in. Security is very important and I don't feel people think of that from the get-go.

Love the idea of shipping something smaller. In your proposed idea, would a user still need to make sure node and express were installed? Or can you have a user download a project folder and initiate the same way they would a typical executable?

When distributed to end-users it could be an executable with node DLL/SO bundled that has no UI (or maybe a simple tray/menu bar icon with an Exit to terminate and a Show to open a local browser to /localhost:1337).

When developing locally I presume it would be very similar to an Electron project, with npm dependencies for express / fastify on the "backend" side and React or whatever you need for the "frontend" side.

During build, you'd produce 2 bundles (frontend and backend) that tree-shake, etc. such that all js dependencies are optimized together. The frontend bundle should load in any browser (it'd be just a normal website with the only difference being that all REST calls go to /localhost). The backend bundle + any native modules will be loaded in the embedded node runtime so they can be distributed as loose files or packaged in something like Electron's asar.

There, I designed the whole thing, now someone go build it :)

i see this approach with DB admin tools which makes it great to run in docker along side the db itself.

Looks kind of like WebView [1] which I earnestly tried but eventually abandoned. Using the system-provided web engine is great for space savings, but terrible for cross-compatibility and feature availability owing to having to use IE on Windows.

[1] https://github.com/zserge/webview

Isn't the "system provided web engine" now Edge on Windows 10, and has been fore a while?

AFAIK, there's a difference between MSHTML (internet explorer) and EdgeHTML (edge / trident). But even then, Edge can be somewhat lacking depending on your use case [1]. For simple apps that just need a simple UI without spending time developing cross-platform, this solution is great! Unfortunately the projects I've had to develop require newer features and/or performance lent by using the Chromium Embedded Framework that simply aren't possible, even if Edge was available.

[1] https://caniuse.com/#compare=ie+11,edge+12,chrome+80

In UWP yes, but not in Win32. Win32 has always been stuck on IE's MSHTML.dll controls, up until either XAML Islands for the WinRT-based EdgeHTML (coming soon, in preview today) or "Webview2" [1] for the Chromium Edge (coming soon, in preview today).

[1] https://docs.microsoft.com/en-us/microsoft-edge/hosting/webv...

So that means only 25% of your users will still have IE since they never upgrade? Then you have corporate environments where IT held back Edge because internal business software requires IE. (Yes that is still a thing. Yes you can install them both. Yes, IT will still do that.) Then you have systems where some badly written installer broke the native web view but the user isn't noticing because they only use Chrome.

This is Windows after all.

Yes, there is webview-x branch that is to be merged in March, that uses Edge (both variants of it) as the default engine on windows.

The good thing about webview is that it does not use localhost:8080 for internal comms!

> There are some drawbacks such as Windows edition is based on IE etc.

This alone is a major reason to use Carlo[1] instead, which is arguably more secure (by virtue of not using IE) and produces even more lightweight bundles than NeutralinoJS.

1. https://github.com/GoogleChromeLabs/carlo

> There are some drawbacks such as Windows edition is based on IE etc.

Well that's kind of a non-starter. Part of the appeal with shipping an entire browser in an Electron app is to give yourself a fixed target.

It always seems that these "Electron killers" all have some fatal flaw, be it "just use whatever the system browser is" or "just as good as Electron, if you don't care about file drag-and-drop, system clipboard integration, full CSS support, minor things like that"[1].

1: https://github.com/ultralight-ux/Ultralight/issues/178

Carlo is essentially what top commenter derefr is asking for.

That said, it is unmaintained and I don't expect that to change.

Is Carlo maintained? The last commit in master was eight months ago.

It's not.

(I was part of the team that launched it.)

Doesn't work on Mojave for me, since it's apparently linked with 10.15 libraries:

    dyld: lazy symbol binding failed: Symbol not found: __ZNSt3__14__fs10filesystem14__current_pathEPNS_10error_codeE
      Referenced from: /Users/rcarmo/Downloads/New Items/neutralinojs-v1.3.0/./neutralino-mac (which was built for Mac OS X 10.15)
      Expected in: /usr/lib/libc++.1.dylib

    dyld: Symbol not found:  __ZNSt3__14__fs10filesystem14__current_pathEPNS_10error_codeE
      Referenced from: /Users/rcarmo/Downloads/New Items/neutralinojs-v1.3.0/./neutralino-mac (which was built for Mac OS X 10.15)
      Expected in: /usr/lib/libc++.1.dylib

    zsh: abort      ./neutralino-mac

This is the correct way of doing it when a PWA doesn't cut it.

No need to push a full browser engine when the OS already has enough of them available.

It definitely is the 'correct' way of doing it, but it will mean you use IE when in windows, which is often/normally not the correct way

We still need to support IE 11 on our projects anyway.

Welcome to the corporate world.

> We still need to support IE 11

Not all of us. I'm happy to lose the 2.16% [1] in return for saving a lot in time and effort.

[1] https://www.w3counter.com/globalstats.php

Lucky you, I usually do internal corporate applications.

Not if you are shipping chrome with your application. Isn't that part of the point of electron?

Being lazy is the point of Electron.

True today, but it won't be long until Edge Chromium. (Assuming Windows 10, that is.)

What are the top reasons an PWA wouldn't cut it?

You need to access some OS features not yet exposed as Web API, or you might need to still have a version for browsers like IE 11.

If you want anything from the web to work on Windows as native why not just use PWA utilizing Microsoft's (1) own PWA Builder (2) including the availability of proper debugging tools and acceptance in the store? It doesn't matter what tech it uses. The more important thing is it will be supported and updated. There won't be any surprises.

(1) https://developer.microsoft.com/en-us/windows/pwa/ (2) https://www.pwabuilder.com/

But it works on only Chrome at the moment. Firefox or Safari users wouldn't install Chrome just for your PWA.

What are you talking about? Read my comment. You have stand-alone native-like app that Microsofts creates for you from your web service. The app could also be installed directly from the Windows Store. No browser required at all.

Why is it called `Neutralino`? As a supersymmetric partner it's much heavier than the Standard Model particles.

Neutrino was taken:


WebWindow is another library that takes the same approach. It's still in progress but is very promising. It was very easy to get running when I tried it last.


A hello world Electron app uses about 50 MB of memory.

The problem with Electron apps is not so much Electron or Chromium but how they are designed & developed. Most developers view memory optimization as an after-thought. This is especially true for multiple document interface applications. The tooling is all there to monitor and optimize memory, but few make real memory budgets part of their build & integration testing process.

Developers have 16-32 GB of memory (or more) workstations and typically work on individual features that don’t exercise the edge cases of large datasets. They don’t bother to implement proper LRU mechanisms, paging, and often do performance optimizations that sacrifice memory for speed.

It gets worse if they aren’t forced to dog food their own creations or aren’t users of their app themselves.

Stupid question: instead of embedding an entire browser in each-and-every app and trying to keep that secure, why not package the native desktop framework as a shared, versioned component and the app as a tiny thing that depends on it?

I'm generally pretty old school when it comes to development practices but I can totally understand how appealing it is to effectively ship your entire environment as part of your application instead of relying on shared dependencies. Dealing with dependency incompatibility is a huge maintenance burden in my experience, and it's super tricky to debug if you don't have access to the problematic environment (which is most of the time if you deal with public projects).

That's why I really try to get into docker for instance, sure good old unix sysadmin and configure scripts might arguably be more elegant and efficient but it's a huge pain to maintain and can (and eventually will) break out the blue after a system update because of a regression in some obscure library. Meanwhile docker images should work mostly everywhere without any effort and you only update your dependencies when you want to update them.

So now that storage is cheap and RAM is plentiful I think shipping the dependencies as part of the executable is a reasonable approach most of the time. The problem with electron is that the dependencies involve a full web browser and half a trillion libraries. That's the insane part. I have full python virtual envs for non-trivial apps that are a fraction of the footprint of an electron hello world. It's the core technology that's broken, not the packaging.

I think the grandparent comment is envisioning something more like Docker than like e.g. the JRE.

This is actually already how the Microsoft Visual Studio C Runtime (aka MSVCRT) is distributed: each application embeds or streaming-downloads the exact [ABI] version of the runtime it needs, but only one of each exact [ABI] version of the runtime needs to exist per system, and each of those runtimes can be upgraded by the OS to resolve security problems (while never altering the ABI guarantees that version distribution makes.)

As such, a runtime built this way is a lot like a base layer in a Docker image: it’s a static dependency of the app, installed during the app’s installation, and held in a pseudo content-addressable store that deduplicates it from other apps’ demands for the same dependency.

>each application embeds or streaming-downloads the exact [ABI] version of the runtime it needs

Except when they don't. Took me way too long to accidentally install the right redist to have fn-key OSD (volume up, mute, airplane mode, et cetera) on my ThinkPad.

Because why bundle it with the drivers? No error messages either. Just mash the buttons and have no visual feedback.

I've lost track of the number of times I've had to find the specific version of msvcrt and install just to get some piece of software working. It's a highly user unfriendly process

> I can totally understand how appealing it is to effectively ship your entire environment as part of your application instead of relying on shared dependencies.

It's the modern "It works on my machine", but in this case it does because you almost ship the entire machine.

Google's Carlo sort of does that. It uses your system's already-installed Chrome instead of packaging another one.


Not a stupid question. This is exactly how operating systems and application SDKs were always developed and deployed until fairly recently.

It worked quite well, until software release cycles got stupidly short. It was always a pain in the ass to have to install the Visual C++ runtime, but there were only so many versions of it. These days you have people linking a hundred DLLs that release new versions monthly, sometimes weekly.

The appealing thing about Electron was that it shipped a particular version of a particular browser brand, combined with a particular version of a Javascript engine.

Knowing exactly what browser version you're developing for gives you a lot of freedom that you'd lack when having to support different ones.

Single binary is becoming more common even for runtime apps (JVM,.NET).

The reason I wouldn't want Electron to be shared across apps is I don't want a system wide install and certainly don't want to deal runtime version type issues. Electron would start having to be backward compatible for years.

That's sane. Sanity is prohibited in the realm of UI programming. There's apparently a law somewhere that states that all GUI libraries and APIs must be one of: platform-specific, bloated/slow, or incomplete/ugly.

Lazarus and LispWorks CAPI are exceptions to this rule, but they both use languages people don’t want to learn and CAPI is proprietary

using the word "lightweight" to describe anything involving js and an html renderer should be prohibited

I wonder why. Given the popularity of HTML you'd think some large organization would've developed a reasonably fast _and_ memory efficient browser engine by now but everyone seems to be aggressively optimizing for speed.

Bloated specs with tons of historical cruft and edge cases. And a renderer needs to support it all. The problem stems from trying to use something designed to share documents with some custom styling as a universal GUI for applications instead.

It's possible to develop relatively lightweight browser engines. Refer to NetSurf for instance. However the ones I've seen are not what you'd consider fully-featured or usable for the average user's everyday browsing. The issues begin at implementing modern CSS and JavaScript support. Admittedly I've never looked too deeply at the internals, from what I understand supporting modern web standards is a maze of edge-cases, bug-for-bug compatibility issues and a forever moving target of feature parity with the major browsers.

I know but the apps are several orders of magnitude smaller than Electron apps, so I think it's appropriate here:

> An uncompressed Neutralino app is only ~5MB and compressed app size is ~1MB.

Indeed. Webshits alone are responsible for 1 or 2% of global energy usage.

I feel like this calibre of comment is a perfect example of the "reddification" of HackerNews recently

If it were being reddified, you'd see a bunch of people needlessly turning things into political discus--- ohh.....

> Please don't submit comments saying that HN is turning into Reddit.




Even disregarding the poor term you've used, I'm pretty skeptical of what you just stated. Especially with a margin error of 1%.

So if I understand right, what makes this lighter than electron is the fact that only webkit2 is used instead of embedding the whole chromium app.

Looks like it's using system controls on macOS, Windows and dynamically linking to webkit on Linux for rendering the served HTML/CSS/JS (from node).

I see mentions of WKWebView(the system webkit) in the code[0], and while I don't know any Windows programming, they are #including <mshtml.h>[1] - looks like a system included web view (presumably the one that edge was based on). The linux build requires libwebkit2gtk-4.0-dev to be installed[2] - they're dynamically linked to webkit2gtk.

[0] https://github.com/neutralinojs/neutralinojs/blob/b10e065c97...

[1] https://github.com/neutralinojs/neutralinojs/blob/07fdc3c1c7...

[2] https://github.com/neutralinojs/neutralinojs/blob/master/REA...

I think you are right except when you say that the HTML/CSS/JS is served from node. The website says it is not served from node which makes it lighter than alternatives.

Developing an app requires node, but it will not be needed at runtime if I get this right.

Indeed I think they don't ship the whole browser package.

What they might actually do is to locally launch a HTTP server which renders the app if you call it on any browser (localhost:8080 in the examples). The chrome of the app is actually a thin layer that use the default OS web browser. That is why the memory footprint is much less higher that alternatives like electron.

I don't understand, it seems like it runs in any browser? Are they using webkit2 as a replacement for node and the system browser for the GUI?

It seems to me that the Javascript runs in the client.

The Javascript side calls the system via the local network, passing through this router: https://github.com/neutralinojs/neutralinojs/blob/master/cor...

I hope that there is some form of authentication to make sure no random web apps are accessing the API.

I agree that they really need to explain this better on their site somewhere.

I guess it needs only 400 Mb of RAM instead of 500 then.

What is the difference between this and https://github.com/zserge/webview which it's based on? Or what do I get from this that I don't from webview (which I've been considering in Rust)?

Webview author here. I have to mention that neutralino is based on a slightly outdated webview, the new version is to be merged in March, which includes EdgeHTML and Edge/Chromium support on Windows.

I'm currently working on an app built with Electron app. One thing I love is not to have to worry about whether the APIs I'm using are supported by the browser, since the browser is packaged inside the app. (if it works on my machine, it has a decent chance or working well on my users' machines).

The perf overhead (memory, bundle size) is big, but it's not stopping anyone from shipping Electron apps (Visual Studio Code, Slack, WhatsApp, etc..).

A nice to have compromise would be to have currently running Chromium Electron instances to host newly launched Electron apps, it doesn't solve the bundle size issue, but at least solves memory bloat and the number of Chrome main processes running.

Why no macOS in the comparison?


For a moment I thought Neutralino didn't support macOS.

Presumably the person who did the benchmarks doesn't own an Apple computer.

I don't think using a local web port for the UI of a desktop app is a good idea, at least for security reasons. I guess much of the resources of the alternative solutions are used to mitigate just that (in addition to having a powerful backend framework). So if you don't want either, than maybe it is an option, but it severly limits the scope of the architecture.

Surprised not to see the license clearly on the site, but it's under MIT License: https://github.com/neutralinojs/neutralinojs/blob/master/LIC...

Sharing this as another alternative, unfortunately unmaintained:


Reminds me of Nidium, but nothing is happening there anymore


It's an awkward transition period toward a universal virtual machine, universal bytecode format JIT based runtime that runs in browser and out of it. Ultimate cross platformness. The Holy Grail. Lot's of people trying several things that tackle some of it but not all. All of them will perish as all things do but they'll pave the way for the future. Let the revolution begin;

SpiderEye [1] is another project with the same approach, while Ultralight [2] is very different but with similar goals in some ways (light cross-platform application UI).

1. https://github.com/JBildstein/SpiderEye

2. https://ultralig.ht

Neutralino offers a lightweight and portable SDK which is an alternative for Electron and NW.js also with many advantages. No extra dependencies are required. SDK is fully portable. Debug applications using a web browser. An uncompressed Neutralino app is only ~5MB and compressed app size is ~1MB.

In time all possible words will have a different, overloaded, meaning within the context of computer science.

If I understand it's like Google Chrome Native Messaging but with a generic multi-purpouse server. https://developer.chrome.com/extensions/nativeMessaging

Electron's value prop is running the same code as your website, and also being able to use latest features from Chromium, Node and JS for unified development.

Neutralino uses MSHTML and WebKit so its already outdated, and it won't run on the web. So why would I use it?

When I click on the comparison button on my mobile browser it just opens the left menu

This looks interesting. I was confused because the name is very close to an established JS build tool: https://neutrinojs.org/

> There are some drawbacks such as Windows edition is based on IE etc.

What does this mean?

It uses whatever the system webview is. So on Windows that is IE, on Mac it’s WKWebView, not sure about Linux.

It’s a trade off: it’s much more lightweight but loses cross platform consistency. For some that might be absolutely fine, for others it may not.

I wish we had a step inbetween. Something more than "just a webview" but something less than, well, all of electron. Give me like a really cut down browser that's consistent across platforms and embed it.

It's a shame Sciter hasn't seen more adoption:


But a) it's a commercial product and b) uses it's own scripting language instead of JavaScript. But from some initial noodling around with it the browser engine is very capable and the footprint small.

Sciter's author here.

a) Is anyone brave here to finance transition of Sciter to OpenSource? Please contact me if yes.

b) Sciter's script is a JavaScript++:

It uses JS syntax and runtime like `arr.concat(a,b)`.

Grammar and syntax was extended to better support UI cases. Like `const width = 12px;` is valid construct as Sciter has Length data type.

React and JSX are implemented natively.

    function render() {
      return <p>{this.greeting}</p>;
is a valid construct as JSX (SSX in Sciter) is a part of script grammar : https://sciter.com/developers/sciter-docs/reactor-and-ssx/

Don’t get me wrong, I agree with you that it’s an amazing scripting language. But I think one of the reasons Electron has been so popular is that web devs can take all the skills they already have, including JS, and make a native app. Learning a new language is a barrier to adoption, to hiring developers in the future, blah blah.

But I want to give you credit for an absolutely phenomenal project! If I had the cash lying around to finance it as an open source concern I would, but alas.

The weird language is the big turn-off for me, not the license. This is also a turn-off for Flutter and Lazarus.

WHY do these projects insist on doing this? What is it about UI that leads people to think this is a good idea? Do not make me learn yet another language just to use your UI library.

It's not that FreePascal or Dart are bad languages. It's that they're another language to consume yet more precious attention and head space, and there's nothing compelling enough about them vs. C++, Rust, Go, Python, JS/TypeScript, etc. to make it worthwhile.

You can use Sciter in C++, Rust, Go, Python, Delphi, C# and D projects : https://github.com/sciter-sdk

You can't write your GUI in those languages.

> You can't write your GUI in those languages.

What do you mean by "write GUI"?

If to declare DOM structure then HTML is for that.

If to initialize DOM structure from code at runtime then this (C++ here):

   use namespace sciter;

   element root = window.get_root();
   element div = element::create("div", L"Hello world");


Or do you mean something else?

Whoa... I didn't know it let you do that! In that case that's quite interesting. It opens the potential for using the web renderer but not having to code everything in JS.

"It opens the potential..."

Applications that use Sciter for their UI are native applications. Like Norton AntiVirus for example. Or any other app of these vendors: https://sciter.com/#customers

I've been looking at Dart lately and it seems like a pretty awesome language. A weird mashup of Java + JavaScript, but I agree its something else that has to be learned. I think flutter would probably have better adoption if they chose something more mainstream.

Just like the Web stack.

If that isn't desired, then doing native apps is the way.

I assume you're quoting the "Why Neutralinojs is better" page:


This page was last updated 2/28/2019. Last month, Microsoft Edge was rereleased as a Chromium based browser. Presumably this would change the Windows frontend for Neutralino to Chromium, but I'm only speculating.

Edit: It appears that a Chromium system-provided web view for Windows is still in developer preview:


There's https://github.com/patr0nus/DeskGap which seems little more mature?

Web devs have ruined the web and now they're ruining the desktop. I wish people would go back to native UIs.

Does this support WASM? I'd expect not given it's so small, but worth asking.

That probably just depends on whether the system browser that it launches supports wasm, I think it’s passing off the dependency.

The docs page is just white for me

Looks great, I will definitely try it!

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact