Why why would I want to use Go on the integration side, and still have to use JS within the webpage? Most Electron apps I've seen have a slim wrapper of code in their main file to just initialize native things. Why is it better or easier to do that in Go instead of in JS?
Picking your technology stack based on "what you prefer working with" rather than "what works best for the application you're building" is piling on technical debt before you've even started your project. That isn't saying Gallium is necessarily the wrong choice over Electron; it's saying you should evaluate them both and use the one best suited to what you're building, even if that means learning a new language.
(Obviously this is a ideological argument rather than a practical one because most projects don't have the budget for devs to do that much prep work like learning a new language, but practicality is boring. :) )
Isn't Electron the very definition of "Picking your technology stack based on what you prefer working with" rather than "what works best for the application you're building"?
I think Electron has proven to be a very powerful model for GUI customization IMO. Some of the plugins people are building are truly amazing and I can't see this happening in a non-web ecosystem.
With Gallium the "outer layer" is compiled whereas with Electron end users can take a look at the scripts (there's some ways to mitigate it, but still, it's not compiled into a binary).
This can be useful if, for example, you want to deploy this as a commercial software and do some checking against piracy...
Which leads to: there's still no licence attached to this cool project ;)
So, you're saying, the only advantage is that instead of every high school student being able to crack your DRM, now only every college student will be able to crack your DRM.
So Go and JS are similar in that they are designed for heavily asynchronous tasks. But they do it very differently: Go has hordes of green threads "goroutines", JS has callbacks all the way down.
As annoying as callbacks can be, they do fit the model basic GUI model very well: user clicks on something, the system calls the corresponding funciton. And indeed I see a lot of that sort of thing in the README.
Does that mean goroutines will fade into the background in Gallium?
> So Go and JS are similar in that they are designed for heavily asynchronous tasks. But they do it very differently: Go has hordes of green threads "goroutines", JS has callbacks all the way down.
concurrent tasks =/= asynchronous tasks.
A big difference is that Go doesn't force you to write asynchronous code for I/O operations, JS engines like nodejs do and it's a pain in the ass. Go only says : "If you want to write concurrent code you can do that", while NodeJS or browsers say :"Any I/O operation needs to be asynchronous and explicit".
If I call an API in Go, I don't have to care whether the computation will be executed in the same thread or not, or in 10 different threads, provided concurrency is encapsulated the right way. There is no amount of async/yield/promise that can mask any I/O operation with Nodejs on the other hand.
> As annoying as callbacks can be, they do fit the model basic GUI model very well:
This is a design decision. Gallium could have used channels instead of callbacks.
>As annoying as callbacks can be, they do fit the model basic GUI model very well: user clicks on something, the system calls the corresponding funciton.
Those are callbacks for event-driven programming.
But there's nothing about them that makes it a great abstraction for asynchronous tasks in general, and even less so for concurrency tasks. They are a low level abstraction that should be used as an implementation detail.
To clarify, they do not fall into the the strictest definition of green threads[1].
> [2]: As of Go 1.5, the default value of GOMAXPROCS is the number of CPUs (whatever your operating system considers to be a CPU) visible to the program at startup.
Prior to 1.5, the default value was '1' but could be changed.
> GUI model [...] Does that mean goroutines will fade into the background in Gallium?
The main concern at the moment seems to be wrapping the underlying APIs. However, I see channels being used for great effect further down the line:
var ui chan uiFunc = // ...
button1Click := make(chan ClickEvent)
go func() {
for evt := range button1Click {
ui <- func() { textBox1.setText("Button clicked!") }
}
}()
button1.onClick(button1Click)
I presume this also applies to interacting with the V8 ABI, seeing as JS is inherently single-threaded.
I wonder how good a desktop app will work if we drop the JS part altogether and use HTTP and regular client-server architecture (i.e. every click will have to rerender the template)? I guess something like Mozilla's servo can be used for that instead of a full featured Chromium to improve performance.
Just throw away the HTML part and make a proper native application using network protocols, e.g. the "HTTP and regular client-server architecture".
That is what I went back to doing in these last three years (Forms/WPF/Android/iOS/WP) and couldn't be happier to have regained some sanity away from the Web world, fad of the day with browsers bended to pretend native UIs.
I'm a full stack dev that can't stand JS, now i started to do UWP (xaml) app, the learning curve is a bit steep, but the UI building is SOOO much better than html/css/js and everything behaves exactly as you would expect and vertical positioning just works!
Author here. I have been thinking about writing a react-like component system for Go, that outputs HTML. The major down side is that then you can't re-use much between your web-based app and your desktop app (which I think is a common pattern now).
Agreed. It would be nice if the Google guys could do something like Qt with Go, but more Go-ish and in pure Go so you can still easily cross-compile. I'd even settle for a faked native look using OpenGL.
I know there are OpenGL packages for Go, but I don't think they are really "pure Go" (in the sense of not linking to any C libraries at all). At least not under X11.
Unlike all the other X11 extensions, the GLX "protocol specification" doesn't define a network protocol. It defines C functions bolted on to Xlib for setting up GL contexts. In many use cases, there probably is no network at all -- just direct rendering.
I don't know what the situation is on other platforms, but I guess it is similar: OpenGL is exposed as some C-based library.
- QtQuick is "the standard library for writing QML applications." [1], providing: Models, Layouts, GraphicalEffects, States, etc. Conveniences and building blocks to build GUIs with QML.
- QML itself is a declarative language totally different from HTML. Bindings are done with JS (by the way, a specific, custom implementation of it), yes, but there's no HTML anywhere.
- Qt also provides the WebEngine module [2], which is an in-house packaging of Chromium. If you use this instead of QML to build your GUI, then yes you're in almost-vanilla "HTML+JS" land. But this is not QtQuick.
Trying to shoehorn a UI description in a procedural language is always going to be awkward.
But we could have a compilable document language with DOM-like bindings and an event loop in Go. It's a lot harder to implement than HTML + JS, though, which already provide that for free.
Actually I think the standardization of HTML5/CSS3/JS as the UI framework is preferable to the extreme fragmentation that exists in the "native" UI space
I think there's opportunity in packaging this as a system installed & independently updated dynamically linked library much like WebView is updated on Android KitKat onwards. Eg. a single "system" Chromium component that's installed centrally & used by multiple programs much like Microsoft Runtime DLLs on Windows.
Not only that, but it will also re-invent the WinSXS hell in different ways. We now have modules, but also loaders in all sorts and flavors, we have AMD style, we have the noConflict style, and in the end, the web will probably re-invent snappy apps and flat image packages. Webpages will load an entire in-browser browser of a specific version required to use the page, and we'll all have come full circle. I bet we're gonna see in-browser virtualisation, because just sandboxing and containerization isn't enough.
This is a bit of a stretch. No one seriously writes AMD today and the support of it is solely for backward compatibility due to how trivial it is to support it. CommonJS won that battle when tools like Webpack & Browserify came into existence. ES6 Modules will replace CommonJS once loaders for both the web and node actually make it into existence. Even still, Webpack 2 and Rollup both support ES6 & CommonJS side-by-side.
>I think there's opportunity in packaging this as a system installed & independently updated dynamically linked library much like WebView is updated on Android KitKat onwards.
The people who are browsing HN probably already have the solution to this problem installed on their computers: a web browser!
I don't really care about standardization of the "native" UI space. What I prefer is lightweight applications otherwise why not simply run it in a web browser? Electron loses the two primary advantages of the web and that is no need to install anything and being cross platform.
For Discord, there is no linux version and on windows I like the web version more.
actually today, I think for most applications, a HTML based UI is good enough performance wise and certainly provides much higher scope for design creativity and flexibility over native framework widgets and views.
The performance improvement has basically come from the massive market that web is and consequently Google, FF and MS optimizing their JS and rendering engines (plus Moore's law)
I find that this phrase irks me quite a lot these days. Feels like it's at every corner of software development waiting to pounce and ensure thoroughly mediocre results.
There's something to be said about, "don't let the perfect be the enemy of the good" but at the same time, "good enough", especially when it comes to UI speed/responsiveness and UX quality, feels like a massive cop out. Isn't there a middle ground somewhere that doesn't call for such huge concessions?
>Actually I think the standardization of HTML5/CSS3/JS as the UI framework is preferable to the extreme fragmentation that exists in the "native" UI space
We've already solved fragmentation in the native UI space, with GUI toolkits like GTK and Qt. If someone extended those to mobile devices, then we'd have something a lot less terrible than HTML5/CSS/JS, which performed a lot better.
I was thinking something more like GTK and GLADE, or Qt and Qt Creator. Qt Quick looks like it's kind of halfway between what I'd consider a GUI toolkit and a drawing library.
Why? Disk space is plentiful and costs peanuts, and is becoming cheaper by the day. What's there to gain from having shared libraries other than that it's psychologically satisfying? Having been a Linux user for 12 years, I feel like it's of very limited benefit and has lots of drawbacks. Is there something I am not understanding?
My / has reached 200GB now? And that's despite /home being seperate.
That's the issue.
With this, my / will reach terabytes.
There's two things why not: cheap isn't free, and "elegancy principle": Don't build shitty hacks, build software that's easy to maintain, as minimal as possible, and will be used for decades.
The same reason security libraries are distributed independently so that they can be automatically updated without the program using them being re-compiled & re-released. On the Android platform, Chromium WebView updates far more frequently than the apps that depend on it & includes security patches on update.
RAM in not as plentiful, nor are level-3, level-2 and level-1 cache. having a second copy or almost-copy of a library can increase utilization of any of them.
Author here. Yeah using servo might be workable because you could test all your HTML ahead of time and work around any problems (unlike the any-browser web workflow). Still I agree re stable release.
This always comes up with OSS projects, that there's another project with the same name. But the reality is there are only a limited number of names to pick from, and an unlimited number of projects. That's why we went to names like Tumblr and Flickr for a while. But if you think Apple is a unique name, you might be surprised: https://en.wikipedia.org/wiki/Apple_Corps_v_Apple_Computer
People feared when many former Node.JS developers migrated to Go because they would probably migrate the same principles from the JavaScript community (NPM and the dependency hell). Now people will fear the migration of Electron-like applications to the Go ecosystem. I am glad that more and more web developer are stepping forward and contributing their skills to create desktop applications, but I still cannot wrap my head around the idea that embedding a giant non-efficient webview in every project is a good idea. At this point, a computer with +16GB RAM will feel like using one with only ~6GB because of the amount of Chromium instances open in the background.
Someone reported yesterday a problem in the SublimeText3 issue tracker [1][2] stating that after the automatic update to the latest version the software started to consume a lot of RAM and CPU, but then he explained that (while using a Mac) he had ST open for several months, WTF!!! He should be graceful that you could keep ST open for more than a week, try that with an Electron-based application like Atom and you will cry. Now imagine this scenario with the future Go+Electron-like applications in the following months.
I've had my web browser open for many weeks without issue. Individual tabs may crash, but the browser stays up and memory usage doesn't get out of hand. Initial memory usage may be heavy on an Electron app, but there's no particular reason to expect unbounded growth.
How many Chromium instances does Gallium create? Why would it ever need more than one unless you need to spawn a new window? We're way beyond the old WinForms days of making new windows that often.
The main reason is user expectations. People expect applications to be portable between web, desktop OS, tablet/phone OS. Developers only have so much time and budget so currently HTML provides the best option to port interfaces between all platforms in the shortest period of time.
It's not ideal, but everything generally comes down to cost benefit analysis with time being a major contributor to cost. That's the entire reason that so many startups have been using Ruby despite it's non-ideal performance. Soon as you get a steady revenue stream from users taking the time to optimize to something else makes sense.
Granted, Elixir is shifting that formula quite a bit now since you can get those Ruby-like levels of productivity and time savings without the long term expectation of refactoring headaches.
A framework like this would be awesome if it used the browser engine on the system rather than CEF, or allowed that as an option. You'd be able to get Mac programs that are just a couple of MB then, rather than having each of these programs weigh 50-60MB. The runtime characteristics might not be much better, but at least every binary is a bit smaller.
Of course, this is a minor complaint on modern systems...
I believe the reason people don't want to use the OS-native web interface is because of the need to support multiple frontends. It's easier to keep your presentation layer consistent across OS when you have a shared rendering platform.
SWT (the eclipse widget toolkit) takes this approach. It's very difficult to maintain API compatibility with the myriad browser versions out there, not to mention having the content in those browser windows display reliably.
The real killer-feature of Electron et. al. is only having one browser version to test against. I think embedding CEF is definitely the right call.
Author here. Yes this is a significant price to pay, but being able to test once and be sure that your users' experience will match your testing is worth a lot. It should be possible to have an updater that avoids downloading the main chromium dylib on most updates.
This is actually not based on CEF, btw, but on libchromiumcontent (the Electron alternative to CEF).
76 comments
[ 2.5 ms ] story [ 143 ms ] thread"Both Electron and Gallium use Chromium under the hood, and in fact some of the C components for Gallium were ported from Electron."
Why why would I want to use Go on the integration side, and still have to use JS within the webpage? Most Electron apps I've seen have a slim wrapper of code in their main file to just initialize native things. Why is it better or easier to do that in Go instead of in JS?
Probably, you wouldn't. But it's not quite surprising if users of GopherJS and Go would prefer Go over JS, is it?
(Obviously this is a ideological argument rather than a practical one because most projects don't have the budget for devs to do that much prep work like learning a new language, but practicality is boring. :) )
This can be useful if, for example, you want to deploy this as a commercial software and do some checking against piracy...
Which leads to: there's still no licence attached to this cool project ;)
Just stop it and give up on DRM.
As annoying as callbacks can be, they do fit the model basic GUI model very well: user clicks on something, the system calls the corresponding funciton. And indeed I see a lot of that sort of thing in the README.
Does that mean goroutines will fade into the background in Gallium?
concurrent tasks =/= asynchronous tasks.
A big difference is that Go doesn't force you to write asynchronous code for I/O operations, JS engines like nodejs do and it's a pain in the ass. Go only says : "If you want to write concurrent code you can do that", while NodeJS or browsers say :"Any I/O operation needs to be asynchronous and explicit".
If I call an API in Go, I don't have to care whether the computation will be executed in the same thread or not, or in 10 different threads, provided concurrency is encapsulated the right way. There is no amount of async/yield/promise that can mask any I/O operation with Nodejs on the other hand.
> As annoying as callbacks can be, they do fit the model basic GUI model very well:
This is a design decision. Gallium could have used channels instead of callbacks.
Node also has a full set of 'normal' synchronous I/O operations (although they were added later after the async stuff).
It will act the same when it's sync vs async.
It would be a horrible idea to await everything, but it would work.
Those are callbacks for event-driven programming.
But there's nothing about them that makes it a great abstraction for asynchronous tasks in general, and even less so for concurrency tasks. They are a low level abstraction that should be used as an implementation detail.
To clarify, they do not fall into the the strictest definition of green threads[1].
> [2]: As of Go 1.5, the default value of GOMAXPROCS is the number of CPUs (whatever your operating system considers to be a CPU) visible to the program at startup.
Prior to 1.5, the default value was '1' but could be changed.
> GUI model [...] Does that mean goroutines will fade into the background in Gallium?
The main concern at the moment seems to be wrapping the underlying APIs. However, I see channels being used for great effect further down the line:
I presume this also applies to interacting with the V8 ABI, seeing as JS is inherently single-threaded.[1]: https://golang.org/pkg/runtime/#GOMAXPROCS [2]: http://dave.cheney.net/tag/gomaxprocs
That is what I went back to doing in these last three years (Forms/WPF/Android/iOS/WP) and couldn't be happier to have regained some sanity away from the Web world, fad of the day with browsers bended to pretend native UIs.
Go needed a GUI, but this?
Unlike all the other X11 extensions, the GLX "protocol specification" doesn't define a network protocol. It defines C functions bolted on to Xlib for setting up GL contexts. In many use cases, there probably is no network at all -- just direct rendering.
I don't know what the situation is on other platforms, but I guess it is similar: OpenGL is exposed as some C-based library.
- QtQuick is "the standard library for writing QML applications." [1], providing: Models, Layouts, GraphicalEffects, States, etc. Conveniences and building blocks to build GUIs with QML.
- QML itself is a declarative language totally different from HTML. Bindings are done with JS (by the way, a specific, custom implementation of it), yes, but there's no HTML anywhere.
- Qt also provides the WebEngine module [2], which is an in-house packaging of Chromium. If you use this instead of QML to build your GUI, then yes you're in almost-vanilla "HTML+JS" land. But this is not QtQuick.
[1] http://doc.qt.io/qt-5/qtquick-index.html
[2] http://doc.qt.io/qt-5/qtwebengine-index.html
But we could have a compilable document language with DOM-like bindings and an event loop in Go. It's a lot harder to implement than HTML + JS, though, which already provide that for free.
It's based on OpenGL ES.
Ivy was made with GO mobile which is a collection of bindings for android/ios only.
I think there's opportunity in packaging this as a system installed & independently updated dynamically linked library much like WebView is updated on Android KitKat onwards. Eg. a single "system" Chromium component that's installed centrally & used by multiple programs much like Microsoft Runtime DLLs on Windows.
The people who are browsing HN probably already have the solution to this problem installed on their computers: a web browser!
I don't really care about standardization of the "native" UI space. What I prefer is lightweight applications otherwise why not simply run it in a web browser? Electron loses the two primary advantages of the web and that is no need to install anything and being cross platform.
For Discord, there is no linux version and on windows I like the web version more.
The performance improvement has basically come from the massive market that web is and consequently Google, FF and MS optimizing their JS and rendering engines (plus Moore's law)
I find that this phrase irks me quite a lot these days. Feels like it's at every corner of software development waiting to pounce and ensure thoroughly mediocre results.
There's something to be said about, "don't let the perfect be the enemy of the good" but at the same time, "good enough", especially when it comes to UI speed/responsiveness and UX quality, feels like a massive cop out. Isn't there a middle ground somewhere that doesn't call for such huge concessions?
We've already solved fragmentation in the native UI space, with GUI toolkits like GTK and Qt. If someone extended those to mobile devices, then we'd have something a lot less terrible than HTML5/CSS/JS, which performed a lot better.
That's the issue.
With this, my / will reach terabytes.
There's two things why not: cheap isn't free, and "elegancy principle": Don't build shitty hacks, build software that's easy to maintain, as minimal as possible, and will be used for decades.
The same reason security libraries are distributed independently so that they can be automatically updated without the program using them being re-compiled & re-released. On the Android platform, Chromium WebView updates far more frequently than the apps that depend on it & includes security patches on update.
RAM in not as plentiful, nor are level-3, level-2 and level-1 cache. having a second copy or almost-copy of a library can increase utilization of any of them.
Package up servo with DOM api via C ffi and you'll have my attention.
Even if someone started a project like this they likely wouldn't be done until it gets a stable release anyway.
Chromium is also an element, but if I named a third OSS project "Chromium" (first: [1], second: [2]), I bet people would complain.
Windows and apple are common words in the English language, but I bet I couldn't name my software project either of those.
Context is important when deciding whether a name is appropriate or not.
[1]: https://en.wikipedia.org/wiki/Chromium_B.S.U.
[2]: https://en.wikipedia.org/wiki/Chromium_(web_browser)
[0]: https://galliumos.org/
> The executable itself is 2.2M [...] Bundle 95MB [...]
> https://www.reddit.com/r/golang/comments/53tw4p/a/d7x2a91
People feared when many former Node.JS developers migrated to Go because they would probably migrate the same principles from the JavaScript community (NPM and the dependency hell). Now people will fear the migration of Electron-like applications to the Go ecosystem. I am glad that more and more web developer are stepping forward and contributing their skills to create desktop applications, but I still cannot wrap my head around the idea that embedding a giant non-efficient webview in every project is a good idea. At this point, a computer with +16GB RAM will feel like using one with only ~6GB because of the amount of Chromium instances open in the background.
Someone reported yesterday a problem in the SublimeText3 issue tracker [1][2] stating that after the automatic update to the latest version the software started to consume a lot of RAM and CPU, but then he explained that (while using a Mac) he had ST open for several months, WTF!!! He should be graceful that you could keep ST open for more than a week, try that with an Electron-based application like Atom and you will cry. Now imagine this scenario with the future Go+Electron-like applications in the following months.
[1] https://github.com/SublimeTextIssues/Core/issues/1387
[2] https://forum.sublimetext.com/t/sublime-3124-eat-up-my-cpus/...
It's not ideal, but everything generally comes down to cost benefit analysis with time being a major contributor to cost. That's the entire reason that so many startups have been using Ruby despite it's non-ideal performance. Soon as you get a steady revenue stream from users taking the time to optimize to something else makes sense.
Granted, Elixir is shifting that formula quite a bit now since you can get those Ruby-like levels of productivity and time savings without the long term expectation of refactoring headaches.
Of course, this is a minor complaint on modern systems...
https://github.com/mgutz/chromeapp
chrome app <- websockets -> go service
The real killer-feature of Electron et. al. is only having one browser version to test against. I think embedding CEF is definitely the right call.
This is actually not based on CEF, btw, but on libchromiumcontent (the Electron alternative to CEF).