<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.4.3">Jekyll</generator><link href="https://electron.atom.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://electron.atom.io/" rel="alternate" type="text/html" /><updated>2017-06-14T16:14:46+00:00</updated><id>https://electron.atom.io/</id><title type="html">Electron</title><subtitle>Build cross platform desktop apps with JavaScript, HTML, and CSS.</subtitle><entry><title type="html">Announcing TypeScript support in Electron</title><link href="https://electron.atom.io/blog/2017/06/01/typescript" rel="alternate" type="text/html" title="Announcing TypeScript support in Electron" /><published>2017-06-01T00:00:00+00:00</published><updated>2017-06-01T00:00:00+00:00</updated><id>https://electron.atom.io/blog/2017/06/01/typescript</id><content type="html" xml:base="https://electron.atom.io/blog/2017/06/01/typescript">&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;electron&lt;/code&gt; npm package now includes a TypeScript definition file that provides detailed annotations of the entire Electron API. These annotation can improve your Electron development
experience &lt;strong&gt;even if you’re writing vanilla JavaScript&lt;/strong&gt;. Just
&lt;code class=&quot;highlighter-rouge&quot;&gt;npm install electron&lt;/code&gt; to get up-to-date Electron typings in your project.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;TypeScript is an open-source programming language created by Microsoft. It’s
a superset of JavaScript that extends the language by adding support for
static types. The TypeScript community has grown quickly in recent years,
and TypeScript was ranked among the
&lt;a href=&quot;https://stackoverflow.com/insights/survey/2017#technology-most-loved-dreaded-and-wanted-languages&quot;&gt;most loved programming languages&lt;/a&gt;
in a recent Stack Overflow developer survey.  TypeScript is described 
as “JavaScript that scales”, and teams at
&lt;a href=&quot;https://githubengineering.com/how-four-native-developers-wrote-an-electron-app/&quot;&gt;GitHub&lt;/a&gt;, 
&lt;a href=&quot;https://slack.engineering/typescript-at-slack-a81307fa288d&quot;&gt;Slack&lt;/a&gt;,
and 
&lt;a href=&quot;https://github.com/Microsoft/vscode&quot;&gt;Microsoft&lt;/a&gt;
are all using it to write scalable Electron apps that are used 
by millions of people.&lt;/p&gt;

&lt;p&gt;TypeScript supports many of the newer language features in JavaScript like
classes, object destructuring, and async/await, but its real differentiating
feature is &lt;strong&gt;type annotations&lt;/strong&gt;.
Declaring the input and output datatypes expected by your program can
&lt;a href=&quot;https://slack.engineering/typescript-at-slack-a81307fa288d&quot;&gt;reduce bugs&lt;/a&gt; by
helping you find errors at compile time, and the annotations can also serve
as a formal declaration of &lt;a href=&quot;https://staltz.com/all-js-libraries-should-be-authored-in-typescript.html&quot;&gt;how your program works&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When libraries are written in vanilla Javascript, the types are often vaguely
defined as an afterthought when writing documentation. Functions can often
accept more types than what was documented, or a function can have invisible
constraints that are not documented, which can lead to runtime errors.&lt;/p&gt;

&lt;p&gt;TypeScript solves this problem with &lt;strong&gt;definition files&lt;/strong&gt;.
A TypeScript definition file describes all the functions of a library and its
expected input and output types. When library authors bundle a TypeScript
definition file with their published library, consumers of that library can
&lt;a href=&quot;https://code.visualstudio.com/docs/editor/intellisense&quot;&gt;explore its API right inside their editor&lt;/a&gt;
and start using it right away, often without needing to consult the library’s
documentation.&lt;/p&gt;

&lt;p&gt;Many popular projects like
&lt;a href=&quot;https://angularjs.org/&quot;&gt;Angular&lt;/a&gt;,
&lt;a href=&quot;http://vuejs.org/&quot;&gt;Vue.js&lt;/a&gt;,
&lt;a href=&quot;https://github.com/mikedeboer/node-github&quot;&gt;node-github&lt;/a&gt;
(and now Electron!) compile their own definition file and bundle it with their
published npm package. For projects that don’t bundle their own definition file,
there is 
&lt;a href=&quot;https://github.com/DefinitelyTyped/DefinitelyTyped&quot;&gt;DefinitelyTyped&lt;/a&gt;,
a third-party ecosystem of community-maintained definition files.&lt;/p&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;p&gt;Starting at version 1.6.10, every release of Electron includes its own
TypeScript definition file. When you install the &lt;code class=&quot;highlighter-rouge&quot;&gt;electron&lt;/code&gt; package from npm,
the &lt;code class=&quot;highlighter-rouge&quot;&gt;electron.d.ts&lt;/code&gt; file is bundled automatically with the
installed package.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://electron.atom.io/docs/tutorial/electron-versioning/&quot;&gt;safest way&lt;/a&gt; to install Electron is using an exact version number:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;npm install electron --save-dev --save-exact
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Or if you’re using &lt;a href=&quot;https://yarnpkg.com/lang/en/docs/migrating-from-npm/#toc-cli-commands-comparison&quot;&gt;yarn&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;yarn add electron --dev --exact
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If you were already using third-party definitions like &lt;code class=&quot;highlighter-rouge&quot;&gt;@types/electron&lt;/code&gt;
and &lt;code class=&quot;highlighter-rouge&quot;&gt;@types/node&lt;/code&gt;, you should remove them from your Electron project to prevent
any collisions.&lt;/p&gt;

&lt;p&gt;The definition file is derived from our
&lt;a href=&quot;https://electron.atom.io/blog/2016/09/27/api-docs-json-schema&quot;&gt;structured API documentation&lt;/a&gt;,
so it will always be consistent with &lt;a href=&quot;https://electron.atom.io/docs/api/&quot;&gt;Electron’s API documentation&lt;/a&gt;.
Just install &lt;code class=&quot;highlighter-rouge&quot;&gt;electron&lt;/code&gt; and you’ll always get TypeScript definitions that are
up to date with the version of Electron you’re using.&lt;/p&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;

&lt;p&gt;For a summary of how to install and use Electron’s new TypeScript annotations,
watch this short demo screencast:&lt;/p&gt;

&lt;iframe width=&quot;100%&quot; height=&quot;420&quot; src=&quot;https://www.youtube.com/embed/PJRag0rYQt8&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;If you’re using &lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;Visual Studio Code&lt;/a&gt;, you’ve
already got TypeScript support built in. There are also community-maintained
plugins for
&lt;a href=&quot;https://atom.io/packages/atom-typescript&quot;&gt;Atom&lt;/a&gt;,
&lt;a href=&quot;https://github.com/Microsoft/TypeScript-Sublime-Plugin&quot;&gt;Sublime&lt;/a&gt;,
&lt;a href=&quot;https://github.com/Microsoft/TypeScript/wiki/TypeScript-Editor-Support#vim&quot;&gt;vim&lt;/a&gt;,
and
&lt;a href=&quot;https://www.typescriptlang.org/index.html#download-links&quot;&gt;other editors&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once your editor is configured for TypeScript, you’ll start to see more
context-aware behavior like autocomplete suggestions, inline method reference,
argument checking, and more.&lt;/p&gt;

&lt;figure&gt;
  &lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/26128017/f6318c20-3a3f-11e7-9c2c-401a32d1f9fb.png&quot; alt=&quot;Method autocompletion&quot; /&gt;
  &lt;figcaption&gt;Method autcompletion&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
  &lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/26128018/f6352600-3a3f-11e7-8d92-f0fb88ecc53e.png&quot; alt=&quot;Method reference&quot; /&gt;
  &lt;figcaption&gt;Inline method reference&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;figure&gt;
  &lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/26128021/f6b1ca0c-3a3f-11e7-8161-ce913268a9f0.png&quot; alt=&quot;Argument checking&quot; /&gt;
  &lt;figcaption&gt;Argument checking&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;h2 id=&quot;getting-started-with-typescript&quot;&gt;Getting started with TypeScript&lt;/h2&gt;

&lt;p&gt;If you’re new to TypeScript and want to learn more, this
&lt;a href=&quot;http://video.ch9.ms/ch9/4ae3/062c336d-9cf0-498f-ae9a-582b87954ae3/B881_mid.mp4&quot;&gt;introductory video from Microsoft&lt;/a&gt;
provides a nice overview of why the language was created, how it works,
how to use it, and where it’s headed.&lt;/p&gt;

&lt;p&gt;There’s also a
&lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/basic-types.html&quot;&gt;handbook&lt;/a&gt;
and a
&lt;a href=&quot;https://www.typescriptlang.org/play/index.html&quot;&gt;playground&lt;/a&gt;
on the official TypeScript website.&lt;/p&gt;

&lt;p&gt;Because TypeScript is a superset of JavaScript, your existing JavaScript code is
already valid TypeScript. This means you can gradually transition an existing
JavaScript project to TypeScript, sprinkling in new language features as needed.&lt;/p&gt;

&lt;h2 id=&quot;thanks&quot;&gt;Thanks&lt;/h2&gt;

&lt;p&gt;This project would not have been possible without the help of Electron’s
community of open-source maintainers. Thanks to
&lt;a href=&quot;https://github.com/MarshallOfSound&quot;&gt;Samuel Attard&lt;/a&gt;,
&lt;a href=&quot;https://github.com/felixrieseberg&quot;&gt;Felix Rieseberg&lt;/a&gt;, 
&lt;a href=&quot;https://github.com/poiru&quot;&gt;Birunthan Mohanathas&lt;/a&gt;, 
&lt;a href=&quot;https://github.com/miniak&quot;&gt;Milan Burda&lt;/a&gt;, 
&lt;a href=&quot;https://github.com/shiftkey&quot;&gt;Brendan Forster&lt;/a&gt;,
and many others for their bug fixes, documentation improvements,
and technical guidance.&lt;/p&gt;

&lt;h2 id=&quot;support&quot;&gt;Support&lt;/h2&gt;

&lt;p&gt;If you encounter any issues using Electron’s new TypeScript definition files,
please file an issue on the
&lt;a href=&quot;https://github.com/electron/electron-typescript-definitions/issues&quot;&gt;electron-typescript-definitions&lt;/a&gt; repository.&lt;/p&gt;

&lt;p&gt;Happy TypeScripting!&lt;/p&gt;</content><author><name>zeke</name></author><summary type="html">The electron npm package now includes a TypeScript definition file that provides detailed annotations of the entire Electron API. These annotation can improve your Electron development experience even if you’re writing vanilla JavaScript. Just npm install electron to get up-to-date Electron typings in your project.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://electron.atom.io/images/opengraph.png" /></entry><entry><title type="html">Project of the Week: Jasper</title><link href="https://electron.atom.io/blog/2017/03/21/jasper" rel="alternate" type="text/html" title="Project of the Week: Jasper" /><published>2017-03-21T00:00:00+00:00</published><updated>2017-03-21T00:00:00+00:00</updated><id>https://electron.atom.io/blog/2017/03/21/jasper</id><content type="html" xml:base="https://electron.atom.io/blog/2017/03/21/jasper">&lt;p&gt;This week we interviewed the creator of &lt;a href=&quot;https://jasperapp.io&quot;&gt;Jasper&lt;/a&gt;, an Electron-based tool for
managing GitHub notifications.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;hello-who-are-you&quot;&gt;Hello! Who are you?&lt;/h2&gt;

&lt;p&gt;I’m &lt;a href=&quot;https://github.com/h13i32maru&quot;&gt;Ryo Maruyama&lt;/a&gt;, a software developer in Japan. I am developing &lt;a href=&quot;https://jasperapp.io&quot;&gt;Jasper&lt;/a&gt; and &lt;a href=&quot;https://esdoc.org&quot;&gt;ESDoc&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-is-jasper&quot;&gt;What is Jasper?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://jasperapp.io&quot;&gt;Jasper&lt;/a&gt; is a flexible and powerful issue reader for GitHub. It supports issues and pull requests on github.com and GitHub Enterprise.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://jasperapp.io/&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/24108647/75ef131e-0d4b-11e7-945b-27dd50cb03ab.png&quot; alt=&quot;Jasper App Screenshot&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;why-did-you-make-it&quot;&gt;Why did you make it?&lt;/h2&gt;

&lt;p&gt;When people use GitHub in their job or OSS activities, they tend to receive many notifications on a daily basis. As a way to subscribe to the notifications, GitHub provides email and &lt;a href=&quot;https://github.com/notifications&quot;&gt;web notifications&lt;/a&gt;. I used these for a couple of years, but I faced the following problems:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;It’s easy to overlook issues where I was mentioned, I commented, or I am watching.&lt;/li&gt;
  &lt;li&gt;I put some issues in a corner of my head to check later, but I sometimes forget about them.&lt;/li&gt;
  &lt;li&gt;To not forget issues, I keep many tabs open in my browser.&lt;/li&gt;
  &lt;li&gt;It’s hard to check all issues that are related to me.&lt;/li&gt;
  &lt;li&gt;It’s hard to grasp all of my team’s activity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was spending a lot of time and energy trying to prevent those problems, so I decided to make an issue reader for GitHub to solve these problems efficiently, and started developing Jasper.&lt;/p&gt;

&lt;h2 id=&quot;whos-using-jasper&quot;&gt;Who’s using Jasper?&lt;/h2&gt;

&lt;p&gt;Jasper is used by developers, designers, and managers in several companies that are using GitHub.
Of course, some OSS developers also are using it.
And it is also used by some people at GitHub!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/mistydemeo/status/778841101109080064&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/24108650/75f87706-0d4b-11e7-8fcb-9fbedf2f66ea.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://twitter.com/jna_sh/status/798283937344651264&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/24108649/75f4b9e0-0d4b-11e7-9701-24a0ef251ad2.png&quot; width=&quot;500&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;how-does-jasper-work&quot;&gt;How does Jasper work?&lt;/h2&gt;

&lt;p&gt;Once Jasper is configured, the following screen appears. From left to right, you can see “streams list”, “issues list” and “issue body”.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://jasperapp.io/&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/24108645/75ae3786-0d4b-11e7-9a1a-3c270ae33cba.png&quot; alt=&quot;Jasper Start Screen&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This “stream” is the core feature of Jasper. For example, if you want to see “issues that are assigned to @zeke in the electron/electron repository”, you create the following stream:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;repo:electron/electron assignee:zeke is:issue
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://jasperapp.io/&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/24108648/75f403ec-0d4b-11e7-9ed4-4599ecd26b78.png&quot; alt=&quot;Jasper Start Screen 2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating the stream and waiting for a few seconds, you can see the issues that meet the conditions.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://jasperapp.io/&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/24108646/75b7fea6-0d4b-11e7-9d05-7dd4e595403c.png&quot; alt=&quot;Jasper Start Screen 3&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;what-can-we-do-with-streams&quot;&gt;What can we do with streams?&lt;/h2&gt;

&lt;p&gt;I will introduce what kind of conditions can be used for stream.&lt;/p&gt;

&lt;h3 id=&quot;users-and-teams&quot;&gt;Users and Teams&lt;/h3&gt;

&lt;table class=&quot;table table-ruled table-full-width&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Stream&lt;/th&gt;
      &lt;th&gt;Issues&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;mentions:cat mentions:dog&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues that mention user &lt;code class=&quot;highlighter-rouge&quot;&gt;cat&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;dog&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;author:cat author:dog&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues created by user &lt;code class=&quot;highlighter-rouge&quot;&gt;cat&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;dog&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;assignee:cat assignee:dog&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues assigned to &lt;code class=&quot;highlighter-rouge&quot;&gt;cat&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;dog&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;commenter:cat commenter:dog&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues that &lt;code class=&quot;highlighter-rouge&quot;&gt;cat&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;dog&lt;/code&gt; commented on&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;involves:cat involves:dog&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues that “involve” &lt;code class=&quot;highlighter-rouge&quot;&gt;cat&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;bob&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;team:animal/white-cat team:animal/black-dog&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues that &lt;code class=&quot;highlighter-rouge&quot;&gt;animal/white-cat&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;animal/black-dog&lt;/code&gt; are mentioned in&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;involves&lt;/code&gt; means &lt;code class=&quot;highlighter-rouge&quot;&gt;mention&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;author&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;assignee&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;commenter&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;repositories-and-organizations&quot;&gt;Repositories and Organizations&lt;/h3&gt;

&lt;table class=&quot;table table-ruled table-full-width&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Stream&lt;/th&gt;
      &lt;th&gt;Issues&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;repo:cat/jump repo:dog/run&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues in &lt;code class=&quot;highlighter-rouge&quot;&gt;cat/jump&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;dog/run&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;org:electron user:cat user:dog&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues in &lt;code class=&quot;highlighter-rouge&quot;&gt;electron&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;cat&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;dog&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;org&lt;/code&gt; is same as &lt;code class=&quot;highlighter-rouge&quot;&gt;user&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;attributes&quot;&gt;Attributes&lt;/h3&gt;

&lt;table class=&quot;table table-ruled table-full-width&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Stream&lt;/th&gt;
      &lt;th&gt;Issues&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;repo:cat/jump milestone:v1.0.0 milestone:v1.0.1&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues that are attached to &lt;code class=&quot;highlighter-rouge&quot;&gt;v1.0.0&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;v1.0.1&lt;/code&gt; in &lt;code class=&quot;highlighter-rouge&quot;&gt;cat/jump&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;repo:cat/jump label:bug label:blocker&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues that are attached &lt;code class=&quot;highlighter-rouge&quot;&gt;bug&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;blocker&lt;/code&gt; in &lt;code class=&quot;highlighter-rouge&quot;&gt;cat/jump&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;electron OR atomshell&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues that include &lt;code class=&quot;highlighter-rouge&quot;&gt;electron&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;atomshell&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;review-status&quot;&gt;Review Status&lt;/h3&gt;

&lt;table class=&quot;table table-ruled table-full-width&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Stream&lt;/th&gt;
      &lt;th&gt;Issues&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;is:pr review:required&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues that are required review in &lt;code class=&quot;highlighter-rouge&quot;&gt;cat/jump&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;is:pr review-requested:cat&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues that are requested review by &lt;code class=&quot;highlighter-rouge&quot;&gt;cat&lt;/code&gt;. &lt;br /&gt; But these are not reviewed yet.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;is:pr reviewed-by:cat&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Issues that are reviewed by &lt;code class=&quot;highlighter-rouge&quot;&gt;cat&lt;/code&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;As you may have noticed by looking at these, streams can use GitHub’s search queries.
For details on how to use streams and search queries, see the following URLs.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://jasperapp.io/doc.html#stream&quot;&gt;jasperapp.io/doc.html#stream&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.github.com/articles/searching-issues/&quot;&gt;help.github.com/articles/searching-issues&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://help.github.com/articles/search-syntax/&quot;&gt;help.github.com/articles/search-syntax&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Jasper also has features for unread issue management, unread comment management, marking stars, notification updating, filtering issues, keyboard shortcuts, etc.&lt;/p&gt;

&lt;h2 id=&quot;is-jasper-a-paid-product-how-much-does-it-cost&quot;&gt;Is Jasper a paid product? How much does it cost?&lt;/h2&gt;

&lt;p&gt;Jasper is $12. However you can use the &lt;a href=&quot;https://jasperapp.io/&quot;&gt;free trial edition&lt;/a&gt; for 30 days.&lt;/p&gt;

&lt;h2 id=&quot;why-did-you-choose-to-build-jasper-on-electron&quot;&gt;Why did you choose to build Jasper on Electron?&lt;/h2&gt;

&lt;p&gt;I like the following aspects of Electron:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Apps can be developed with JavaScript/CSS/HTML.&lt;/li&gt;
  &lt;li&gt;Apps can be built for Windows, Mac, and Linux platforms.&lt;/li&gt;
  &lt;li&gt;Electron is actively developed and has a large community.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These features enable rapid and simple desktop application development. It is awesome! If you have any product idea, you should consider using Electron by all means.&lt;/p&gt;

&lt;h2 id=&quot;what-are-some-challenges-youve-faced-while-developing-jasper&quot;&gt;What are some challenges you’ve faced while developing Jasper?&lt;/h2&gt;

&lt;p&gt;I had a hard time figuring out the “stream” concept. At first I considered using GitHub’s &lt;a href=&quot;https://developer.github.com/v3/activity/notifications/&quot;&gt;Notifications API&lt;/a&gt;. However I noticed that it does not support certain use cases. After that I considered using the &lt;a href=&quot;https://developer.github.com/v3/issues/&quot;&gt;Issues API&lt;/a&gt; and &lt;a href=&quot;https://developer.github.com/v3/pulls/&quot;&gt;Pull Requests API&lt;/a&gt;, in addition to the Notification API. But it never became what I wanted. Then while thinking about various methods, I realized that polling GitHub’s &lt;a href=&quot;https://developer.github.com/v3/search/&quot;&gt;Search API&lt;/a&gt; would offer the most flexibility. It took about a month of experimentation to get to this point, then I implemented a prototype of Jasper with the stream concept in two days.&lt;/p&gt;

&lt;p&gt;Note: The polling is limited to once every 10 seconds at most. This is acceptable enough for the restriction of GitHub API.&lt;/p&gt;

&lt;h2 id=&quot;whats-coming-next&quot;&gt;What’s coming next?&lt;/h2&gt;

&lt;p&gt;I have a plan to develop the following features:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;A filtered stream&lt;/strong&gt;: A stream has some filtered stream that filter issues in the stream. It is like as view of SQL.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Multiple accounts&lt;/strong&gt;: you will be able to use both github.com and GHE&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Improve performance&lt;/strong&gt;: For now the loading a issue in WebView is low speed than normal browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Follow &lt;a href=&quot;https://twitter.com/jasperappio&quot;&gt;@jasperappio&lt;/a&gt; on Twitter for updates.&lt;/p&gt;</content><author><name>zeke</name></author><summary type="html">This week we interviewed the creator of Jasper, an Electron-based tool for managing GitHub notifications.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://electron.atom.io/images/opengraph.png" /></entry><entry><title type="html">Project of the Week: WebTorrent</title><link href="https://electron.atom.io/blog/2017/03/14/webtorrent" rel="alternate" type="text/html" title="Project of the Week: WebTorrent" /><published>2017-03-14T00:00:00+00:00</published><updated>2017-03-14T00:00:00+00:00</updated><id>https://electron.atom.io/blog/2017/03/14/webtorrent</id><content type="html" xml:base="https://electron.atom.io/blog/2017/03/14/webtorrent">&lt;p&gt;This week we caught up with &lt;a href=&quot;https://github.com/feross&quot;&gt;@feross&lt;/a&gt; and &lt;a href=&quot;https://github.com/dcposch&quot;&gt;@dcposch&lt;/a&gt; to talk about WebTorrent, the web-powered torrent client that connects users together to form a distributed, decentralized browser-to-browser network.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;what-is-webtorrent&quot;&gt;What is WebTorrent?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://webtorrent.io&quot;&gt;WebTorrent&lt;/a&gt; is the first torrent client that works in the browser. It’s written completely in JavaScript and it can use WebRTC for peer-to-peer transport. No browser plugin, extension, or installation is required.&lt;/p&gt;

&lt;p&gt;Using open web standards, WebTorrent connects website users together to form a distributed, decentralized browser-to-browser network for efficient file transfer.&lt;/p&gt;

&lt;p&gt;You can see a demo of WebTorrent in action here: &lt;a href=&quot;https://webtorrent.io/&quot;&gt;webtorrent.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://webtorrent.io/&quot;&gt;
  &lt;img alt=&quot;webtorrent homepage&quot; src=&quot;https://cloud.githubusercontent.com/assets/2289/23912149/1543d2ce-089c-11e7-8519-613740c82b47.jpg&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;why-is-this-cool&quot;&gt;Why is this cool?&lt;/h2&gt;

&lt;p&gt;Imagine a video site like YouTube, but where visitors help to host the site’s content. The more people that use a WebTorrent-powered website, the faster and more resilient it becomes.&lt;/p&gt;

&lt;p&gt;Browser-to-browser communication cuts out the middle-man and lets people communicate on their own terms. No more client/server – just a network of peers, all equal. WebTorrent is the first step in the journey to re-decentralize the Web.&lt;/p&gt;

&lt;h2 id=&quot;where-does-electron-come-into-the-picture&quot;&gt;Where does Electron come into the picture?&lt;/h2&gt;

&lt;p&gt;About one year ago, we decided to build &lt;a href=&quot;https://webtorrent.io/desktop/&quot;&gt;WebTorrent Desktop&lt;/a&gt;, a version of WebTorrent that runs as a desktop app.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://webtorrent.io/desktop/&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/23912152/154aef0a-089c-11e7-8544-869b0cd642b1.jpg&quot; alt=&quot;WebTorrent Desktop player window&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We created WebTorrent Desktop for three reasons:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;We wanted a clean, lightweight, ad-free, open source torrent app&lt;/li&gt;
  &lt;li&gt;We wanted a torrent app with good streaming support&lt;/li&gt;
  &lt;li&gt;We need a “hybrid client” that connects the BitTorrent and WebTorrent networks&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;if-we-can-already-download-torrents-in-my-web-browser-why-a-desktop-app&quot;&gt;If we can already download torrents in my web browser, why a desktop app?&lt;/h2&gt;

&lt;p&gt;First, a bit of background on the design of WebTorrent.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://webtorrent.io/desktop/&quot;&gt;
  &lt;img alt=&quot;webtorrent desktop logo&quot; src=&quot;https://cloud.githubusercontent.com/assets/2289/23912151/154657e2-089c-11e7-9889-6914ce71ebc9.png&quot; width=&quot;200&quot; align=&quot;right&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the early days, BitTorrent used TCP as its transport protocol. Later, uTP came along promising better performance and additional advantages over TCP. Every mainstream torrent client eventually adopted uTP, and today you can use BitTorrent over either protocol. The WebRTC protocol is the next logical step. It brings the promise of interoperability with web browsers – one giant P2P network made up of all desktop BitTorrent clients and millions of web browsers.&lt;/p&gt;

&lt;p&gt;“Web peers” (torrent peers that run in a web browser) make the BitTorrent network stronger by adding millions of new peers, and spreading BitTorrent to dozens of new use cases. WebTorrent follows the BitTorrent spec as closely as possible, to make it easy for existing BitTorrent clients to add support for WebTorrent.&lt;/p&gt;

&lt;p&gt;Some torrent apps like &lt;a href=&quot;https://www.vuze.com/&quot;&gt;Vuze&lt;/a&gt; already support web peers, but we didn’t want to wait around for the rest to add support. &lt;strong&gt;So basically, WebTorrent Desktop was our way to speed up the adoption of the WebTorrent protocol.&lt;/strong&gt; By making an awesome torrent app that people really want to use, we increase the number of peers in the network that can share torrents with web peers (i.e. users on websites).&lt;/p&gt;

&lt;h2 id=&quot;what-are-some-interesting-use-cases-for-torrents-beyond-what-people-already-know-they-can-do&quot;&gt;What are some interesting use cases for torrents beyond what people already know they can do?&lt;/h2&gt;

&lt;p&gt;One of the most exciting uses for WebTorrent is peer-assisted delivery. Non-profit projects like &lt;a href=&quot;https://www.wikipedia.org/&quot;&gt;Wikipedia&lt;/a&gt; and the &lt;a href=&quot;https://archive.org/&quot;&gt;Internet Archive&lt;/a&gt; could reduce bandwidth and hosting costs by letting visitors chip in. Popular content can be served browser-to-browser, quickly and cheaply. Rarely-accessed content can be served reliably over HTTP from the origin server.&lt;/p&gt;

&lt;p&gt;The Internet Archive actually already updated their torrent files so they work great with WebTorrent. So if you want to embed Internet Archive content on your site, you can do it in a way that reduces hosting costs for the Archive, allowing them to devote more money to actually archiving the web!&lt;/p&gt;

&lt;p&gt;There are also exciting business use cases, from CDNs to app delivery over P2P.&lt;/p&gt;

&lt;h2 id=&quot;what-are-some-of-your-favorite-projects-that-use-webtorrent&quot;&gt;What are some of your favorite projects that use WebTorrent?&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/23912148/154392c8-089c-11e7-88a8-3d4bcb1d2a94.jpg&quot; alt=&quot;gaia app screenshot&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The coolest thing built with WebTorrent, hands down, is probably &lt;a href=&quot;http://charliehoey.com/threejs-demos/gaia_dr1.html&quot;&gt;Gaia 3D Star Map&lt;/a&gt;. It’s a slick 3D interactive simulation of the Milky Way. The data loads from a torrent, right in your browser. It’s awe-inspiring to fly through our star system and realize just how little we humans are compared to the vastness of our universe.&lt;/p&gt;

&lt;p&gt;You can read about how this was made in &lt;a href=&quot;https://medium.com/@flimshaw/torrenting-the-galaxy-extracting-2-million-3d-stars-from-180gb-of-csvs-457ff70c0f93&quot;&gt;Torrenting The Galaxy&lt;/a&gt;, a blog post where the author, Charlie Hoey, explains how he built the star map with WebGL and WebTorrent.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://brave.com/&quot;&gt;
  &lt;img alt=&quot;brave logo&quot; src=&quot;https://cloud.githubusercontent.com/assets/2289/23912147/1542ad4a-089c-11e7-8106-15c8e34298a9.png&quot; width=&quot;150&quot; align=&quot;left&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We’re also huge fans of &lt;a href=&quot;https://brave.com/&quot;&gt;Brave&lt;/a&gt;. Brave is a browser that automatically blocks ads and trackers to make the web faster and safer. Brave recently added torrent support, so you can &lt;a href=&quot;https://torrentfreak.com/brave-a-privacy-focused-browser-with-built-in-torrent-streaming-170219/&quot;&gt;view traditional torrents without using a separate app&lt;/a&gt;. That feature is powered by WebTorrent.&lt;/p&gt;

&lt;p&gt;So, just like how most browsers can render PDF files, Brave can render magnet links and torrent files. They’re just another type of content that the browser natively supports.&lt;/p&gt;

&lt;p&gt;One of the co-founders of Brave is actually Brendan Eich, the creator of JavaScript, the language we wrote WebTorrent in, so we think it’s pretty cool that Brave chose to integrate WebTorrent.&lt;/p&gt;

&lt;h2 id=&quot;why-did-you-choose-to-build-webtorrent-desktop-on-electron&quot;&gt;Why did you choose to build WebTorrent Desktop on Electron?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://webtorrent.io/desktop/&quot;&gt;
  &lt;img alt=&quot;WebTorrent Desktop main window&quot; src=&quot;https://cloud.githubusercontent.com/assets/2289/23912150/15444542-089c-11e7-91ab-7fe3f1e5ee43.jpg&quot; align=&quot;right&quot; width=&quot;450&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is a meme that Electron apps are “bloated” because they include the entire Chrome content module in every app. In some cases, this is partially true (an Electron app installer is usually ~40MB, where an OS-specific app installer is usually ~20MB).&lt;/p&gt;

&lt;p&gt;However, in the case of WebTorrent Desktop, we use nearly every Electron feature, and many dozens of Chrome features in the course of normal operation. If we wanted to implement these features from scratch for each platform, it would have taken months or years longer to build our app, or we would have only been able to release for a single platform.&lt;/p&gt;

&lt;p&gt;Just to get an idea, we use Electron’s &lt;a href=&quot;https://electron.atom.io/docs/api/app/#appdockbouncetype-macos&quot;&gt;dock integration&lt;/a&gt; (to show download progress), &lt;a href=&quot;https://electron.atom.io/docs/api/menu/&quot;&gt;menu bar integration&lt;/a&gt; (to run in the background), &lt;a href=&quot;https://electron.atom.io/docs/api/app/#appsetasdefaultprotocolclientprotocol-path-args-macos-windows&quot;&gt;protocol handler registration&lt;/a&gt; (to open magnet links), &lt;a href=&quot;https://electron.atom.io/docs/api/power-save-blocker/&quot;&gt;power save blocker&lt;/a&gt; (to prevent sleep during video playback), and &lt;a href=&quot;https://electron.atom.io/docs/api/auto-updater/&quot;&gt;automatic updater&lt;/a&gt;. As for Chrome features, we use plenty: the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;video&amp;gt;&lt;/code&gt; tag (to play many different video formats), the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;track&amp;gt;&lt;/code&gt; tag (for closed captions support), drag-and-drop support, and WebRTC (which is non-trivial to use in a native app).&lt;/p&gt;

&lt;p&gt;Not to mention: our torrent engine is written in JavaScript and assumes the existence of lots of Node APIs, but especially &lt;code class=&quot;highlighter-rouge&quot;&gt;require('net')&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;require('dgram')&lt;/code&gt; for TCP and UDP socket support.&lt;/p&gt;

&lt;p&gt;Basically, Electron is just what we needed and had the exact set of features we needed to ship a solid, polished app in record time.&lt;/p&gt;

&lt;h2 id=&quot;what-are-your-favorite-things-about-electron&quot;&gt;What are your favorite things about Electron?&lt;/h2&gt;

&lt;p&gt;The WebTorrent library has been in development as an open source side project for two years. &lt;strong&gt;We made WebTorrent Desktop in four weeks.&lt;/strong&gt; Electron is the primary reason that we were able to build and ship our app so quickly.&lt;/p&gt;

&lt;p&gt;Just as Node.js made server programming accessible to a generation of jQuery-using front-end programmers, Electron makes native app development accessible to anyone familiar with Web or Node.js development. Electron is extremely empowering.&lt;/p&gt;

&lt;h2 id=&quot;do-the-website-and-the-desktop-client-share-code&quot;&gt;Do the website and the Desktop client share code?&lt;/h2&gt;

&lt;p&gt;Yes, the &lt;a href=&quot;https://npmjs.com/package/webtorrent&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;webtorrent&lt;/code&gt; npm package&lt;/a&gt; works in Node.js, in the browser, and in Electron. The exact same code can run in all environments – this is the beauty of JavaScript. It’s today’s universal runtime. Java Applets promised “Write Once, Run Anywhere” apps, but that vision never really materialized for a number of reasons. Electron, more than any other platform, actually gets pretty darn close to that ideal.&lt;/p&gt;

&lt;h2 id=&quot;what-are-some-challenges-youve-faced-while-building-webtorrent&quot;&gt;What are some challenges you’ve faced while building WebTorrent?&lt;/h2&gt;

&lt;p&gt;In early versions of the app, we struggled to make the UI performant. We put the torrent engine in the same renderer process that draws the main app window which, predictably, led to slowness anytime there was intense CPU activity from the torrent engine (like verifying the torrent pieces received from peers).&lt;/p&gt;

&lt;p&gt;We fixed this by moving the torrent engine to a second, invisible renderer process that we communicate with over &lt;a href=&quot;https://electron.atom.io/docs/api/ipc-main/&quot;&gt;IPC&lt;/a&gt;. This way, if that process briefly uses a lot of CPU, the UI thread will be unaffected. Buttery-smooth scrolling and animations are so satisfying.&lt;/p&gt;

&lt;p&gt;Note: we had to put the torrent engine in a renderer process, instead of a “main” process, because we need access to WebRTC (which is only available in the renderer.)&lt;/p&gt;

&lt;h2 id=&quot;in-what-areas-should-electron-be-improved&quot;&gt;In what areas should Electron be improved?&lt;/h2&gt;

&lt;p&gt;One thing we’d love to see is better documentation about how to build and ship production-ready apps, especially around tricky subjects like code signing and auto-updating. We had to learn about best practices by digging into source code and asking around on Twitter!&lt;/p&gt;

&lt;h2 id=&quot;is-webtorrent-desktop-done-if-not-whats-coming-next&quot;&gt;Is WebTorrent Desktop done? If not, what’s coming next?&lt;/h2&gt;

&lt;p&gt;We think the current version of WebTorrent Desktop is excellent, but there’s always room for improvement. We’re currently working on improving polish, performance, subtitle support, and video codec support.&lt;/p&gt;

&lt;p&gt;If you’re interested in getting involved in the project, check out &lt;a href=&quot;https://github.com/feross/webtorrent-desktop&quot;&gt;our GitHub page&lt;/a&gt;!&lt;/p&gt;

&lt;h2 id=&quot;any-electron-development-tips-that-might-be-useful-to-other-developers&quot;&gt;Any Electron development tips that might be useful to other developers?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://feross.org/&quot;&gt;Feross&lt;/a&gt;, one of the WebTorrent Desktop contributors, recently gave a talk &lt;em&gt;“Real world Electron: Building Cross-platform desktop apps with JavaScript”&lt;/em&gt; at NodeConf Argentina that contains useful tips for releasing a polished Electron app. The talk is especially useful if you’re at the stage where you have a basic working app and you’re trying to take it to the next level of polish and professionalism.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=YLExGgEnbFY&quot;&gt;Watch here&lt;/a&gt;:&lt;/p&gt;

&lt;iframe width=&quot;100%&quot; height=&quot;360&quot; src=&quot;https://www.youtube.com/embed/YLExGgEnbFY?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;a href=&quot;https://speakerdeck.com/feross/real-world-electron&quot;&gt;Slides here&lt;/a&gt;:&lt;/p&gt;

&lt;script async=&quot;&quot; class=&quot;speakerdeck-embed&quot; data-id=&quot;5aae08bb7c5b4dbd89060cff11bb1300&quot; data-ratio=&quot;1.77777777777778&quot; src=&quot;//speakerdeck.com/assets/embed.js&quot;&gt;&lt;/script&gt;

&lt;p&gt;&lt;a href=&quot;https://dcpos.ch/&quot;&gt;DC&lt;/a&gt;, another WebTorrent contributor, wrote &lt;a href=&quot;https://blog.dcpos.ch/how-to-make-your-electron-app-sexy&quot;&gt;a checklist of things you can do&lt;/a&gt; to make your app feel polished and native. It comes with code examples and covers things like macOS dock integration, drag-and-drop, desktop notifications, and making sure your app loads quickly.&lt;/p&gt;</content><author><name>zeke</name></author><summary type="html">This week we caught up with @feross and @dcposch to talk about WebTorrent, the web-powered torrent client that connects users together to form a distributed, decentralized browser-to-browser network.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://electron.atom.io/images/opengraph.png" /></entry><entry><title type="html">Touch Bar Support</title><link href="https://electron.atom.io/blog/2017/03/08/touch-bar-support" rel="alternate" type="text/html" title="Touch Bar Support" /><published>2017-03-08T00:00:00+00:00</published><updated>2017-03-08T00:00:00+00:00</updated><id>https://electron.atom.io/blog/2017/03/08/touch-bar-support</id><content type="html" xml:base="https://electron.atom.io/blog/2017/03/08/touch-bar-support">&lt;p&gt;The Electron &lt;a href=&quot;https://github.com/electron/electron/releases/tag/v1.6.3&quot;&gt;1.6.3&lt;/a&gt; beta release contains initial support for the macOS &lt;a href=&quot;https://developer.apple.com/macos/touch-bar&quot;&gt;Touch Bar&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;The new Touch Bar API allows you to add buttons, labels, popovers, color
pickers, sliders, and spacers. These elements can be dynamically updated and
also emit events when they are interacted with.&lt;/p&gt;

&lt;p&gt;This is the first release of this API so it will be evolving over the next
few Electron releases. Please check out the release notes for further updates
and open &lt;a href=&quot;https://github.com/electron/electron/issues&quot;&gt;issues&lt;/a&gt; for any problems
or missing functionality.&lt;/p&gt;

&lt;p&gt;You can install this version via &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install electron@beta&lt;/code&gt; and learn
more about it in the &lt;a href=&quot;https://github.com/electron/electron/blob/master/docs/api/touch-bar.md&quot;&gt;TouchBar&lt;/a&gt;
and &lt;a href=&quot;https://github.com/electron/electron/blob/master/docs/api/browser-window.md#winsettouchbartouchbar-macos&quot;&gt;BrowserWindow&lt;/a&gt;
Electron docs.&lt;/p&gt;

&lt;p&gt;Big thanks to &lt;a href=&quot;https://github.com/MarshallOfSound&quot;&gt;@MarshallOfSound&lt;/a&gt; for contributing this to Electron. :tada:&lt;/p&gt;

&lt;h2 id=&quot;touch-bar-example&quot;&gt;Touch Bar Example&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/671378/23723516/5ff1774c-03fe-11e7-97b8-c693a0004dc8.gif&quot; alt=&quot;Touch Bar Gif&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Below is an example of creating a simple slot machine game in the touch bar.
It demonstrates how to create a touch bar, style the items, associate it with a
window, handle button click events, and update the labels dynamically.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BrowserWindow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'electron'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;TouchBarButton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBarLabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBarSpacer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBar&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;spinning&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Reel labels&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;reel1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBarLabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;reel2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBarLabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;reel3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBarLabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Spin result label&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBarLabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Spin button&lt;/span&gt;
&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;spin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBarButton&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'🎰 Spin'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;backgroundColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#7851A9'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Ignore clicks if already spinning&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;spinning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;spinning&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timeout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
    &lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;spinLength&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 4 seconds&lt;/span&gt;
    &lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;startTime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;spinReels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;updateReels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;startTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;spinLength&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;finishSpin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Slow down a bit on each spin&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;timeout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;spinReels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;spinReels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getRandomValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'🍒'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'💎'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'7️⃣'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'🍊'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'🔔'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'⭐'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'🍇'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'🍀'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;updateReels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;reel1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getRandomValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;reel2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getRandomValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;reel3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getRandomValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;finishSpin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uniqueValues&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;reel1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;reel2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;reel3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;size&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uniqueValues&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// All 3 values are the same&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'💰 Jackpot!'&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textColor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#FDFF00'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;uniqueValues&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// 2 values are the same&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'😍 Winner!'&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textColor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#FDFF00'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// No values are the same&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'🙁 Spin Again'&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;textColor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;spinning&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kr&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;touchBar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;spin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBarSpacer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'large'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;reel1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBarSpacer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'small'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;reel2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBarSpacer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'small'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;reel3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;TouchBarSpacer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'large'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}),&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;once&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'ready'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;BrowserWindow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;titleBarStyle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'hidden-inset'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;backgroundColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#000'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;loadURL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'about:blank'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;window&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setTouchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;touchBar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</content><author><name>kevinsawicki</name></author><summary type="html">The Electron 1.6.3 beta release contains initial support for the macOS Touch Bar.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://electron.atom.io/images/opengraph.png" /></entry><entry><title type="html">Project of the Week: Voltra</title><link href="https://electron.atom.io/blog/2017/03/07/voltra" rel="alternate" type="text/html" title="Project of the Week: Voltra" /><published>2017-03-07T00:00:00+00:00</published><updated>2017-03-07T00:00:00+00:00</updated><id>https://electron.atom.io/blog/2017/03/07/voltra</id><content type="html" xml:base="https://electron.atom.io/blog/2017/03/07/voltra">&lt;p&gt;This week we met with &lt;a href=&quot;https://twitter.com/aprileelcich&quot;&gt;Aprile Elcich&lt;/a&gt; and
&lt;a href=&quot;https://twitter.com/0x00A&quot;&gt;Paolo Fragomeni&lt;/a&gt; to talk about Voltra, an
Electron-powered music player.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;what-is-voltra&quot;&gt;What is Voltra?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://voltra.co/&quot;&gt;Voltra&lt;/a&gt; is a music player for people who want to own their music. It’s also a store where you can discover and buy new music based on what you already own. It’s ad-free, cross-platform for desktop and mobile. It also doesn’t spy on you.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://voltra.co/&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/23670061/4db0323c-031b-11e7-81fd-128e714e911c.jpg&quot; alt=&quot;voltra-artistview&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;who-is-voltra-for&quot;&gt;Who is Voltra for?&lt;/h2&gt;

&lt;p&gt;Anyone who listens to music.&lt;/p&gt;

&lt;h2 id=&quot;what-motivated-you-to-create-voltra&quot;&gt;What motivated you to create Voltra?&lt;/h2&gt;

&lt;p&gt;Radio has has always had a big share of listeners. It’s moving off the airwaves and onto the Internet. Now you can rent music on demand — it’s a radio revival! A lot of new products and services have emerged because of this, but streaming radio still leaves someone else in control of your music and how you experience it.&lt;/p&gt;

&lt;p&gt;We wanted a product that was entirely focused on music you own. Something that made it easy to discover and buy new music directly from artists or labels.&lt;/p&gt;

&lt;h2 id=&quot;is-there-a-free-version&quot;&gt;Is there a free version?&lt;/h2&gt;

&lt;p&gt;The desktop player is completely free. &lt;a href=&quot;https://voltra.co/artists&quot;&gt;Selling your music is also free!&lt;/a&gt; We are not ad-supported.&lt;/p&gt;

&lt;p&gt;Since the app is free, we may open source it later on. Right now we don’t have the bandwidth to manage that. We also have very specific ideas for features and the direction we want to take things. We have an active beta community and we take our feedback to heart.&lt;/p&gt;

&lt;h2 id=&quot;how-do-you-make-money&quot;&gt;How do you make money?&lt;/h2&gt;

&lt;p&gt;We have premium features!&lt;/p&gt;

&lt;p&gt;Our &lt;a href=&quot;https://voltra.co/premium/&quot;&gt;Voltra Audio Archive&lt;/a&gt; is a cloud-backup service designed specifically for music. We don’t compress or share data blocks. Your music collection is physically backed up for you.&lt;/p&gt;

&lt;p&gt;For artists and labels, our &lt;a href=&quot;https://voltra.co/artists/pro&quot;&gt;Pro Membership&lt;/a&gt; offers tools to help them reach more relevant audiences, such as analytics and professional artist webpages.&lt;/p&gt;

&lt;h2 id=&quot;what-makes-voltra-different&quot;&gt;What makes Voltra different?&lt;/h2&gt;

&lt;p&gt;Design and usability are incredibly important to us. We want to give listeners a distraction-free listening experience! There are a some interesting music players and stores out there. But many of them are more advanced and harder to use than their creators realize. We want to make Voltra accessible to as many people as possible.&lt;/p&gt;

&lt;p&gt;We also don’t take a cut from the artist or the label. That’s a key differentiator for us. It’s really important because it lowers the barrier for artists to get their music to market.&lt;/p&gt;

&lt;h2 id=&quot;what-are-some-design--technical-decisions-you-made&quot;&gt;What are some design &amp;amp; technical decisions you made?&lt;/h2&gt;

&lt;p&gt;While designing Voltra, we considered UI conventions from native apps and the web, we also thought a lot about what we could remove. We have an active private beta group who have given us critical feedback over the last few months.&lt;/p&gt;

&lt;p&gt;We found that album art and photography are really important to people. Many players are just lists of files. One of the cool things about owning physical albums is the album art, and we wanted to put emphasis on this in the Voltra desktop app.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://voltra.co/&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/23670056/4b0c18d4-031b-11e7-89e1-539e927a380d.jpg&quot; alt=&quot;voltra-albumview&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We also made sure not to mess with people’s files. We use file watching so you can put your files wherever you want, and we don’t rename them or move them for you. We have an embedded database to track the state of the watched directories so that we can track what’s new, even when the process isn’t running.&lt;/p&gt;

&lt;h2 id=&quot;what-are-some-challenges-youve-faced-while-building-voltra&quot;&gt;What are some challenges you’ve faced while building Voltra?&lt;/h2&gt;

&lt;p&gt;We spend a lot of time focused on performance. We started with frameworks but moved to vanilla Javascript. In our experience, the generalized abstractions they provide outweigh the performance penalties and ceremony that they introduce.&lt;/p&gt;

&lt;p&gt;We handle very large collections pretty well at this point. Large collections means possibly tens of thousands of images! Having Node.js’ file system module directly available from the render process made it really easy to lazy load and unload lots of images super quickly based on DOM events.&lt;/p&gt;

&lt;p&gt;In general &lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate&quot;&gt;setImmediate&lt;/a&gt;&lt;/em&gt; and &lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback&quot;&gt;requestIdleCallback&lt;/a&gt;&lt;/em&gt; have been super important tools for performing lots of processing while keeping the UI responsive. More specifically, distributing CPU-bound tasks into separate processes really helps to keep the user interface responsive. For example, we moved the actual audio context into a separate process, communicating with it over &lt;a href=&quot;https://electron.atom.io/docs/glossary/#ipc&quot;&gt;IPC&lt;/a&gt; to avoid potential interruptions from a busy UI.&lt;/p&gt;

&lt;h2 id=&quot;why-did-you-choose-to-build-voltra-on-electron&quot;&gt;Why did you choose to build Voltra on Electron?&lt;/h2&gt;

&lt;p&gt;The browser’s sandbox is too restricted for our app. But we are also developing a web player. So it’s a huge win that we can share almost 100% of the code between the two implementations.&lt;/p&gt;

&lt;p&gt;We actually started by building a native app with Swift. The main problem we found was that we were reinventing a lot of things. The web has the world’s largest open source eco-system. So we pretty quickly switched to Electron.&lt;/p&gt;

&lt;p&gt;Also, and most importantly, with Electron you develop once and it should Just Work™ on all the major platforms. It’s not guaranteed, but the cost of coding natively for each platform definitely outweighs any other costs that electron introduces.&lt;/p&gt;

&lt;h2 id=&quot;what-are-your-favorite-things-about-electron&quot;&gt;What are your favorite things about Electron?&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GTD!&lt;/strong&gt;: Having Node.js’ networking stack and Chromium’s presentation layer packaged together is a recipe for getting things done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Competency&lt;/strong&gt;: It’s just the web stack, so literally our whole team is involved in actually building the product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Community&lt;/strong&gt;:  There is a highly organized community that knows how to communicate really well! We feel pretty great about developing with support like that.&lt;/p&gt;

&lt;h2 id=&quot;in-what-areas-could-electron-be-improved&quot;&gt;In what areas could Electron be improved?&lt;/h2&gt;

&lt;p&gt;We would like to see Electron endorse a single packager. The packager is as important to Electron what the package manager is to Node. There are multiple packagers in user-land, each with interesting features but each with bugs. Consensus by the community would help to direct the energy being spent by contributors.&lt;/p&gt;

&lt;h2 id=&quot;whats-coming-next&quot;&gt;What’s coming next?&lt;/h2&gt;

&lt;p&gt;We‘re currently developing a mobile app, and working with artists and labels to add their music to the Voltra shop. Hey! If you’re an artist or label, &lt;a href=&quot;https://admin.voltra.co/signup&quot;&gt;sign up now&lt;/a&gt;! We plan on opening up the shop when we reach our goal of 10 million tracks.&lt;/p&gt;</content><author><name>zeke</name></author><summary type="html">This week we met with Aprile Elcich and Paolo Fragomeni to talk about Voltra, an Electron-powered music player.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://electron.atom.io/images/opengraph.png" /></entry><entry><title type="html">Electron Internals: Building Chromium as a Library</title><link href="https://electron.atom.io/blog/2017/03/03/electron-internals-building-chromium-as-a-library" rel="alternate" type="text/html" title="Electron Internals: Building Chromium as a Library" /><published>2017-03-03T00:00:00+00:00</published><updated>2017-03-03T00:00:00+00:00</updated><id>https://electron.atom.io/blog/2017/03/03/electron-internals-building-chromium-as-a-library</id><content type="html" xml:base="https://electron.atom.io/blog/2017/03/03/electron-internals-building-chromium-as-a-library">&lt;p&gt;Electron is based on Google’s open-source Chromium, a project that is not
necessarily designed to be used by other projects. This post introduces
how Chromium is built as a library for Electron’s use, and how the build
system has evolved over the years.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;using-cef&quot;&gt;Using CEF&lt;/h2&gt;

&lt;p&gt;The Chromium Embedded Framework (CEF) is a project that turns Chromium into
a library, and provides stable APIs based on Chromium’s codebase. Very
early versions of Atom editor and NW.js used CEF.&lt;/p&gt;

&lt;p&gt;To maintain a stable API, CEF hides all the details of Chromium
and wraps Chromium’s APIs with its own interface. So when we needed to
access underlying Chromium APIs, like integrating Node.js into web pages, the
advantages of CEF became blockers.&lt;/p&gt;

&lt;p&gt;So in the end both Electron and NW.js switched to using Chromium’s APIs
directly.&lt;/p&gt;

&lt;h2 id=&quot;building-as-part-of-chromium&quot;&gt;Building as part of Chromium&lt;/h2&gt;

&lt;p&gt;Even though Chromium does not officially support outside projects, the codebase
is modular and it is easy to build a minimal browser based on Chromium. The core
module providing the browser interface is called Content Module.&lt;/p&gt;

&lt;p&gt;To develop a project with Content Module, the easiest way is to build the
project as part of Chromium. This can be done by first checking out Chromium’s
source code, and then adding the project to Chromium’s &lt;code class=&quot;highlighter-rouge&quot;&gt;DEPS&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;NW.js and very early versions of Electron are using this way for building.&lt;/p&gt;

&lt;p&gt;The downside is, Chromium is a very large codebase and requires very powerful
machines to build. For normal laptops, that can take more than 5 hours.
So this greatly impacts the number of developers that can contribute to the
project, and it also makes development slower.&lt;/p&gt;

&lt;h2 id=&quot;building-chromium-as-a-single-shared-library&quot;&gt;Building Chromium as a single shared library&lt;/h2&gt;

&lt;p&gt;As a user of Content Module, Electron does not need to modify Chromium’s code
under most cases, so an obvious way to improve the building of Electron is to
build Chromium as a shared library, and then link with it in Electron. In this
way developers no longer need to build all off Chromium when contributing to
Electron.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/electron/libchromiumcontent&quot;&gt;libchromiumcontent&lt;/a&gt; project was created by
&lt;a href=&quot;https://github.com/aroben&quot;&gt;@aroben&lt;/a&gt; for this purpose. It builds the Content
Module of Chromium as a shared library, and then provides Chromium’s headers
and prebuilt binaries for download. The code of the initial version of
libchromiumcontent can be found &lt;a href=&quot;https://github.com/electron/libchromiumcontent/tree/873daa8c57efa053d48aa378ac296b0a1206822c&quot;&gt;in this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/electron/brightray&quot;&gt;brightray&lt;/a&gt; project was also born as part of libchromiumcontent,
which provides a thin layer around Content Module.&lt;/p&gt;

&lt;p&gt;By using libchromiumcontent and brightray together, developers can
quickly build a browser without getting into the details of building Chromium.
And it removes the requirement of a fast network and powerful machine for building
the project.&lt;/p&gt;

&lt;p&gt;Apart from Electron, there were also other Chromium-based projects built in this
way, like the &lt;a href=&quot;https://www.quora.com/Is-Breach-Browser-still-in-development&quot;&gt;Breach browser&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;filtering-exported-symbols&quot;&gt;Filtering exported symbols&lt;/h2&gt;

&lt;p&gt;On Windows there is a limitation of how many symbols one shared library can
export. As the codebase of Chromium grew, the number of symbols exported in
libchromiumcontent soon exceeded the limitation.&lt;/p&gt;

&lt;p&gt;The solution was to filter out unneeded symbols when generating the DLL file.
It worked by &lt;a href=&quot;https://github.com/electron/libchromiumcontent/pull/11/commits/85ca0f60208eef2c5013a29bb4cf3d21feb5030b&quot;&gt;providing a &lt;code class=&quot;highlighter-rouge&quot;&gt;.def&lt;/code&gt; file to the linker&lt;/a&gt;, and then using
a script to &lt;a href=&quot;https://github.com/electron/libchromiumcontent/pull/47/commits/d2fed090e47392254f2981a56fe4208938e538cd&quot;&gt;judge whether symbols under a namespace should be
exported&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By taking this approach, though Chromium kept adding new exported symbols,
libchromiumcontent could still generate shared library files by stripping more
symbols.&lt;/p&gt;

&lt;h2 id=&quot;component-build&quot;&gt;Component build&lt;/h2&gt;

&lt;p&gt;Before talking about the next steps taken in libchromiumcontent, it is important
to introduce the concept of component build in Chromium first.&lt;/p&gt;

&lt;p&gt;As a huge project, the linking step takes very long in Chromium when building.
Normally when a developer makes a small change, it can take 10 minutes to see the
final output. To solve this, Chromium introduced component build, which builds
each module in Chromium as separated shared libraries, so the time spent in the
final linking step becomes unnoticeable.&lt;/p&gt;

&lt;h2 id=&quot;shipping-raw-binaries&quot;&gt;Shipping raw binaries&lt;/h2&gt;

&lt;p&gt;With Chromium continuing to grow, there were so many exported symbols in
Chromium that even the symbols of Content Module and Webkit were more than the
limitation. It was impossible to generate a usable shared library by simply
stripping symbols.&lt;/p&gt;

&lt;p&gt;In the end, we had to &lt;a href=&quot;https://github.com/electron/libchromiumcontent/pull/98&quot;&gt;ship the raw binaries of Chromium&lt;/a&gt; instead of
generating a single shared library.&lt;/p&gt;

&lt;p&gt;As introduced earlier there are two build modes in Chromium. As a result of
shipping raw binaries, we have to ship two different distributions of binaries
in libchromiumcontent. One is called &lt;code class=&quot;highlighter-rouge&quot;&gt;static_library&lt;/code&gt; build, which includes
all static libraries of each module generated by the normal build of Chromium.
The other is &lt;code class=&quot;highlighter-rouge&quot;&gt;shared_library&lt;/code&gt;, which includes all shared libraries of each
module generated by the component build.&lt;/p&gt;

&lt;p&gt;In Electron, the Debug version is linked with the &lt;code class=&quot;highlighter-rouge&quot;&gt;shared_library&lt;/code&gt; version of
libchromiumcontent, because it is small to download and takes little time
when linking the final executable. And the Release version of Electron is
linked with the &lt;code class=&quot;highlighter-rouge&quot;&gt;static_library&lt;/code&gt; version of libchromiumcontent, so the compiler
can generate full symbols which are important for debugging, and the linker
can do much better optimization since it knows which object files are needed
and which are not.&lt;/p&gt;

&lt;p&gt;So for normal development, developers only need to build the Debug version,
which does not require a good network or powerful machine. Though the Release
version then requires much better hardware to build, it can generate better
optimized binaries.&lt;/p&gt;

&lt;h2 id=&quot;the-gn-update&quot;&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;gn&lt;/code&gt; update&lt;/h2&gt;

&lt;p&gt;Being one of the largest projects in the world, most normal systems are not
suitable for building Chromium, and the Chromium team develops their own build
tools.&lt;/p&gt;

&lt;p&gt;Earlier versions of Chromium were using &lt;code class=&quot;highlighter-rouge&quot;&gt;gyp&lt;/code&gt; as a build system, but it suffers
from being slow, and its configuration file becomes hard to understand for complex
projects. After years of development, Chromium switched to &lt;code class=&quot;highlighter-rouge&quot;&gt;gn&lt;/code&gt; as a
build system, which is much faster and has a clear architecture.&lt;/p&gt;

&lt;p&gt;One of the improvements of &lt;code class=&quot;highlighter-rouge&quot;&gt;gn&lt;/code&gt; is to introduce &lt;code class=&quot;highlighter-rouge&quot;&gt;source_set&lt;/code&gt;, which represents
a group of object files. In &lt;code class=&quot;highlighter-rouge&quot;&gt;gyp&lt;/code&gt;, each module was represented by either
&lt;code class=&quot;highlighter-rouge&quot;&gt;static_library&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;shared_library&lt;/code&gt;, and for the normal build of Chromium,
each module generated a static library and they were linked together in the
final executable. By using &lt;code class=&quot;highlighter-rouge&quot;&gt;gn&lt;/code&gt;, each module now only generates a bunch of
object files, and the final executable just links all the object files together,
so the intermediate static library files are no longer generated.&lt;/p&gt;

&lt;p&gt;This improvement however made great trouble to libchromiumcontent, because
the intermediate static library files were actually needed by libchromiumcontent.&lt;/p&gt;

&lt;p&gt;The first try to solve this was to &lt;a href=&quot;https://github.com/electron/libchromiumcontent/pull/239&quot;&gt;patch &lt;code class=&quot;highlighter-rouge&quot;&gt;gn&lt;/code&gt; to generate static library
files&lt;/a&gt;, which solved the problem, but was far from a decent
solution.&lt;/p&gt;

&lt;p&gt;The second try was made by &lt;a href=&quot;https://github.com/alespergl&quot;&gt;@alespergl&lt;/a&gt; to
&lt;a href=&quot;https://github.com/electron/libchromiumcontent/pull/249&quot;&gt;produce custom static libraries from the list of object files&lt;/a&gt;.
It used a trick to first run a dummy build to collect a list of generated
object files, and then actually build the static libraries by feeding
&lt;code class=&quot;highlighter-rouge&quot;&gt;gn&lt;/code&gt; with the list. It only made minimal changes to Chromium’s source
code, and kept Electron’s building architecture still.&lt;/p&gt;

&lt;h2 id=&quot;summary&quot;&gt;Summary&lt;/h2&gt;

&lt;p&gt;As you can see, compared to building Electron as part of Chromium, building
Chromium as a library takes greater efforts and requires continuous
maintenance. However the latter removes the requirement of powerful hardware
to build Electron, thus enabling a much larger range of developers to build and
contribute to Electron. The effort is totally worth it.&lt;/p&gt;</content><author><name>zcbenz</name></author><summary type="html">Electron is based on Google’s open-source Chromium, a project that is not necessarily designed to be used by other projects. This post introduces how Chromium is built as a library for Electron’s use, and how the build system has evolved over the years.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://electron.atom.io/images/opengraph.png" /></entry><entry><title type="html">Project of the Week: WordPress Desktop</title><link href="https://electron.atom.io/blog/2017/02/28/wordpress" rel="alternate" type="text/html" title="Project of the Week: WordPress Desktop" /><published>2017-02-28T00:00:00+00:00</published><updated>2017-02-28T00:00:00+00:00</updated><id>https://electron.atom.io/blog/2017/02/28/wordpress</id><content type="html" xml:base="https://electron.atom.io/blog/2017/02/28/wordpress">&lt;p&gt;This week we caught up with folks at &lt;a href=&quot;https://automattic.com/&quot;&gt;Automattic&lt;/a&gt; to
talk about &lt;a href=&quot;https://apps.wordpress.com/desktop/&quot;&gt;WordPress Desktop&lt;/a&gt;, an
open-source desktop client for managing WordPress content.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;a href=&quot;https://apps.wordpress.com/desktop/&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/23391881/ea54d52e-fd2c-11e6-86ec-98fe466d5c5c.gif&quot; alt=&quot;WordPress Apps&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;everyone-knows-about-wordpress-but-what-is-wordpress-desktop&quot;&gt;Everyone knows about WordPress, but what is WordPress Desktop?&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://apps.wordpress.com/desktop/&quot;&gt;WordPress.com Desktop app&lt;/a&gt; provides a seamless cross-platform experience that allows you to focus on your content and design with no browser tabs to distract you — or to keep your sites sidelined but accessible. In combination with our browser support and mobile app you can build your site anywhere, in whatever way helps you get your work done.&lt;/p&gt;

&lt;h2 id=&quot;why-build-a-desktop-app-for-managing-wordpress-sites-couldnt-it-all-be-web-based&quot;&gt;Why build a Desktop app for managing WordPress sites? Couldn’t it all be web-based?&lt;/h2&gt;

&lt;p&gt;It’s actually using exactly the same technology you get when visiting &lt;a href=&quot;https://wordpress.com&quot;&gt;WordPress.com&lt;/a&gt; in your browser. However, it’s all locally hosted, so it has minimal load times. With the benefit of native features such as being in your dock, notifications, etc., you really can focus on your WordPress sites and blogging.&lt;/p&gt;

&lt;h2 id=&quot;why-did-you-choose-to-build-wordpress-desktop-on-electron&quot;&gt;Why did you choose to build WordPress Desktop on Electron?&lt;/h2&gt;

&lt;p&gt;At the end of 2015 we rebuilt much of WordPress.com in the form of &lt;a href=&quot;https://github.com/automattic/wp-calypso&quot;&gt;Calypso&lt;/a&gt;, an open-source modern JavaScript app using React. We started looking at Electron and with some changes to Calypso were able to get it running locally. It was a compelling  experience and we thought there was a lot of value in developing it further.&lt;/p&gt;

&lt;p&gt;We had several teams working on Calypso. To make a full multi-platform GUI client that matched this using traditional desktop technologies would have taken more work. By using Electron, a small team of 2-4 of us were able to leverage the other team’s efforts and build the Desktop app in a couple of months.&lt;/p&gt;

&lt;h2 id=&quot;what-are-some-challenges-youve-faced-while-building-wordpress-desktop&quot;&gt;What are some challenges you’ve faced while building WordPress Desktop?&lt;/h2&gt;

&lt;p&gt;We got an initial version of the app running very quickly, but tuning it to behave optimally as a desktop app took a lot more time. One big challenge with the app is that you’re actually running a copy of Calypso on your own machine - it’s purely an API driven UI. There was a lot of bridging work involved in this, and changes were fed back to Calypso itself.&lt;/p&gt;

&lt;p&gt;Additionally a lot of effort was spent packaging the app for different platforms - we provide Windows, macOS, and Linux versions - and there are sufficient differences to make this tricky.&lt;/p&gt;

&lt;p&gt;At the time Electron was relatively new and we kept running into issues that were shortly fixed (sometimes the same day!)&lt;/p&gt;

&lt;h2 id=&quot;in-what-areas-should-electron-be-improved&quot;&gt;In what areas should Electron be improved?&lt;/h2&gt;

&lt;p&gt;Electron already provides most of what we need for the Desktop app, and it’s progressed rapidly since we started using it. That said, there are some areas that are taken for granted in a desktop app, such as spell checking and find/replace, that are harder to replicate with Electron as-is.&lt;/p&gt;

&lt;p&gt;We’d also love to see some of the newer Chrome technologies filtering down into Electron too. We’re particularly keen on experimenting with WebVR.&lt;/p&gt;

&lt;h2 id=&quot;what-are-your-favorite-things-about-electron&quot;&gt;What are your favorite things about Electron?&lt;/h2&gt;

&lt;p&gt;The main reason we chose Electron, and it’s biggest strength, is the very active and open community. Automattic has always believed in open source. It is one of our core tenets, and the Electron project and community follows a lot of the core beliefs of being very open and positive.&lt;/p&gt;

&lt;h2 id=&quot;whats-coming-next-in-wordpress-desktop&quot;&gt;What’s coming next in WordPress Desktop?&lt;/h2&gt;

&lt;p&gt;The great thing about our model is that the Desktop app benefits from any new Calypso feature - there are constant improvements. We’re hoping we can add additional features to the app such as offline support, which would really take the app into native territory, and better system notifications.&lt;/p&gt;

&lt;h2 id=&quot;are-there-any-teams-at-automattic-working-on-other-electron-apps&quot;&gt;Are there any teams at Automattic working on other Electron apps?&lt;/h2&gt;

&lt;p&gt;Yes, after our efforts on the Desktop app, the Simplenote team decided to use Electron to build desktop apps for Windows and Linux (a native Mac client already exists). The &lt;a href=&quot;https://github.com/Automattic/simplenote-electron&quot;&gt;Simplenote Electron app&lt;/a&gt; is also open source and available on Github.&lt;/p&gt;

&lt;p&gt;We’ve also got an upcoming Raspberry Pi integration that uses Electron.&lt;/p&gt;

&lt;p&gt;If any of that sounds interesting then we’d &lt;a href=&quot;https://automattic.com/work-with-us/&quot;&gt;love to hear from you&lt;/a&gt;!&lt;/p&gt;

&lt;h2 id=&quot;any-electron-tips-that-might-be-useful-to-other-developers&quot;&gt;Any Electron tips that might be useful to other developers?&lt;/h2&gt;

&lt;p&gt;The process of shipping signed desktop software is relatively new to us, especially for Windows. we wrote up an article for &lt;a href=&quot;https://mkaz.tech/geek/code-signing-a-windows-application.html&quot;&gt;Code Signing a Windows App&lt;/a&gt; which includes the process and a few of the hurdles we went through to do it right.&lt;/p&gt;</content><author><name>zeke</name></author><summary type="html">This week we caught up with folks at Automattic to talk about WordPress Desktop, an open-source desktop client for managing WordPress content.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://electron.atom.io/images/opengraph.png" /></entry><entry><title type="html">Project of the Week: Dat</title><link href="https://electron.atom.io/blog/2017/02/21/dat" rel="alternate" type="text/html" title="Project of the Week: Dat" /><published>2017-02-21T00:00:00+00:00</published><updated>2017-02-21T00:00:00+00:00</updated><id>https://electron.atom.io/blog/2017/02/21/dat</id><content type="html" xml:base="https://electron.atom.io/blog/2017/02/21/dat">&lt;p&gt;This week’s featured project is &lt;a href=&quot;https://datproject.org/&quot;&gt;Dat&lt;/a&gt;, a
&lt;a href=&quot;https://changelog.com/rfc/6&quot;&gt;grant-funded&lt;/a&gt;, open source, decentralized tool
for distributing data sets. Dat is built and maintained by a
&lt;a href=&quot;https://datproject.org/team&quot;&gt;geodistributed team&lt;/a&gt;, many of whom helped
write this post.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/datproject/dat-desktop&quot;&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/23175925/dbaee7ec-f815-11e6-80cc-3041203c7842.png&quot; alt=&quot;A screenshot of the main view of dat-desktop, showing a few rows of shared
dats&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;first-off-what-is-dat&quot;&gt;First off what is Dat?&lt;/h2&gt;

&lt;p&gt;We wanted to bring the best parts of peer to peer and distributed systems to data sharing. We started with scientific data sharing and then began branching out into research institutions, government, public service, and open source teams as well.&lt;/p&gt;

&lt;p&gt;Another way to think about it is a sync and upload app like Dropbox or BitTorrent Sync, except Dat is &lt;a href=&quot;https://github.com/datproject&quot;&gt;open source&lt;/a&gt;. Our goal is to be a a powerful, open source, non-profit data sharing software for big, small, medium, small-batch and big-batch data.&lt;/p&gt;

&lt;p&gt;To use the &lt;code class=&quot;highlighter-rouge&quot;&gt;dat&lt;/code&gt; CLI tool, all you have to type is:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dat share path/to/my/folder
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And dat will create a link that you can use to send that folder to someone else – no central servers or third parties get access to your data. Unlike BitTorrent, it’s also impossible to sniff who is sharing what (&lt;a href=&quot;https://github.com/datproject/docs/blob/master/papers/dat-paper.md&quot;&gt;see the Dat Paper draft for more details&lt;/a&gt;).&lt;/p&gt;

&lt;h2 id=&quot;now-we-know-what-dat-is-how-does-dat-desktop-fit-in&quot;&gt;Now we know what Dat is. How does Dat Desktop fit in?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/datproject/dat-desktop&quot;&gt;Dat Desktop&lt;/a&gt; is a way to make Dat accessible to people who can’t or don’t want to use the command line. You can host multiple dats on your machine and serve the data over your network.&lt;/p&gt;

&lt;h2 id=&quot;can-you-share-some-cool-use-cases&quot;&gt;Can you share some cool use cases?&lt;/h2&gt;

&lt;h3 id=&quot;datarefuge--project-svalbard&quot;&gt;DataRefuge + Project Svalbard&lt;/h3&gt;

&lt;p&gt;We’re working on a thing codenamed &lt;a href=&quot;https://github.com/datproject/svalbard&quot;&gt;Project Svalbard&lt;/a&gt; that is related to &lt;a href=&quot;http://www.ppehlab.org/datarefuge&quot;&gt;DataRefuge&lt;/a&gt;, a group working to back up government climate data at risk of disappearing. Svalbard is named after the Svalbard Global Seed Vault in the Arctic which has a big underground backup library of plant DNA. Our version of it is a big version controlled collection of public scientific datasets. Once we know and can trust the metadata, we can build other cool projects like a &lt;a href=&quot;https://github.com/datproject/datasilo/&quot;&gt;distributed volunteer data storage network&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;california-civic-data-coalition&quot;&gt;California Civic Data Coalition&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.californiacivicdata.org/&quot;&gt;CACivicData&lt;/a&gt; is an open-source archive serving up daily downloads from CAL-ACCESS, California’s database tracking money in politics. They do &lt;a href=&quot;http://calaccess.californiacivicdata.org/downloads/0&quot;&gt;daily releases&lt;/a&gt;, which means hosting a lot of duplicate data across their zip files. We’re working on hosting their data as a Dat repository which will reduce the amount of hassle and bandwidth needed to refer to specific version or update to a newer version.&lt;/p&gt;

&lt;h2 id=&quot;electron-updates&quot;&gt;Electron Updates&lt;/h2&gt;

&lt;p&gt;This one isn’t concrete yet, but we think a fun use case would be putting a compiled Electron app in a Dat repository, then using a Dat client in Electron to pull the latest deltas of the built app binary, to save on download time but also to reduce bandwidth costs for the server.&lt;/p&gt;

&lt;h2 id=&quot;who-should-be-using-dat-desktop&quot;&gt;Who should be using Dat Desktop?&lt;/h2&gt;

&lt;p&gt;Anyone who wants to share and update data over a p2p network. Data scientists, open data hackers, researchers, developers. We’re super receptive to feedback if anyone has a cool use case we haven’t thought of yet. You can drop by our &lt;a href=&quot;https://gitter.im/datproject/discussions&quot;&gt;Gitter Chat&lt;/a&gt; and ask us anything!&lt;/p&gt;

&lt;h2 id=&quot;whats-coming-next-in-dat-and-dat-desktop&quot;&gt;What’s coming next in Dat and Dat Desktop?&lt;/h2&gt;

&lt;p&gt;User accounts and metadata publishing. We are working on a Dat registry web app to be deployed at &lt;a href=&quot;https://datproject.org/&quot;&gt;datproject.org&lt;/a&gt; which will basically be an ‘NPM for datasets’, except the caveat being we are just going to be a metadata directory and the data can live anywhere online (as opposed to NPM or GitHub where all the data is centrally hosted, because source code is small enough you can fit it all in one system). Since many datasets are huge, we need a federated registry (similar to how BitTorrent trackers work). We want to make it easy for people to find or publish datasets with the registry from Dat Desktop, to make the data sharing process frictionless.&lt;/p&gt;

&lt;p&gt;Another feature is multi-writer/collaborative folders. We have big plans to do collaborative workflows, maybe with branches, similar to git, except designed around dataset collaboration. But we’re still working on overall stability and standardizing our protocols right now!&lt;/p&gt;

&lt;h2 id=&quot;why-did-you-choose-to-build-dat-desktop-on-electron&quot;&gt;Why did you choose to build Dat Desktop on Electron?&lt;/h2&gt;

&lt;p&gt;Dat is built using Node.js, so it was a natural fit for our integration. Beyond this, our users use a variety of machines
since scientists, researchers and government officials may be forced to use certain setups for their institutions – this means we need to be able to target Windows and Linux as well as Mac. Dat Desktop gives us that quite easily.&lt;/p&gt;

&lt;h2 id=&quot;what-are-some-challenges-youve-faced-while-building-dat-and-dat-desktop&quot;&gt;What are some challenges you’ve faced while building Dat and Dat Desktop?&lt;/h2&gt;

&lt;p&gt;Figuring out what people want. We started with tabular datasets, but we realized that it was a bit of a complicated problem to solve and that most people don’t use databases. So half way through the project, we redesigned everything from scratch to use a filesystem and haven’t looked back.&lt;/p&gt;

&lt;p&gt;We also ran into some general Electron infrastructure problems, including:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Telemetry - how to capture anonymous usage statistics&lt;/li&gt;
  &lt;li&gt;Updates - It’s kind of piecemeal and magic to set up automatic updates&lt;/li&gt;
  &lt;li&gt;Releases - XCode signing, building releases on Travis, doing beta builds, all were challenges.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We also use Browserify and some cool Browserify Transforms on the ‘front end’ code in Dat Desktop (which is kind of weird because we still bundle even though we have native &lt;code class=&quot;highlighter-rouge&quot;&gt;require&lt;/code&gt; – but it’s because we want the Transforms). To better help manage our CSS we switched from Sass to using &lt;a href=&quot;https://github.com/stackcss/sheetify&quot;&gt;sheetify&lt;/a&gt;. It’s greatly helped us modularize our CSS and made it easier to move our UI to a component oriented architecture with shared dependencies. For example &lt;a href=&quot;https://github.com/Kriesse/dat-colors&quot;&gt;dat-colors&lt;/a&gt; contains all of our colors and is shared between all our projects.&lt;/p&gt;

&lt;p&gt;We’ve always been a big fan of standards and minimal abstractions. Our whole interface is built using regular DOM nodes with just a few helper libraries. We’ve started to move some of these components into &lt;a href=&quot;https://base.choo.io&quot;&gt;base-elements&lt;/a&gt;, a library of low-level reusable components. As with most of our technology we keep iterating on it until we get it right, but as a team we have a feeling we’re heading in the right direction here.&lt;/p&gt;

&lt;h2 id=&quot;in-what-areas-should-electron-be-improved&quot;&gt;In what areas should Electron be improved?&lt;/h2&gt;

&lt;p&gt;We think the biggest pain point is native modules. Having to rebuild your modules for Electron with npm adds complexity to the workflow. Our team developed a module called &lt;a href=&quot;http://npmjs.org/prebuild&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;prebuild&lt;/code&gt;&lt;/a&gt; which handles pre-built binaries, which worked well for Node, but Electron workflows still required a custom step after installing, usually &lt;code class=&quot;highlighter-rouge&quot;&gt;npm run rebuild&lt;/code&gt;. It was annoying. To address this we recently switched to a strategy where we bundle all compiled binary versions of all platforms inside the npm tarball. This means tarballs get larger (though this can be optimized with &lt;code class=&quot;highlighter-rouge&quot;&gt;.so&lt;/code&gt; files - shared libraries), this approach avoids having to run post-install scripts and also avoids the &lt;code class=&quot;highlighter-rouge&quot;&gt;npm run rebuild&lt;/code&gt; pattern completely. It means &lt;code class=&quot;highlighter-rouge&quot;&gt;npm install&lt;/code&gt; does the right thing for Electron the first time.&lt;/p&gt;

&lt;h2 id=&quot;what-are-your-favorite-things-about-electron&quot;&gt;What are your favorite things about Electron?&lt;/h2&gt;

&lt;p&gt;The APIs seem fairly well thought out, it’s relatively stable, and it does a pretty good job at keeping up to date with upstream Node releases, not much else we can ask for!&lt;/p&gt;

&lt;h2 id=&quot;any-electron-tips-that-might-be-useful-to-other-developers&quot;&gt;Any Electron tips that might be useful to other developers?&lt;/h2&gt;

&lt;p&gt;If you use native modules, give &lt;a href=&quot;https://www.npmjs.com/package/prebuild&quot;&gt;prebuild&lt;/a&gt; a shot!&lt;/p&gt;

&lt;h2 id=&quot;whats-the-best-way-to-follow-dat-developments&quot;&gt;What’s the best way to follow Dat developments?&lt;/h2&gt;

&lt;p&gt;Follow &lt;a href=&quot;https://twitter.com/dat_project&quot;&gt;@dat_project&lt;/a&gt; on Twitter, or
subscribe to our &lt;a href=&quot;https://tinyletter.com/datdata&quot;&gt;email newsletter&lt;/a&gt;.&lt;/p&gt;</content><author><name>zeke</name></author><summary type="html">This week’s featured project is Dat, a grant-funded, open source, decentralized tool for distributing data sets. Dat is built and maintained by a geodistributed team, many of whom helped write this post.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://electron.atom.io/images/opengraph.png" /></entry><entry><title type="html">Project of the Week: Ghost</title><link href="https://electron.atom.io/blog/2017/02/14/ghost" rel="alternate" type="text/html" title="Project of the Week: Ghost" /><published>2017-02-14T00:00:00+00:00</published><updated>2017-02-14T00:00:00+00:00</updated><id>https://electron.atom.io/blog/2017/02/14/ghost</id><content type="html" xml:base="https://electron.atom.io/blog/2017/02/14/ghost">&lt;p&gt;This week we chatted with &lt;a href=&quot;https://felixrieseberg.com/&quot;&gt;Felix Rieseberg&lt;/a&gt;, desktop engineer at &lt;a href=&quot;https://slack.com/&quot;&gt;Slack&lt;/a&gt; and maintainer of &lt;a href=&quot;https://ghost.org/downloads/&quot;&gt;Ghost Desktop&lt;/a&gt;, an Electron client for the &lt;a href=&quot;https://ghost.org/&quot;&gt;Ghost&lt;/a&gt; publishing platform.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class=&quot;pt-5&quot;&gt;
  &lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/22913898/7396b0de-f222-11e6-8e5d-147a7ced37a9.png&quot; alt=&quot;Ghost Desktop Screenshot&quot; /&gt; 
&lt;/div&gt;

&lt;h2 id=&quot;what-is-ghost&quot;&gt;What is Ghost?&lt;/h2&gt;

&lt;p&gt;Ghost is a fully open source, hackable platform for building and running a modern online publication. We power blogs, magazines and journalists from Zappos to Sky News.&lt;/p&gt;

&lt;h2 id=&quot;what-makes-it-different-from-other-publishing-platforms&quot;&gt;What makes it different from other publishing platforms?&lt;/h2&gt;

&lt;p&gt;Ghost was founded in April 2013, after a very successful Kickstarter campaign to create a new platform focused solely on professional publishing. Our mission is to create the best open source tools for independent journalists and writers across the world, and have a real impact on the future of online media. It offers a simpler, more focussed experience: Our editor is designed solely around providing the best possible writing experience.&lt;/p&gt;

&lt;p&gt;Compared to the all-time classic WordPress, it offers a simpler, more streamlined experience - it is easier to setup and maintain, comes with all important features out-of-the-box, and is dramatically faster. Compared to other online platforms, Ghost gives writers full ownership and control over their content, allows full customization, and enables authors to build a business around their publication.&lt;/p&gt;

&lt;h2 id=&quot;is-ghost-a-for-profit-company&quot;&gt;Is Ghost a for-profit company?&lt;/h2&gt;

&lt;p&gt;This one is important to us: Ghost is an independent non-profit organisation. We build publishing tools for modern journalism &amp;amp; blogging because we believe freedom of speech is important. Our software is released under a &lt;a href=&quot;https://github.com/TryGhost/Ghost&quot;&gt;free open source license&lt;/a&gt;, our business model is &lt;a href=&quot;https://blog.ghost.org/year-3/&quot;&gt;completely transparent&lt;/a&gt;, and our legal structure means that 100% of the money we make is reinvested into making Ghost better.&lt;/p&gt;

&lt;h2 id=&quot;what-is-ghost-desktop&quot;&gt;What is Ghost Desktop?&lt;/h2&gt;

&lt;p&gt;Ghost Desktop allows writers to manage multiple blogs at once - and to focus on their writing. Simple things like common writing shortcuts can’t be realized in a browser, but are available in our desktop app. It allows other applications to communicate directly &lt;a href=&quot;https://github.com/tryghost/ghost-desktop/blob/master/docs/deeplinks.md&quot;&gt;with the blog via deeplinks&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-is-ghost-for-journalism&quot;&gt;What is Ghost for Journalism?&lt;/h2&gt;

&lt;p&gt;This year we’re very excited to be dedicating our entire 10 person full-time Ghost team to helping grow three independent publications, along with $45,000 in resources toward their efforts. We’re calling it &lt;a href=&quot;https://ghost.org/journalism/&quot;&gt;Ghost for Journalism&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We’ve been building Ghost as the web’s next great platform for independent publishers for about three and half years now, and we’ve now reached a really interesting inflection point. We started this journey to create a simple, well designed blogging platform which could be used by just about anyone. That was always going to be step one.&lt;/p&gt;

&lt;p&gt;Long term, we want Ghost to be an incredible platform for the world’s best journalism, and that means we need to build features to attract exactly those people. This year we’re making a very conscious decision to focus on just that.&lt;/p&gt;

&lt;h2 id=&quot;why-did-you-choose-to-build-ghost-desktop-on-electron&quot;&gt;Why did you choose to build Ghost Desktop on Electron?&lt;/h2&gt;

&lt;p&gt;Ghost uses JavaScript and Node.js on both the backend and frontend, so being able to utilize the same technology and skillset enables our team to move faster, build more, and ultimately deliver a better experience. In addition, being able to share more than 95% of code between the macOS, Windows, and Linux version of the app allows us to focus on building a great core user experience, without having to maintain one code base for each platform.&lt;/p&gt;

&lt;h2 id=&quot;what-are-some-challenges-youve-faced-while-building-ghost-desktop&quot;&gt;What are some challenges you’ve faced while building Ghost Desktop?&lt;/h2&gt;

&lt;p&gt;Spellchecking is likely still one of the most difficult services offered - we could easily utilize one of the many online services, but correctly spellchecking text in multiple languages while guarding the privacy and autonomy of our users is not an easy task.&lt;/p&gt;

&lt;h2 id=&quot;in-what-areas-should-electron-be-improved&quot;&gt;In what areas should Electron be improved?&lt;/h2&gt;

&lt;p&gt;We would love to see Electron bring the operating system’s native spellchecking capabilities to their apps. We’re dreaming about a world in which an &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;input&amp;gt;&lt;/code&gt; field receives the same services as a &lt;code class=&quot;highlighter-rouge&quot;&gt;NSTextView&lt;/code&gt;, but we are also intimately aware how difficult that is.&lt;/p&gt;

&lt;h2 id=&quot;what-are-your-favorite-things-about-electron&quot;&gt;What are your favorite things about Electron?&lt;/h2&gt;

&lt;p&gt;JavaScript is famous for being a vast ecosystem, involving countless tools and frameworks - but the convenience it affords us is hard to overstate. Building an app with Electron is only &lt;em&gt;slightly&lt;/em&gt; harder than building a web app, which is an amazing  feat.&lt;/p&gt;

&lt;h2 id=&quot;is-ghost-done-if-not-whats-coming-next&quot;&gt;Is Ghost done? If not, what’s coming next?&lt;/h2&gt;

&lt;p&gt;Ghost Desktop is also an ongoing project - we’re pretty far from being done. We have been talking for a while about bringing a full offline mode to our users, and we’re getting fairly close. Other notable work areas are the extension and integration with other text editing apps (like Word or Atom), ultimately allowing people to write posts using their favorite tools. In general, once we’ve shipped the offline mode feature, we’re looking for deeper integration with the operating system. If that sounds interesting to you, &lt;a href=&quot;https://github.com/tryghost/ghost-desktop&quot;&gt;join us&lt;/a&gt;!&lt;/p&gt;

&lt;h2 id=&quot;what-are-some-of-your-favorite-electron-apps&quot;&gt;What are some of your favorite Electron apps?&lt;/h2&gt;

&lt;p&gt;I’m a big fan of &lt;a href=&quot;https://getkap.co/&quot;&gt;Kap&lt;/a&gt;, &lt;a href=&quot;https://github.com/henryboldi/felony&quot;&gt;Felony&lt;/a&gt;, and &lt;a href=&quot;https://code.visualstudio.com&quot;&gt;Visual Studio Code&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;👻&lt;/p&gt;</content><author><name>zeke</name></author><summary type="html">This week we chatted with Felix Rieseberg, desktop engineer at Slack and maintainer of Ghost Desktop, an Electron client for the Ghost publishing platform.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://electron.atom.io/images/opengraph.png" /></entry><entry><title type="html">Project of the Week: Beaker Browser</title><link href="https://electron.atom.io/blog/2017/02/07/beaker-browser" rel="alternate" type="text/html" title="Project of the Week: Beaker Browser" /><published>2017-02-07T00:00:00+00:00</published><updated>2017-02-07T00:00:00+00:00</updated><id>https://electron.atom.io/blog/2017/02/07/beaker-browser</id><content type="html" xml:base="https://electron.atom.io/blog/2017/02/07/beaker-browser">&lt;p&gt;This week we caught up with &lt;a href=&quot;http://pfrazee.github.io/&quot;&gt;Paul Frazee&lt;/a&gt;, creator
of &lt;a href=&quot;https://beakerbrowser.com/&quot;&gt;Beaker Browser&lt;/a&gt;. Beaker is an experimental
peer-to-peer web browser that uses the Dat protocol to host sites from users’
devices.&lt;/p&gt;

&lt;hr /&gt;

&lt;iframe width=&quot;100%&quot; height=&quot;420&quot; src=&quot;https://www.youtube.com/embed/Bem9nRpyPEs&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h2 id=&quot;what-is-beaker-and-why-did-you-create-it&quot;&gt;What is Beaker and why did you create it?&lt;/h2&gt;

&lt;p&gt;Beaker is a participatory browser. It’s a browser for indie hackers.&lt;/p&gt;

&lt;p&gt;The Web is closed source. If you want to influence how social media works, you have to work at Facebook or Twitter. For search, Google. Control is in the hands of companies, rather than the users themselves.&lt;/p&gt;

&lt;p&gt;With Beaker, we have a new Web protocol: the &lt;a href=&quot;https://datprotocol.com&quot;&gt;Decentralized Archive Transport&lt;/a&gt;. “Dat.” It creates sites on demand, for free, and then shares them from the device. No servers required. That’s our innovation.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://cloud.githubusercontent.com/assets/2289/22560648/3defed5c-e92a-11e6-93f8-956cafafe3be.jpg&quot; alt=&quot;Beakers Protocols&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When you visit a Dat site in Beaker, you download the files. The site is yours, forever. You can save it, fork it, modify it, and share your new version for free. It’s all open-source.&lt;/p&gt;

&lt;p&gt;So that’s what it’s about: We’re making a browser for open-source Websites. We want it to be a toolkit for social hacking.&lt;/p&gt;

&lt;h2 id=&quot;who-should-be-using-beaker&quot;&gt;Who should be using Beaker?&lt;/h2&gt;

&lt;p&gt;Hackers. Modders. Creative types. People who like to tinker.&lt;/p&gt;

&lt;h2 id=&quot;how-do-i-create-a-new-project-that-uses-dat&quot;&gt;How do I create a new project that uses Dat?&lt;/h2&gt;

&lt;p&gt;We’ve got &lt;a href=&quot;https://github.com/beakerbrowser/bkr&quot;&gt;a command-line tool called bkr&lt;/a&gt; that’s kind of like git + npm. Here’s creating a site:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/my-site
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;bkr init
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello, world!&quot;&lt;/span&gt; &amp;gt; index.html
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;bkr publish
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And here’s forking a site:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;bkr fork dat://0ff7d4c7644d0aa19914247dc5dbf502d6a02ea89a5145e7b178d57db00504cd/ ~/my-fork
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; ~/my-fork
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;My fork has no regard for the previous index.html!&quot;&lt;/span&gt; &amp;gt; index.html
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;bkr publish
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Those sites then get hosted out of your browser. It’s a little like BitTorrent; you share the sites in a P2P mesh.&lt;/p&gt;

&lt;p&gt;If you want a GUI, we have some basic tools built into the browser, but we’re pushing those tools into userland. It’s all going to be moddable user apps.&lt;/p&gt;

&lt;h2 id=&quot;why-did-you-choose-to-build-beaker-on-electron&quot;&gt;Why did you choose to build Beaker on Electron?&lt;/h2&gt;

&lt;p&gt;It was obvious for this project. If I forked Chrome myself, I’d be writing C++ right now! Nobody wants to do that. I know the Web stack, and I can work quickly with it. It’s a no-brainer.&lt;/p&gt;

&lt;p&gt;The truth is, I’m not sure I could do any of this without Electron. It’s a great piece of software.&lt;/p&gt;

&lt;h2 id=&quot;what-are-some-challenges-youve-faced-while-building-beaker&quot;&gt;What are some challenges you’ve faced while building Beaker?&lt;/h2&gt;

&lt;p&gt;Half of it is poking at the tools and figuring out how much I can get away with.&lt;/p&gt;

&lt;p&gt;Making the browser itself was pretty easy. Electron is practically a toolkit for making browsers. …Except for the browser tabs; that took me forever to get right. I finally broke down and learned how to do SVGs. It’s much better looking, but it took 3 or 4 iterations before I got that right.&lt;/p&gt;

&lt;h2 id=&quot;in-what-areas-should-electron-be-improved&quot;&gt;In what areas should Electron be improved?&lt;/h2&gt;

&lt;p&gt;It’d be really great if I could dock the devtools inside a webview.&lt;/p&gt;

&lt;h2 id=&quot;whats-coming-next-in-beaker&quot;&gt;What’s coming next in Beaker?&lt;/h2&gt;

&lt;p&gt;Secure DNS names for Dat sites. A socially configurable URL scheme, called the &lt;a href=&quot;https://github.com/beakerbrowser/beaker/wiki/App-Scheme&quot;&gt;“app scheme.”&lt;/a&gt; More Dat APIs.&lt;/p&gt;

&lt;h2 id=&quot;for-folks-who-may-be-interested-in-contributing-to-the-project-in-what-areas-does-beaker-need-help&quot;&gt;For folks who may be interested in contributing to the project, in what areas does Beaker need help?&lt;/h2&gt;

&lt;p&gt;We have lots of open issues. Don’t be afraid to ping me. #beakerbrowser on freenode. We keep a &lt;a href=&quot;https://beakerbrowser.com/docs/team.html&quot;&gt;page for contributors&lt;/a&gt; and we’ll add you to it. And if you visit Austin, I’ll buy you a beer.&lt;/p&gt;

&lt;h2 id=&quot;any-electron-tips-that-might-be-useful-to-other-developers&quot;&gt;Any Electron tips that might be useful to other developers?&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Use the build tooling that’s out there. You don’t want to wrestle with your own solutions, trust me. Use electron-builder. Use a boilerplate repo.&lt;/li&gt;
  &lt;li&gt;If you need to open an issue in the Electron repo, go the extra mile to make it easy to reproduce. You’ll get a response much more quickly, and the team will appreciate it. Even better, try fixing it yourself. It’s actually pretty interesting to see the innards.&lt;/li&gt;
  &lt;li&gt;Read through all the guides and advanced docs at least once.&lt;/li&gt;
  &lt;li&gt;Don’t build a browser, it’s a saturated market.&lt;/li&gt;
&lt;/ol&gt;</content><author><name>zeke</name></author><summary type="html">This week we caught up with Paul Frazee, creator of Beaker Browser. Beaker is an experimental peer-to-peer web browser that uses the Dat protocol to host sites from users’ devices.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://electron.atom.io/images/opengraph.png" /></entry></feed>