{"id":5106,"date":"2019-01-07T21:35:41","date_gmt":"2019-01-07T20:35:41","guid":{"rendered":"https:\/\/monodes.com\/predaelli\/?p=5106"},"modified":"2019-01-07T11:36:00","modified_gmt":"2019-01-07T10:36:00","slug":"how-to-easily-build-desktop-apps-with-html-css-and-javascript","status":"publish","type":"post","link":"https:\/\/monodes.com\/predaelli\/2019\/01\/07\/how-to-easily-build-desktop-apps-with-html-css-and-javascript\/","title":{"rendered":"How to Easily Build Desktop Apps with HTML, CSS and Javascript"},"content":{"rendered":"<blockquote><p>Can HTML, CSS and Javascript really be used to build Desktop Applications?<\/p><\/blockquote>\n<p>Source: <em><a href=\"https:\/\/adityasridhar.com\/posts\/desktop-apps-with-html-css-javascript\">How to Easily Build Desktop Apps with HTML, CSS and Javascript<\/a><\/em><\/p>\n<p><!--more--><!--nextpage--><\/p>\n<blockquote>\n<h1 id=\"b91b\" class=\"graf graf--h3 graf--leading graf--title\">How to Easily Build Desktop Apps with HTML, CSS and Javascript<\/h1>\n<div class=\"uiScale uiScale-ui--regular uiScale-caption--regular u-flexCenter u-marginVertical24 u-fontSize15 js-postMetaLockup\">\n<div class=\"u-flex0\"><\/div>\n<div class=\"u-flex1 u-paddingLeft15 u-overflowHidden\">\n<div class=\"u-paddingBottom3\"><a class=\"ds-link ds-link--styleSubtle ui-captionStrong u-inlineBlock link link--darken link--darker\" dir=\"auto\" href=\"https:\/\/medium.freecodecamp.org\/@aditya_sridhar\" data-action=\"show-user-card\" data-action-value=\"40655dbea7f6\" data-action-type=\"hover\" data-user-id=\"40655dbea7f6\" data-collection-slug=\"free-code-camp\">Aditya Sridhar<\/a><\/div>\n<\/div>\n<\/div>\n<div class=\"uiScale uiScale-ui--regular uiScale-caption--regular u-flexCenter u-marginVertical24 u-fontSize15 js-postMetaLockup\">\n<div class=\"u-flex1 u-paddingLeft15 u-overflowHidden\">\n<div class=\"ui-caption postMetaInline js-testPostMetaInlineSupplemental\"><time datetime=\"2019-01-04T21:53:22.521Z\">Jan 4<\/time><\/div>\n<\/div>\n<\/div>\n<figure id=\"5d03\" class=\"graf graf--figure graf-after--h3\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"0*mwIqsFZSbnweFQuv\" data-width=\"4272\" data-height=\"2848\" data-unsplash-photo-id=\"dPgPoiUIiXk\" data-is-featured=\"true\" data-action=\"zoom\" data-action-value=\"0*mwIqsFZSbnweFQuv\" data-scroll=\"native\"><\/div>\n<\/div>\n<\/figure>\n<figure id=\"5d03\" class=\"graf graf--figure graf-after--h3\">Can HTML, CSS and Javascript really be used to build Desktop Applications?<\/figure>\n<p id=\"6a2e\" class=\"graf graf--p graf-after--p\">The answer is yes. \ud83d\ude04<\/p>\n<p id=\"40ec\" class=\"graf graf--p graf-after--p\">In this Article we will be focussing mainly on how Electron can be used to create desktop applications with Web Technologies like HTML, CSS and Javascript.<\/p>\n<h3 id=\"4904\" class=\"graf graf--h3 graf-after--p\">Electron<\/h3>\n<p id=\"84a4\" class=\"graf graf--p graf-after--h3\"><a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/electronjs.org\/\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/electronjs.org\/\">Electron<\/a> can be used to build Desktop Apps with HTML, CSS and Javascript. Also these apps work for multiple platforms like Windows, Mac, Linux and so on.<\/p>\n<p id=\"844b\" class=\"graf graf--p graf-after--p\">Electron combines Chromium and NodeJS into a single runtime. This enables us to run the HTML, CSS and Javascript code as a desktop application.<\/p>\n<h3 id=\"e801\" class=\"graf graf--h3 graf-after--p\">Electron Forge<\/h3>\n<p id=\"54c3\" class=\"graf graf--p graf-after--h3\">If Electron is used directly, then some manual setup is needed before building your application. Also if you want to use Angular, React, Vue or any other framework or library, you will need to manually configure for that.<\/p>\n<p id=\"e1b6\" class=\"graf graf--p graf-after--p\"><a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/electronforge.io\/\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/electronforge.io\/\">Electron Forge<\/a> makes the above things much easier.<\/p>\n<p id=\"4ecc\" class=\"graf graf--p graf-after--p\">It provides template applications with Angular, React, Vue and other frameworks which avoids the extra manual setups.<\/p>\n<p id=\"ae12\" class=\"graf graf--p graf-after--p\">Also it provides an easy way to build and package the application. It also provides many other features which can be found in their <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/docs.electronforge.io\/\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/docs.electronforge.io\/\">documenation<\/a>.<\/p>\n<h3 id=\"e371\" class=\"graf graf--h3 graf-after--p\">Pre-requisites<\/h3>\n<p id=\"ce87\" class=\"graf graf--p graf-after--h3\">Ensure you have NodeJS installed. It can be installed from <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/nodejs.org\/en\/\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/nodejs.org\/en\/\">here<\/a>.<\/p>\n<p id=\"96ce\" class=\"graf graf--p graf-after--p\">Install Electron Forge globally using the following command:<\/p>\n<pre id=\"d21f\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">npm install -g electron-forge<\/code><\/pre>\n<h3 id=\"3290\" class=\"graf graf--h3 graf-after--pre\">Let\u2019s get started with the application<\/h3>\n<p id=\"101a\" class=\"graf graf--p graf-after--h3\">Use the following command to create your application:<\/p>\n<pre id=\"2761\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">electron-forge init simple-desktop-app-electronjs<\/code><\/pre>\n<p id=\"6346\" class=\"graf graf--p graf-after--pre\"><strong class=\"markup--strong markup--p-strong\">simple-desktop-app-electronjs<\/strong> is the name of the application.<\/p>\n<p id=\"3ed8\" class=\"graf graf--p graf-after--p\">The above command will take some time to run.<\/p>\n<p id=\"f174\" class=\"graf graf--p graf-after--p\">Once it finishes running, start the application using the following commands:<\/p>\n<pre id=\"35f1\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">cd simple-desktop-app-electronjs\nnpm start<\/code><\/pre>\n<p id=\"6d3e\" class=\"graf graf--p graf-after--pre\">This should open up a window like the one shown below:<\/p>\n<figure id=\"3bdf\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"0*0GItlhn34oza9bq8.jpg\" data-width=\"756\" data-height=\"380\" data-action=\"zoom\" data-action-value=\"0*0GItlhn34oza9bq8.jpg\" data-scroll=\"native\"><\/div>\n<\/div>\n<\/figure>\n<figure id=\"3bdf\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"0*0GItlhn34oza9bq8.jpg\" data-width=\"756\" data-height=\"380\" data-action=\"zoom\" data-action-value=\"0*0GItlhn34oza9bq8.jpg\" data-scroll=\"native\"><a href=\"https:\/\/medium.freecodecamp.org\/how-to-easily-build-desktop-apps-with-html-css-and-javascript-d3e3f03f95a5\"><img data-recalc-dims=\"1\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/1600\/0%2A0GItlhn34oza9bq8.jpg?w=910&#038;ssl=1\" alt=\"\"\/><\/a><\/div>\n<\/div>\n<\/figure>\n<h3 id=\"880d\" class=\"graf graf--h3 graf-after--figure\">Understanding the Existing Folder Structure and&nbsp;Code<\/h3>\n<p id=\"526f\" class=\"graf graf--p graf-after--h3\">The application has a particular folder structure. Here I will be mentioning some of the important things in this folder structure.<\/p>\n<h4 id=\"8122\" class=\"graf graf--h4 graf-after--p\">package.json<\/h4>\n<p id=\"ceb1\" class=\"graf graf--p graf-after--h4\">It has information about the application you are creating, all the dependencies needed for the app, and some scripts. Some of the scripts are already pre configured, and you can add new scripts as well.<\/p>\n<p id=\"8f80\" class=\"graf graf--p graf-after--p\">The <strong class=\"markup--strong markup--p-strong\">config.forge<\/strong> path has all the configurations which are specific to ElectronJS. For example <strong class=\"markup--strong markup--p-strong\">make-targets<\/strong> is used to specify the target make files for various platforms like Windows, Mac or Linux.<\/p>\n<p id=\"57c7\" class=\"graf graf--p graf-after--p\">Also package.json has <code class=\"\" data-line=\"\">&quot;main&quot;: &quot;src\/index.js&quot;<\/code> which indicates that src\/index.js is the starting point of the application<\/p>\n<h4 id=\"7714\" class=\"graf graf--h4 graf-after--p\">src\/index.js<\/h4>\n<p id=\"049f\" class=\"graf graf--p graf-after--h4\">According to package.json, <strong class=\"markup--strong markup--p-strong\">index.js<\/strong> is the main script. The process which runs the main script is known as the <strong class=\"markup--strong markup--p-strong\">main process<\/strong>. So the main process runs the index.js script.<\/p>\n<p id=\"ff5e\" class=\"graf graf--p graf-after--p\">The main process is used to display GUI elements. It does this by creating web pages.<\/p>\n<p id=\"5596\" class=\"graf graf--p graf-after--p\">Each web page created runs in a process called the <strong class=\"markup--strong markup--p-strong\">renderer process.<\/strong><\/p>\n<h4 id=\"5718\" class=\"graf graf--h4 graf-after--p\">Main process and renderer&nbsp;process<\/h4>\n<p id=\"f8d9\" class=\"graf graf--p graf-after--h4\">The purpose of the <strong class=\"markup--strong markup--p-strong\">main process<\/strong> is to create web pages using a <code class=\"\" data-line=\"\">BrowserWindow<\/code> Instance.<\/p>\n<p id=\"b2f9\" class=\"graf graf--p graf-after--p\">The <code class=\"\" data-line=\"\">BrowserWindow<\/code> Instance uses a <strong class=\"markup--strong markup--p-strong\">renderer process<\/strong> to run each web page.<\/p>\n<p id=\"17ba\" class=\"graf graf--p graf-after--p\"><strong class=\"markup--strong markup--p-strong\">Each app can have only one main process but can have many renderer processes.<\/strong><\/p>\n<p id=\"a95e\" class=\"graf graf--p graf-after--p\">It is possible to communicate between the main and the renderer process as well. This, however, will not be covered in this article.<\/p>\n<figure id=\"2fc0\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"0*_KAbfHP3uc1f21bf.jpg\" data-width=\"848\" data-height=\"498\" data-action=\"zoom\" data-action-value=\"0*_KAbfHP3uc1f21bf.jpg\" data-scroll=\"native\"><\/div>\n<\/div>\n<\/figure>\n<figure id=\"2fc0\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"0*_KAbfHP3uc1f21bf.jpg\" data-width=\"848\" data-height=\"498\" data-action=\"zoom\" data-action-value=\"0*_KAbfHP3uc1f21bf.jpg\" data-scroll=\"native\"><a href=\"https:\/\/medium.freecodecamp.org\/how-to-easily-build-desktop-apps-with-html-css-and-javascript-d3e3f03f95a5\"><img data-recalc-dims=\"1\" decoding=\"async\" class=\"alignnone size-full\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/1600\/0%2A_KAbfHP3uc1f21bf.jpg?w=910&#038;ssl=1\" alt=\"\"\/><\/a><\/div>\n<\/div><figcaption class=\"imageCaption\"><em class=\"markup--em markup--figure-em\">Electron Architecture showing main and renderer process. The file names can&nbsp;vary.<\/em><\/figcaption><\/figure>\n<p id=\"ea1d\" class=\"graf graf--p graf-after--figure\"><strong class=\"markup--strong markup--p-strong\">abcd.html<\/strong> is shown as a second webpage in the above architecture. But in our code we won\u2019t be having a second web page.<\/p>\n<h4 id=\"284c\" class=\"graf graf--h4 graf-after--p\">src\/index.html<\/h4>\n<p id=\"47b1\" class=\"graf graf--p graf-after--h4\">index.js loads the index.html file into a new BrowerWindow Instance.<\/p>\n<p id=\"1309\" class=\"graf graf--p graf-after--p\">What this basically means is that index.js creates a new GUI Window, and loads it with index.html web page. The index.html web page runs in its own renderer process.<\/p>\n<h4 id=\"e21c\" class=\"graf graf--h4 graf-after--p\">Code in index.js explained<\/h4>\n<p id=\"fd25\" class=\"graf graf--p graf-after--h4\">Most of the code created in index.js has good comments explaining what it does. Here I will mention a few key points to note in index.js:<\/p>\n<pre id=\"2132\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">mainWindow &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;=&lt;\/strong&gt; &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;new&lt;\/strong&gt; BrowserWindow({\n    width: 800,\n    height: 600,\n  });\n\n  &lt;em class=&quot;markup--em markup--pre-em&quot;&gt;\/\/ and load the index.html of the app.&lt;\/em&gt;\n  mainWindow.loadURL(`file:\/\/${__dirname}\/index.html`);<\/code><\/pre>\n<p id=\"6afb\" class=\"graf graf--p graf-after--pre\">The above code snippet basically creates a <strong class=\"markup--strong markup--p-strong\">BrowserWindow<\/strong> Instance and loads <strong class=\"markup--strong markup--p-strong\">index.html<\/strong> into the BrowserWindow.<\/p>\n<p id=\"6e29\" class=\"graf graf--p graf-after--p\">You will see <strong class=\"markup--strong markup--p-strong\">app<\/strong> used often in the code. For example take the below code snippet:<\/p>\n<pre id=\"494e\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">app.on(&#039;ready&#039;, createWindow);<\/code><\/pre>\n<p id=\"8ba6\" class=\"graf graf--p graf-after--pre\"><strong class=\"markup--strong markup--p-strong\">app<\/strong> is used to control the application\u2019s event life cycle.<\/p>\n<p id=\"0519\" class=\"graf graf--p graf-after--p\">The above code snippet says that when the application is ready, load the first window.<\/p>\n<p id=\"1297\" class=\"graf graf--p graf-after--p\">Similarly, <strong class=\"markup--strong markup--p-strong\">app<\/strong> can be used to perform other actions on various events. For example it can be used to perform some action right before the application closes and so on.<\/p>\n<h3 id=\"6901\" class=\"graf graf--h3 graf-after--p\">Let\u2019s create a Temperature Converter Desktop Application<\/h3>\n<p id=\"885a\" class=\"graf graf--p graf-after--h3\">Let us use the same application we used before and modify it slightly to create a temperature converter application.<\/p>\n<p id=\"47ce\" class=\"graf graf--p graf-after--p\">First let us install Bootstrap with the following command:<\/p>\n<pre id=\"15ca\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">npm install bootstrap --save<\/code><\/pre>\n<p id=\"5507\" class=\"graf graf--p graf-after--pre\">Copy the following code into src\/index.html:<\/p>\n<pre id=\"82fc\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">&lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;&lt;!DOCTYPE html&gt;&lt;\/strong&gt;\n&lt;html&gt;\n  &lt;head&gt;\n    &lt;meta charset=&quot;utf-8&quot;&gt;\n    &lt;title&gt;Temperature Converter&lt;\/title&gt;\n    &lt;link rel=&quot;stylesheet&quot; type=&quot;text\/css&quot; href=&quot;..\/node_modules\/bootstrap\/dist\/css\/bootstrap.min.css&quot;&gt;\n\n  &lt;\/head&gt;\n  &lt;body&gt;\n    &lt;h1&gt;Temperature Converter&lt;\/h1&gt;\n    &lt;div class=&quot;form-group col-md-3&quot;&gt;\n      &lt;label for=&quot;usr&quot;&gt;Celcius:&lt;\/label&gt;\n      &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;celcius&quot; onkeyup=&quot;celciusToFahrenheit()&quot;&gt;\n    &lt;\/div&gt;\n    &lt;div class=&quot;form-group col-md-3&quot;&gt;\n      &lt;label for=&quot;pwd&quot;&gt;Fahrenheit:&lt;\/label&gt;\n      &lt;input type=&quot;text&quot; class=&quot;form-control&quot; id=&quot;fahrenheit&quot; onkeyup=&quot;fahrenheitToCelcius()&quot;&gt;\n    &lt;\/div&gt;\n    &lt;script src=&#039;.\/renderer.js&#039;&gt;&lt;\/script&gt;\n  &lt;\/body&gt;\n  &lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<p id=\"a65e\" class=\"graf graf--p graf-after--pre\">The above code does the following:<\/p>\n<ol class=\"postList\">\n<li id=\"7531\" class=\"graf graf--li graf-after--p\">Creates a text box with id <strong class=\"markup--strong markup--li-strong\">Celcius<\/strong>. Whenever anything is typed in this textbox, the <strong class=\"markup--strong markup--li-strong\">celciusToFahrenheit()<\/strong> function is called.<\/li>\n<li id=\"42ea\" class=\"graf graf--li graf-after--li\">Creates a text box with id <strong class=\"markup--strong markup--li-strong\">Fahrenheit<\/strong>. Whenever anything is typed in this textbox, the <strong class=\"markup--strong markup--li-strong\">fahrenheitToCelcius()<\/strong> function is called.<\/li>\n<li id=\"22d3\" class=\"graf graf--li graf-after--li\">Whenever a new value is typed in the Celcius text box, the value in the Fahrenheit text box displays the same temperature in Fahrenheit<\/li>\n<li id=\"6751\" class=\"graf graf--li graf-after--li\">Whenever a new value is typed in the Fahrenheit text box, the value in the Celcius text box displays the same temperature in Celcius<\/li>\n<\/ol>\n<p id=\"2b4f\" class=\"graf graf--p graf-after--li\">The 2 functions which do the temperature conversion are present in <strong class=\"markup--strong markup--p-strong\">renderer.js.<\/strong><\/p>\n<p id=\"fff2\" class=\"graf graf--p graf-after--p\">Create a file called <strong class=\"markup--strong markup--p-strong\">renderer.js<\/strong> inside <strong class=\"markup--strong markup--p-strong\">src<\/strong>. Copy the following code into it:<\/p>\n<pre id=\"7274\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">&lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;function&lt;\/strong&gt; celciusToFahrenheit(){\n    &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;let&lt;\/strong&gt; celcius &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;=&lt;\/strong&gt; document.getElementById(&#039;celcius&#039;).value;\n    &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;let&lt;\/strong&gt; fahrenheit &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;=&lt;\/strong&gt; (celcius&lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;*&lt;\/strong&gt; 9&lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;\/&lt;\/strong&gt;5) &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;+&lt;\/strong&gt; 32;\n    document.getElementById(&#039;fahrenheit&#039;).value &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;=&lt;\/strong&gt; fahrenheit;\n\n}\n\n&lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;function&lt;\/strong&gt; fahrenheitToCelcius(){\n    &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;let&lt;\/strong&gt; fahrenheit &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;=&lt;\/strong&gt; document.getElementById(&#039;fahrenheit&#039;).value;\n    &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;let&lt;\/strong&gt; celcius &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;=&lt;\/strong&gt; (fahrenheit &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;-&lt;\/strong&gt; 32) &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;*&lt;\/strong&gt; 5&lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;\/&lt;\/strong&gt;9\n    document.getElementById(&#039;celcius&#039;).value &lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;=&lt;\/strong&gt; celcius;\n}<\/code><\/pre>\n<p id=\"7b52\" class=\"graf graf--p graf-after--pre\">The<strong class=\"markup--strong markup--p-strong\"> celciusToFahrenheit()<\/strong> function reads the value in the <strong class=\"markup--strong markup--p-strong\">Celcius<\/strong> text box, converts it to Fahrenheit, and writes the new temperature into the <strong class=\"markup--strong markup--p-strong\">Fahrenheit<\/strong> text box.<\/p>\n<p id=\"17ef\" class=\"graf graf--p graf-after--p\">The<strong class=\"markup--strong markup--p-strong\"> fahrenheitToCelcius()<\/strong> function does the exact opposite of this.<\/p>\n<h3 id=\"dcbd\" class=\"graf graf--h3 graf-after--p\">Running the application<\/h3>\n<p id=\"5334\" class=\"graf graf--p graf-after--h3\">Run the application using the following command:<\/p>\n<pre id=\"1a9f\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">npm start<\/code><\/pre>\n<p id=\"5831\" class=\"graf graf--p graf-after--pre\">This should display the following window. Try it out with different values.<\/p>\n<figure id=\"094e\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"0*YRm0cLilFtYLE2Q0.jpg\" data-width=\"593\" data-height=\"335\" data-scroll=\"native\"><\/div>\n<\/div>\n<\/figure>\n<figure id=\"094e\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"0*YRm0cLilFtYLE2Q0.jpg\" data-width=\"593\" data-height=\"335\" data-scroll=\"native\"><img data-recalc-dims=\"1\" decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/i0.wp.com\/cdn-images-1.medium.com\/max\/1600\/0%2AYRm0cLilFtYLE2Q0.jpg?w=910&#038;ssl=1\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/1600\/0*YRm0cLilFtYLE2Q0.jpg\"\/><\/div>\n<\/div>\n<\/figure>\n<h3 id=\"8eaa\" class=\"graf graf--h3 graf-after--figure\">Packaging the application<\/h3>\n<p id=\"23ea\" class=\"graf graf--p graf-after--h3\">The command to package the application is:<\/p>\n<pre id=\"71f6\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">npm run package<\/code><\/pre>\n<p id=\"7099\" class=\"graf graf--p graf-after--pre\">This command will take some time to run. Once it finishes check the <strong class=\"markup--strong markup--p-strong\">out<\/strong> folder within the project folder.<\/p>\n<p id=\"13c9\" class=\"graf graf--p graf-after--p\">I tested this in a Windows machine. This creates a folder called <strong class=\"markup--strong markup--p-strong\">simple-desktop-app-electronjs-win32-x64<\/strong> inside the <strong class=\"markup--strong markup--p-strong\">out<\/strong> folder<\/p>\n<p id=\"86e5\" class=\"graf graf--p graf-after--p\">So in the <strong class=\"markup--strong markup--p-strong\">out\/simple-desktop-app-electronjs-win32-x64<\/strong> folder, the command creates an&nbsp;<strong class=\"markup--strong markup--p-strong\">.exe<\/strong> file for this application. Clicking on the exe file automatically starts the desktop application.<\/p>\n<p id=\"d313\" class=\"graf graf--p graf-after--p\">The folder name <strong class=\"markup--strong markup--p-strong\">simple-desktop-app-electronjs-win32-x64<\/strong> can be broken down as <strong class=\"markup--strong markup--p-strong\">appname-platform-architecture<\/strong> where<\/p>\n<ul class=\"postList\">\n<li id=\"22f5\" class=\"graf graf--li graf-after--p\">appname = simple-desktop-app-electronjs<\/li>\n<li id=\"b158\" class=\"graf graf--li graf-after--li\">platform = win32<\/li>\n<li id=\"0416\" class=\"graf graf--li graf-after--li\">architecture = x64<\/li>\n<\/ul>\n<p id=\"4d7a\" class=\"graf graf--p graf-after--li\"><strong class=\"markup--strong markup--p-strong\">When you run this command without any parameters, by default it packages for the platform which you are using for development.<\/strong><\/p>\n<p id=\"591b\" class=\"graf graf--p graf-after--p\">Let\u2019s say you want to package for a different platform and architecture. Then you can use the following syntax:<\/p>\n<pre id=\"7f85\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">npm run package -- --platform=&lt;platform&gt; arch=&lt;architecture&gt;<\/code><\/pre>\n<p id=\"6b9f\" class=\"graf graf--p graf-after--pre\">For example, in order to package for linux you can use the following command:<\/p>\n<pre id=\"60cd\" class=\"graf graf--pre graf-after--p\"><code class=\"\" data-line=\"\">npm run package -- --platform&lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;=&lt;\/strong&gt;linux --arch&lt;strong class=&quot;markup--strong markup--pre-strong&quot;&gt;=&lt;\/strong&gt;x64<\/code><\/pre>\n<p id=\"0c6b\" class=\"graf graf--p graf-after--pre\">This will create a folder called <strong class=\"markup--strong markup--p-strong\">simple-desktop-app-electronjs-linux-x64<\/strong> inside the <strong class=\"markup--strong markup--p-strong\">out<\/strong> folder.<\/p>\n<h3 id=\"ea09\" class=\"graf graf--h3 graf-after--p\">Creating a make&nbsp;File<\/h3>\n<p id=\"5792\" class=\"graf graf--p graf-after--h3\">In order to create a make file or an installer for the application, use the following command:<\/p>\n<pre id=\"7c40\" class=\"graf graf--pre graf-after--p\">npm run make<\/pre>\n<p id=\"c796\" class=\"graf graf--p graf-after--pre\">This command will take some time to run. Once it finishes check the <strong class=\"markup--strong markup--p-strong\">out<\/strong> folder within the project folder.<\/p>\n<p id=\"3f92\" class=\"graf graf--p graf-after--p\">The <strong class=\"markup--strong markup--p-strong\">out\/make<\/strong> folder will have a Windows installer for the desktop application.<\/p>\n<p id=\"ef01\" class=\"graf graf--p graf-after--p\"><strong class=\"markup--strong markup--p-strong\">When you run this command without any parameters, by default it creates the installer for the platform which you are using for development.<\/strong><\/p>\n<h3 id=\"2e85\" class=\"graf graf--h3 graf-after--p\">Code<\/h3>\n<p id=\"ec7b\" class=\"graf graf--p graf-after--h3\">The code for this desktop application is available in my GitHub repo:<\/p>\n<p id=\"0aaf\" class=\"graf graf--p graf-after--p\"><a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/aditya-sridhar\/simple-desktop-app-electronjs\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/aditya-sridhar\/simple-desktop-app-electronjs\">https:\/\/github.com\/aditya-sridhar\/simple-desktop-app-electronjs<\/a><\/p>\n<h3 id=\"aefc\" class=\"graf graf--h3 graf-after--p\">Congrats \ud83d\ude04<\/h3>\n<p id=\"38b8\" class=\"graf graf--p graf-after--h3\">You now know how to create desktop applications using HTML, CSS and Javascript.<\/p>\n<p id=\"527f\" class=\"graf graf--p graf-after--p\">This article covered very basic concepts of Electron and Electron-Forge.<\/p>\n<p id=\"02fc\" class=\"graf graf--p graf-after--p\">To know more about them, you can check out their documentation.<\/p>\n<h3 id=\"fd70\" class=\"graf graf--h3 graf-after--p\">About the&nbsp;author<\/h3>\n<p id=\"8f94\" class=\"graf graf--p graf-after--h3\">I love technology and follow the advancements in the field. I also like helping others with my technology knowledge.<\/p>\n<p id=\"9779\" class=\"graf graf--p graf-after--p\">Feel free to connect with me on my LinkedIn account <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/www.linkedin.com\/in\/aditya1811\/\" target=\"_blank\" rel=\"nofollow noopener noopener noopener noopener noopener noopener noopener noopener noopener noopener\" data-href=\"https:\/\/www.linkedin.com\/in\/aditya1811\/\">https:\/\/www.linkedin.com\/in\/aditya1811\/<\/a><\/p>\n<p id=\"f09e\" class=\"graf graf--p graf-after--p\">You can also follow me on twitter <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/twitter.com\/adityasridhar18\" target=\"_blank\" rel=\"nofollow noopener noopener noopener noopener noopener noopener noopener noopener\" data-href=\"https:\/\/twitter.com\/adityasridhar18\">https:\/\/twitter.com\/adityasridhar18<\/a><\/p>\n<p id=\"6d2b\" class=\"graf graf--p graf-after--p graf--trailing\">My Website: <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/adityasridhar.com\/\" target=\"_blank\" rel=\"nofollow noopener noopener noopener noopener noopener noopener noopener\" data-href=\"https:\/\/adityasridhar.com\/\">https:\/\/adityasridhar.com\/<\/a><\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p class=\"excerpt\">Can HTML, CSS and Javascript really be used to build Desktop Applications? Source: How to Easily Build Desktop Apps with HTML, CSS and Javascript<\/p>\n<p class=\"more-link-p\"><a class=\"more-link\" href=\"https:\/\/monodes.com\/predaelli\/2019\/01\/07\/how-to-easily-build-desktop-apps-with-html-css-and-javascript\/\">Read more &rarr;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[72,50],"tags":[],"class_list":["post-5106","post","type-post","status-publish","format-standard","hentry","category-documentations","category-javascript"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6daft-1km","jetpack-related-posts":[{"id":15415,"url":"https:\/\/monodes.com\/predaelli\/2026\/03\/30\/elena-the-tiny-library-to-build-progressive-web-components\/","url_meta":{"origin":5106,"position":0},"title":"Elena, the tiny library to build Progressive Web Components.","author":"Paolo Redaelli","date":"2026-03-30","format":false,"excerpt":"\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2591\u2591\u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2588\u2591\u2591\u2588\u2588\u2588 \u2591\u2588\u2588\u2588 \u2588 \u2591 \u2591\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2588\u2588\u2588 \u2588\u2588\u2588\u2591\u2591\u2588\u2588\u2588\u2591\u2591\u2588\u2588\u2588\u2591\u2591\u2588\u2588\u2588 \u2591\u2591\u2591\u2591\u2591\u2588\u2588\u2588 \u2591\u2588\u2588\u2588\u2591\u2591\u2588 \u2591\u2588\u2588\u2588 \u2591\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2588\u2588\u2588 \u2591\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2591\u2588\u2588\u2588 \u2591 \u2588 \u2591\u2588\u2588\u2588 \u2591\u2588\u2588\u2588\u2591\u2591\u2591 \u2591\u2588\u2588\u2588 \u2591\u2588\u2588\u2588 \u2588\u2588\u2588\u2591\u2591\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2591\u2591\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2591\u2591\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591 \u2591\u2591\u2591\u2591\u2591 \u2591\u2591\u2591\u2591\u2591\u2591 \u2591\u2591\u2591\u2591 \u2591\u2591\u2591\u2591\u2591 \u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2591\u2588 Simple, tiny library for building Progressive Web Components.| Elena is a simple, tiny library\u2026","rel":"","context":"In &quot;Web&quot;","block_context":{"text":"Web","link":"https:\/\/monodes.com\/predaelli\/category\/web\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":7689,"url":"https:\/\/monodes.com\/predaelli\/2020\/10\/17\/11-frontend-tricks-that-most-frontend-developers-dont-know-about-by-daniel-anderson-javascript-in-plain-english-oct-2020-medium\/","url_meta":{"origin":5106,"position":1},"title":"11 Frontend tricks that most Frontend Developers don\u2019t know about | by Daniel Anderson | JavaScript In Plain English | Oct, 2020 | Medium","author":"Paolo Redaelli","date":"2020-10-17","format":false,"excerpt":"Interesting tricks you can do with HTML\/JS\/CSS Source: 11 Frontend tricks that most Frontend Developers don\u2019t know about | by Daniel Anderson | JavaScript In Plain English | Oct, 2020 | Medium 11 Frontend tricks that most Frontend Developers don\u2019t know about Interesting tricks you can do with HTML\/JS\/CSS Below\u2026","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/monodes.com\/predaelli\/category\/javascript\/"},"img":{"alt_text":"Image for post","src":"https:\/\/i0.wp.com\/monodes.com\/predaelli\/wp-content\/uploads\/sites\/4\/2020\/10\/10U-rN1M_Vh0a2Cs_TAnGKw.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":3701,"url":"https:\/\/monodes.com\/predaelli\/2018\/01\/24\/dpkg-how-to-install-scratch-2-on-ubuntu-16-10-or-17-04-64bit-ask-ubuntu\/","url_meta":{"origin":5106,"position":2},"title":"dpkg &#8211; How to install Scratch 2 on Ubuntu 16.10. or 17.04 (64bit)? &#8211; Ask Ubuntu","author":"Paolo Redaelli","date":"2018-01-24","format":false,"excerpt":"Today my daughter asked me to install Scratch. But not the tablet. I already did it. On the computer. I tought it was a breeze. Actually it was as simple as \"sudo apt install scratch\". Too bad I got an oldish 1.4 version and her book refers to version 2.0.\u2026","rel":"","context":"In &quot;Proprietary software&quot;","block_context":{"text":"Proprietary software","link":"https:\/\/monodes.com\/predaelli\/category\/software\/proprietary-software\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":9861,"url":"https:\/\/monodes.com\/predaelli\/2022\/11\/20\/epicyon-activitypub-server\/","url_meta":{"origin":5106,"position":3},"title":"Epicyon ActivityPub server","author":"Paolo Redaelli","date":"2022-11-20","format":false,"excerpt":"Epicyon ActivityPub serverActivityPub server written in Python, HTML and CSS, and suitable for self-hosting on single board computers I may have found a Fediverse server I want to run \u00a0 Epicyon is a fediverse server suitable for self-hosting a small number of accounts on low power systems. Key features: Open\u2026","rel":"","context":"In &quot;Senza categoria&quot;","block_context":{"text":"Senza categoria","link":"https:\/\/monodes.com\/predaelli\/category\/senza-categoria\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":5369,"url":"https:\/\/monodes.com\/predaelli\/2019\/03\/19\/8-useful-css-tricks-parallax-images-sticky-footers-and-more\/","url_meta":{"origin":5106,"position":4},"title":"8 useful CSS tricks: Parallax images, sticky footers and more","author":"Paolo Redaelli","date":"2019-03-19","format":"link","excerpt":"8 useful CSS tricks: Parallax images, sticky footers and more This article shares some of my most satisfying \u201cah-hah!\u201d moments learning CSS, and I hope it can prompt some \u201cah-hah!\u201d moments for you too. Sticky Footer Zoom-on-Hover Images Instant Night Mode Custom Bullet Points Parallax Images Animation with Cropped Images\u2026","rel":"","context":"In &quot;HTML&quot;","block_context":{"text":"HTML","link":"https:\/\/monodes.com\/predaelli\/category\/html\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":5071,"url":"https:\/\/monodes.com\/predaelli\/2018\/12\/18\/are-your-js-project-fat\/","url_meta":{"origin":5106,"position":5},"title":"Are your js project fat?","author":"Paolo Redaelli","date":"2018-12-18","format":false,"excerpt":"https:\/\/css-tricks.com\/how-to-worry-about-npm-package-weight\/ tells you how to curb your import madness","rel":"","context":"In &quot;Javascript&quot;","block_context":{"text":"Javascript","link":"https:\/\/monodes.com\/predaelli\/category\/javascript\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts\/5106","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/comments?post=5106"}],"version-history":[{"count":0,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/posts\/5106\/revisions"}],"wp:attachment":[{"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/media?parent=5106"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/categories?post=5106"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/monodes.com\/predaelli\/wp-json\/wp\/v2\/tags?post=5106"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}