We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Building Desktop Apps with Ember and Electron

00:00

Formal Metadata

Title
Building Desktop Apps with Ember and Electron
Title of Series
Number of Parts
37
Author
License
CC Attribution - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
You may have seen apps like Slack, Visual Studio Code, or Docker's Kitematic: desktop applications written using Node.js and Chromium. You might be hoping to build something similar. Electron was originally built for the Atom editor, and enables developers to build beautiful cross-platform apps using the JavaScript we all love. When combined with Ember, you're looking at a fantastic desktop app development framework. Ember and Electron are a match made in heaven, and this talk will teach you all you need to know to get started building desktop apps with Ember.
13
Thumbnail
07:51
VideoconferencingCodeMobile appBuildingOpen sourceSource codeSoftware developerInterprozesskommunikationProcess (computing)Message passingSoftware testingDisintegrationInstallation artBinary fileWindowGoodness of fitScripting languageTelecommunicationWeb 2.0Vertex (graph theory)Mobile appLevel (video gaming)MereologyLine (geometry)NumberResultantBuildingConnectivity (graph theory)Web browserInstallation artVolumenvisualisierungProcess (computing)WebsiteWater vaporSlide ruleVisualization (computer graphics)Cartesian coordinate systemMachine codeElectric generatorBasis <Mathematik>Right angleSource codeQuicksortInternetworkingState observerDrop (liquid)Combinational logicHand fanOffice suiteProduct (business)Event horizonNormal (geometry)Statement (computer science)String (computer science)Network topologyTheoryDifferent (Kate Ryan album)Software developerGraphical user interfaceDefault (computer science)Open sourceRemote procedure callSoftware frameworkWeb applicationRevision controlBitBinary codeCommon Language InfrastructureComputer animation
Computer fileGame controllerRouter (computing)Template (C++)Component-based software engineeringEndliche ModelltheorieProcess (computing)Computing platformEuclidean vectorCase moddingClique-widthExecution unitRevision controlMobile appWindowTelecommunicationWeb browserComputer fileCartesian coordinate systemPresentation of a group1 (number)Uniform resource locatorServer (computing)QuicksortEvent horizonState of matterSubject indexingIntegerRight angleCASE <Informatik>Default (computer science)Source code
Revision controlTotal S.A.CodeData modelAsynchronous Transfer ModeExecution unitMultiplicationBitCASE <Informatik>CuboidState of matterRight anglePower (physics)Cartesian coordinate systemVolume (thermodynamics)Context awarenessSocket-SchnittstelleFormal languageDifferent (Kate Ryan album)Gene clusterKey (cryptography)TelecommunicationReplication (computing)Mobile appObject (grammar)DialectProcess (computing)Software testingQuicksortDiffuser (automotive)Multiplication signMereologyGraph (mathematics)Vertex (graph theory)Open setGraphical user interfaceWeb 2.0Web applicationGame controllerComputer fileResolvent formalismVideo game consoleComputer animation
Mobile appMaxima and minimaRevision controlVertex (graph theory)Point (geometry)Mobile appCartesian coordinate systemQuicksortProof theoryExecution unitModule (mathematics)Computing platformEndliche ModelltheorieControl flowNumberSoftware testingTelecommunicationWeb browserPresentation of a groupWordComputer animation
Menu (computing)PredictabilityMotion blurExecution unitUtility softwareSet (mathematics)Instance (computer science)Element (mathematics)TouchscreenSoftware repositoryWeb browserSoftware testingWindowRevision controlAirfoilPoint cloudComa BerenicesTotal S.A.Default (computer science)Computing platformBuildingComputer fileEmailMobile appBlogScripting languageOpen setUniform resource locatorAsynchronous Transfer ModeContent (media)Context awarenessComponent-based software engineeringTemplate (C++)Form (programming)IntelPrice indexRouter (computing)outputCore dumpMenu (computing)Mobile appContext awarenessTelecommunicationMachine codeEndliche ModelltheorieCartesian coordinate systemDifferent (Kate Ryan album)Binary codeBuildingMultiplication signVarianceThread (computing)Medical imagingWeb browserVolumenvisualisierungAsynchronous Transfer ModeComputing platformSoftware testingEvent horizonLine (geometry)Computer fileWindowPhysical systemHecke operatorProduct (business)Query languageTraffic reportingQuicksortServer (computing)Graphical user interfaceCore dumpInformation securityPoint (geometry)Right angleCuboidBlock (periodic table)BitNormal (geometry)Connectivity (graph theory)Matching (graph theory)Video gameOptical disc driveVertex (graph theory)Software developerClosed setWeightVector spaceGroup actionCASE <Informatik>MathematicsMereologyDevice driverArithmetic meanWritingSpacetimeWordDistanceGame controllerNumberReplication (computing)TheoryEmailProcess (computing)Instance (computer science)Key (cryptography)Moment (mathematics)SequelMathematical analysis
AreaUniform resource locatorComputer iconExecution unitTemplate (C++)Component-based software engineeringBlogContext awarenessComputer fileGame controllerEndliche ModelltheoriePasswordRevision controlCompilerTotal S.A.Computer configurationComputing platformBuildingError messageNumbering schemeModul <Datentyp>Vertex (graph theory)EmailTelecommunicationVertex (graph theory)Right angleModule (mathematics)Cartesian coordinate systemInteractive televisionKey (cryptography)Point (geometry)Block (periodic table)MacOS XString (computer science)Object (grammar)INTEGRALVector spaceMultiplication signInheritance (object-oriented programming)Computer fileHard disk driveCross-site scriptingOperating systemWindowInternetworkingCASE <Informatik>WebsiteServer (computing)Thread (computing)EmailWeb-DesignerInstallation artScripting languageComputing platformRevision controlPasswordEndliche ModelltheorieQuicksortJunction (traffic)Physical systemBitOpen setBuildingPlanningSlide ruleTheoryVirtual machineSoftwareCycle (graph theory)Link (knot theory)Goodness of fitNumberPersonal digital assistantMathematicsContext awarenessTowerCommunications protocolSubsetComputer animation
XMLUML
Transcript: English(auto-generated)
So my name is Felix. I'm an open source engineer with Microsoft, which really
just means that I build open source for a living. I don't really have a product or anything. I'm just hanging out in the office building open source. And one of the things that I thought was really sweet, at least working with it over the last year, was Electron. And I've been a long Ember fan. And those two things work really well together.
So what I want to talk about today is pretty much how you can turn your Ember app into a desktop application, what kind of things you have to consider, how you can make your Ember app a true desktop application that also does some desktop-y stuff. It's not just a web app, and it's on tab. And then also, I'm going to show to you Ember Electron, which is pretty much where I put all the learnings and
all the automation that you could automate away from taking an Ember app into an actual Electron app. So with that being said, a very quick introduction into Electron. If you've never heard of it, that's totally fine. It's a pure developer tool. But you might be running some of the apps that use Electron. I think most prominent are Atom, Visual Studio Code,
Slack. There's a bunch of them, Brave, that new browser that is around. All of them are using Electron. Electron is essentially a combination of Chromium, the open source version of Chrome, combined with Node, and a bunch of APIs that allow you to call native stuff. So there's things like notifications, something I worked on for a solid week. Which, if you write that in C++, is pretty difficult code.
But what you can do now is you can just say, new notification. And then, all of a sudden, a notification pops up. So there's a bunch of benefits to using it. The biggest one is, of course, that it's cross-platform. That is the most straightforward one. That is what people usually like. You build your application once. And because it's using mostly web technologies, it
automatically runs on Windows, Mac OS X, and Linux if you wanted to. But the other one is, and I think that's an actually really big benefit, is that the developer tools are amazing. Because so many applications are using the same stuff, you get to use some of the tools that those people have developed to make things easier. So if you want to use the same one-click installer that
Slack uses on Windows, you can do that. If you want to use the same auto-updater that works in Atom and Visual Studio Code on Mac and Windows, where your app starts, and all of a sudden it's been updated, you can do that. All those things are part of the developer ecosystem around Electron, and it's pretty big. I don't think I'm telling any JavaScript developer anything new when I say that. But using premade stuff is a good idea. Defaults are smart.
It's a good idea not to reinvent the wheel. So before we go any further, I promise this is going to be the only technical slide. But I want to be very, very brief about how Electron works underneath, because I assume that many of you, or some of you, may have used something like Node WebKit, or
maybe CEF, the Chrome Embedded Framework. And Electron works slightly different in one way. And that is that Electron, when it starts, it's really just a process. There's no window. There's no UI to be seen. It's just a process that is Node only. And that process is able to spin up renderer processes, which are essentially just Chromium windows. And those two processes talk to each other via something
that's called the IPC. And the reason I point this out is because it's going to become important later on. But the idea is that you start not a website or a web app, you start a script first. So that script then gets to open up. Browser windows, do things, update the app, so on and so forth. So when I was working with Electron, previously I was
working with Node WebKit. And there was a really, really sweet add-on called Ember CLI Node WebKit, built by Estelle, who might be somewhere in the room. It's an amazing tool if you ever want to use Node WebKit. It just makes things a lot easier. There's a lot of defaults you have to do. And if you just want to run your Ember web app and have all the hot reloading and all that stuff, it makes
stuff tremendously easy. So really enjoying that, and also really enjoying with Estelle on that. She was amazing when we built our app in Microsoft. I thought it would be sort of nice if we had the same thing for Electron. So I took the whole thing and ported over to Electron. With Node WebKit being very similar, it was already 50% done. And there's a bunch of stuff in there that makes your
development now fairly easy. This talk was initially about all the things you have to consider and all the things you have to do. But we could just automate those away into that add-on, which makes things a lot easier. There's basically four big components to it. The first one is that it allows you to automatically set up all the defaults.
So you can turn a normal vanilla Ember app and immediately make it Electron runnable. The second one is that we can package in the Ember CLI the Ember Inspector, something called Ember CLI Remote Inspector. You might be wondering why that is necessary. Browser add-ons do not run in Electron. They don't run in Node WebKit. If you still want to use Ember Inspector, you have to
be a little bit fancy about it. The add-on does that. The third one is packaging. So you basically have an Ember app in the beginning. And then at the end, you run the binary. There has to be a sort of step in between. We run that step for you, including recompiling the native dependencies, which is more work than it sounds like, because you can't just compile them against Node.
You have to compile them against Electron. And so I have been working with C++ with Electron to give you guys Electron tools. And a quick show of hands, how many people of you touch C++ on, I want to say, like a monthly basis? There's just a few hands. So let me tell you, if I want to add a new feature to
Electron, I first have to deal with the fact that Electron has about 40 different string types. 10 of those are documented, and the other 30 are sort of like, surprise, new Chrome string type. And it was all built 20 years ago at Google, and all the people involved are dead or something, and just dropped off the internet.
And then you're sitting there. So if you don't have to deal with that, that is sort of amazing, right? And C++ is really the only other native technology that we have to truly build native apps. So all of that stuff being handled for you is sort of nice. So that being said, let's quickly go into the first command, right?
You basically install an Ember add-on. And what happens then is that automatically a blueprint generation is run. And instead of showing you more slides, I'm just going to show you what that looks like. So if we quickly close the presentation here and go over here, what I have here is just a default, boring Ember app, right?
You just run ember new, and then I wrote conf app. And this is the usual stuff I can do, instead that I also ran ember install ember-electron. And there's a few things. The most notable ones are that it now added an electron.js file. And that is really what is going to be executed by electron as soon as you run the application.
And then here you can do a few things. Like you can see right here, one of the most important events is that all windows are closed. As soon as the windows are closed, we actually leave the app. But we also go ahead and open up a new browser window and basically load the location of our Ember app. So I guess this is the first very important thing to
realize is that your application is now running without a server. There's no server to be run. And just so you guys and people know, running a server in a local app is sort of a big anti-pattern. You should never do that. So electron is not running a server for you. It's just straight up loading the file. Yeah, and then if the window is closed, we just reset the
main window. So that allows us immediately to, we could normally just say ember-serve. But in this case, we can just say ember-electron. And what that does is it builds the application. So let's give that a second to just do it real quick. It builds the application and then injects a few things you might need. So that is our application right here. Let me just show you what it briefly did here.
But it also injects the ember inspector with sockets. So what it can do now is it can head over to Chrome. Sorry, that should not launch. Just quit that right away. So I can reload this. And let's just move this over here and this application over here. And I can still inspect my electron application just like
it would inspect a normal ember app. That just works out of the box. You can do things. If your application is really, really big, sometimes it gets a little bit icky because it is just running over web sockets. But Tom and Yuda were talking about how popular ember inspector is. And I think that just speaks to how amazing the ember inspector is. Because you can just use it, which is sort of fantastic.
But the other thing is that it sets up the require and the node context in such a way that you can actually use it. So if I just open up the console right here, I can just go ahead and say process. And I can just say process.versions. What I get all of a sudden is my node object. And I can do some pretty simple things.
I can just go ahead and say rfs require fs. And what I get then is straight up fs. I can call that from within my application. You can call those things from within your ember application. And I think the implications here are fairly obvious, but it just allows your application to be much more
powerful than it may have been before as a pure web app. The big difference between a web app and a native app is not necessarily that the native app is written in a different language. It's just that the native app has more powers. It can just do more things. It can control your volume, control your file system, open files, delete files, do all those things. And I think if you look at Adam today, Adam is a pretty
powerful tool. And there isn't really that much that is missing. And the developers that work on Adam with Electron have pretty much all the tools that they need. And this is just, and with Electron in this case, it's just fairly easily making sure that you can call require inside your application. It's using the ember resolver.
And you can use it here and call ember apps. So that is sort of the easier part. Let me quickly jump back to the presentation. The next one is ember-electron-test, which again, the whole point here is just to make things easy.
The concept doesn't really have tests. But what it did bring is Ghost desktop, which is an ember application that I'm currently working on. Anyone has ever heard of the blogging platform Ghost? I'm on that team. And we're currently building a desktop app using the stuff I just showed you. And it's sort of my proof point to make sure that ember-electron works well. So normally if you just run ember-test, that doesn't really
work because you might be calling native node modules. And if you call those from a browser, everything breaks, and everything's horrible, and nothing really works, and you've got to work around that. So what we have now is ember-electron-test, which basically spins up Electron and runs your Q unit tests inside Electron. And again, it takes care of everything for you. It's pretty much automated away, and everything that is
difficult now just runs here. All your tests just run. Or don't run, in this case. We're trying very hard. The app is not released yet, but there we go. You can just run those things. You get a coverage report at the end, and everything that you normally do still works. So that just works, and it's sort of nice.
Then obviously we also have the server mode, same thing. And there isn't really anything to consider at this point, which is very convenient because normally you would have to consider a bunch of things. There isn't really any way to do this in an easy way. But now you have server mode. And I'm not going to show you hot live reloading because I think you know what it looks like.
But if I change a file and update, all the tests run again. And this is just automated away for you. And thanks to some very nice PRs, it even works on Linux, which has a slightly different file watching mode than Windows and OS X. So up to that point, it was all pretty easy stuff. And I want to say almost very boring.
What becomes more interesting is the whole step. If you go from just this folder, this embassy.li folder, over into an actual package binary, and there's a bunch of stuff you've got to do. Let me just run the build, and I'm going to walk you guys through how that actually works.
So we have this package command, and we're going to specify the platform because I don't actually have anything installed here that allows me to build other platforms. But what it does is that it builds your Ember application in production mode. It then takes all your main code, because remember, we
have two different threads. In this case, we have a renderer process, which runs my Ember application. But we still have the main thread, which runs all the stuff that Electron usually talks about, like opening new browser windows, opening a new dialogue, setting up native images. So what we do is that we also copy over that code. And I hope this is big enough. No, I can make it bigger.
And once we have done that, we create a new package.json, install the right dependencies, because you probably don't want to ship all your dev dependencies with your actual application. There's no reason for your application model to contain Babel. No user's going to need it. So we just install the actual dependencies.
Then we go over, download the Electron headers, because it turns out Electron is actually a different binary than Node. So if you want to run anything native, like SQL Lite or anything like that, you will have to recompile your dependencies. So we do that. It's just like abstracted away from you. And then we package the application. And if you go over here, there's now a folder called
Electron builds. And we now have a confab. And I can just run it. And all of a sudden, I have my confab. And that just works. There's absolutely nothing you have to do manually. It just works. So there we are. That being said, this is about the time where we can talk about some things that have become a little bit more
interesting. And what I brought for you is the Ghost Desktop app. So let me first show you the Ghost Desktop app. Let's go in here. What's this? Just say Ember Electron, which is going to build my application and spin up the Ghost app. So Ghost Desktop is going to be essentially a way to run
your blocks from a desktop way. And there's a few things we do that sort of turn it beyond just being a normal Ember app. So what you see here is essentially two Ember apps. We have an outside Ember app and an inside Ember app. So this, welcome to Ghosting here. This is all, let me just go here.
This is an empty block. This is basically the inside block. This is an Ember application by itself. But then we wrap a whole Ember application around it. And this is important because of the security model. We basically don't want to give full node access to the Ghost instance, mostly because of enough security. I'm going to talk a little bit about security at
the end of the talk. But we also want to do a bunch of native things. And this is a good point to maybe talk about some of the shortcomings Electron still has, some of the things you will have to consider when you build an Ember app. Let me start by talking about the context menu. If we just do anything right here. As you can see, you cannot see that I'm
doing a right click. But what happens is that Electron comes without a context menu. That is something you will have to set up yourself. I can show you the code. It is, in theory, fairly easy to do. But it is interesting that you have to do it in the first place. So just consider that there's a few things that you expect as a developer to just be there, which aren't really there if you can suddenly control the whole
application. Context menu, copy, paste, those things that are not automatically out of the box. Some are available. You have to get that context menu for yourself. And another thing I'm fighting with right now, which is pretty big, is something like spell check. All three platforms offer up a native spell check API that Chrome is usually hooking into.
Chromium is not hooking into that. Meaning we have a blogging app. Writing is sort of the core thing that we do. It's fairly important. We currently don't have a spell check, which is also why the application is not released yet. There's a whole developer system around it, how you get around that. But what's basically going to happen is that we're going to wait for key events, analyze the words, make
sure that those match the dictionary, and then pass it all back. Because we don't want to ship a whole dictionary, what we're going to do instead is that we're going to use the native components. But native components means all of a sudden we have C++ and so forth. You can sort of see where this is going. There's a lot of work you have to do extra. But the big benefit here is that even though you sometimes
do have to call native, you always can. There might be reasons for you to wonder why the heck you would want to call something natively. Let me just give you a very quick example. Just for fun, I worked on something called Waffle, which is a little calendar application.
And what you're seeing right now is just Ember. And the calendar application, calendars are interesting. Time is interesting. So specifically, I tried out a bunch of ways to cache my events and keep my events around. But it turns out that all the ways I could find in JavaScript to do what in SQL would be a date between query. So what you want to get is you want to get all the events
that start or end between two times. All of those are very, very slow if you run them 1,000 times. For the application to be snappy, like right here, I just want to go next and do that. And that is very, very slow. What, however, is very fast is SQLite and C. So I can just go ahead and say straight up, var SQLite equals
require SQLite. And that works inside my Ember application. There's nothing else I have to do. And the beauty here is that the way Ember is designed, and we talked to Tom about that briefly outside. I'm not surprised because it comes out of Coca-Cola. But the way Ember is set up, it makes those interactions very natural and very easy. So let me show you something else.
In the example of Ghost, I can't find my Ghost anymore because I have so many election apps open. But in the example of Ghost, you never actually have to log in. Instead, we're using the native operating system's key vault. If you never develop native apps, that's probably something you never heard about and you don't actually have to. But basically, if you manage secrets inside an application,
developers very quickly start using very insecure methods to keep passwords around. So all three platforms, Linux, Windows, and Ostend, have at some point offered developers a very easy API to just, OK, give me a string. I'm going to keep it secure. Just give me. Of course, you have to call that natively. There's a little module out there called Keytar that does that for you.
So if we go and check out our block model right now, it's pretty simple stuff, right? Get password just looks like this. I require Keytar. And I just spell it require node because that makes it clearer, but you could also just say require Keytar. And then I just run this native module. And what happens is if you compile Ghost desktop, let me
just do that here, is that melectron will handle the whole, oh, I have native dependency with C++. I've got to recompile that. And melectron will completely handle that for you. It will go and ensure that it gets the right headers for the right version of electron you're using.
It will recompile them with the build tools you have. But this is an interesting junction for, I see a lot of Macs here, as there is to be expected at EmberCon. This is an interesting junction because it suddenly requires you to more or less install all the systems. Because as soon as you have native dependencies, you will
actually need native build tools, right? You cannot build a Windows application without having the native Windows application build tools the same way around. You can actually do it from Mac OS X by installing Wine. And then it suddenly works. In theory, you can build Linux from both platforms. We had a bit of trouble with that. But in theory, that is possible.
But the biggest gotcha is also something web developers never think about, like me. We released a developer preview of Ghost desktop. And I just built that on my machine, which is 64-bit. It's a normal MacBook. Turns out if you have 32-bit, it didn't even start. Oh, right. Sort of forgot.
Sorry. Yeah, those things happen, right? So basically, and then I updated it to specifically say this. Just so you know, this is the platform you're compiling for. It's suddenly more than just an operating system.
But all that being said, let me go into my last slide, because I think it's an important one. Because every now and then, at least us in the Electron team get questions that make me very, very concerned. And we already had the first cases. So I work for Microsoft.
We recently experienced that people on the internet are mean. So apparently, nobody told us. So I want to make one thing abundantly clear, because I think the Electron team, and me included, totally failed
to make this obvious. If you build, and this is not specified to Electron. This is true for all the solutions currently that give you node access. If you thought cross-site scripting text was scary, you have not considered that as soon as you run them here, they can literally wipe your hard drive.
This is very important. I've seen that so many times. And there was actually a big case involving Electron with an anti-virus company called Avast, which had the great idea of, oh, I know how we make our normal website into an application. We host a little server that just accepts a bunch of strings, and then we execute those strings.
But the thing here is that Google actually, you can read the whole thread on the Chromium mailing list. So Google actually contacted Avast, and was like, hey, just so you know, everyone running Avast can actually totally be root-kitted from the outside. The trouble here is that many developers, I think,
don't really understand what's actually happening. So to give me a very simple example, we can open up new windows using a file string that is something that has always been possible in Chromium. So you can basically say, the same way you can install an NPM module from a string, we can create a new
window from a string. You can basically say, this is my HTML object here. This is a string. And in there, I can say pretty much anything, including exec, spawn, download new scripts, execute those new scripts. So basically what I'm saying is, if you are thinking about building a desktop app, that's amazing. You should absolutely do that. There are actually real benefits to having a desktop app, because you can integrate into the desktop a
little bit easier. You can have notifications. You can have doc menus. You can have native menus. You can have a protocol, if you want to have. So what we're going to build is ghost colon slash slash. And then you can basically do the whole post this automatically thing. There's a lot of integrations you can do. But please be aware that all of a sudden your tech vector has grown by about a bazillion percent.
And be super paranoid about what you do. And if you're not using HTTPS yet, but you still want to load remote resources, this will be a great time to start. SSL is really sweet. So in summary, please go and check this out. It's on this link. And I think I'm almost out of time.
But it's on this link. Please go and check out Ember Electron. In theory, unless you're doing anything super crazy fancy, but I've tested this with a bunch of teams inside Microsoft running Ember. And I also tested this with a bunch of people outside Microsoft running Ember. In theory, you just have to run Ember, install Ember Electron. And then Ember Electron, all of a sudden your application is going to run as an application.
And you can take it from there and see if that maybe would be a good idea for users. So that will be the talk. Thank you very much.