<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Open Sourcery]]></title><description><![CDATA[A blog on my experiences in the open source ecosystem]]></description><link>https://amilajack.com/</link><image><url>https://amilajack.com/favicon.png</url><title>Open Sourcery</title><link>https://amilajack.com/</link></image><generator>Ghost 5.33</generator><lastBuildDate>Tue, 21 Apr 2026 09:06:01 GMT</lastBuildDate><atom:link href="https://amilajack.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Roughpad - Your New Scratchpad]]></title><description><![CDATA[<p>I&apos;m incredibly excited to announce an app I&apos;ve been working on for a while, Roughpad: a productivity tool for quick and easy notes.</p><p>Roughpad is great for jotting down small and unstructured bits of information. So far users have been using Roughpad for meeting notes, code</p>]]></description><link>https://amilajack.com/roughpad/</link><guid isPermaLink="false">618dfabc6fc68141ffa1ae86</guid><category><![CDATA[roughpad]]></category><category><![CDATA[productivity]]></category><category><![CDATA[apps]]></category><category><![CDATA[notes]]></category><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Sat, 13 Nov 2021 02:39:34 GMT</pubDate><media:content url="https://amilajack.com/content/images/2021/11/Screen-Shot-2021-11-12-at-7.26.48-PM.png" medium="image"/><content:encoded><![CDATA[<img src="https://amilajack.com/content/images/2021/11/Screen-Shot-2021-11-12-at-7.26.48-PM.png" alt="Roughpad - Your New Scratchpad"><p>I&apos;m incredibly excited to announce an app I&apos;ve been working on for a while, Roughpad: a productivity tool for quick and easy notes.</p><p>Roughpad is great for jotting down small and unstructured bits of information. So far users have been using Roughpad for meeting notes, code snippets, todo lists, journaling, twitter thread drafts, jotting down phone numbers, and more.</p><figure class="kg-card kg-image-card"><img src="https://amilajack.com/content/images/2021/11/140842957-fc15d416-8bd6-4cb4-84fa-10ac21dc29ed.gif" class="kg-image" alt="Roughpad - Your New Scratchpad" loading="lazy" width="1798" height="1262"></figure><p>Tools like Notion, Quip, and Google Docs encourage structure with folders, document titles, and document formatting options. While structure is great for larger documents, it is often overkill for rough notes or jotting things down. Roughpad doesn&apos;t force you to figure out what folder you should put a note into, nor does it encourage titling or formatting. Just create a new tab and start typing.</p><h2 id="features">Features</h2><p><strong>Global Shortcut</strong></p><p>Roughpad adds a global shortcut which allows you to press <code>Command + Shift + D</code> to focus Roughpad.</p><p><strong>Tabs and Shortcuts</strong></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://amilajack.com/content/images/2021/11/140602491-d6f3c272-273e-445a-bbd3-d309777e57d4.gif" class="kg-image" alt="Roughpad - Your New Scratchpad" loading="lazy" width="1920" height="1080"><figcaption>Tab Support (with roughpad dark mode)</figcaption></figure><p><strong>Markdown</strong></p><p>Roughpad supports markdown, which makes code snippets, lists, checkboxes, and other tasks easy.</p><p><strong>Command Palette and Search</strong></p><p>To make Roughpad even faster to use, &#xA0;it features a command palette for quick searches across all your notes. Open and close the command palette with <code>Command + P</code>.</p><figure class="kg-card kg-image-card"><img src="https://amilajack.com/content/images/2021/11/cmdp-1.gif" class="kg-image" alt="Roughpad - Your New Scratchpad" loading="lazy" width="1798" height="1262"></figure><p><strong>Local First</strong></p><p>Roughpad&apos;s notes are local first, meaning they&apos;re stored on your computer. This makes Roughpad incredibly fast and secure.</p><hr><h2 id="try-it-out">Try it out!</h2><!--kg-card-begin: html--><a href="https://roughpad-releases.vercel.app" style="text-decoration: none; text-align: left;">
    <button type="button" style="background: black; color: white; padding: 15px 30px; border-radius: 10px; font-size: 2rem;">
		Download it here
    </button>
</a><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[Getting Started in Open Source]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Its hard to imagine a world without open source software, the most significant force multiplier for the software industry. Open source software is so prevelant that we often take it for granted that critical software should be open source and free to use. This includes anything from databases to cryptocurrencies</p>]]></description><link>https://amilajack.com/getting-started-open-source/</link><guid isPermaLink="false">60035b47e0233a06b83a9a11</guid><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Wed, 03 Feb 2021 05:02:11 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Its hard to imagine a world without open source software, the most significant force multiplier for the software industry. Open source software is so prevelant that we often take it for granted that critical software should be open source and free to use. This includes anything from databases to cryptocurrencies to programming languages.</p>
<p>Open collaboration and free use of projects isn&apos;t the norm across industries. Imagine trying to explain how open source to someone outside the software industry. If you say &quot;the world depends on this software that engineers write in their free time, without compensation&quot;, you&apos;d be right and your friend would be puzzled. Open source is confusing and I rarely see explinations around why and how it works and why one should contribute to open source. In this post I&apos;ll discuss what open source is, why it works, and how you can start contributing to open source.</p>
<hr>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Mom: Dad said you invented a thing? ESLint?<br>Me: Yes.<br>Mom: What is it?<br>Me: It finds and fixes problems in JavaScript.<br>Mom: Huh. Do people use it?<br>Me: Basically everyone writing JS.<br>Mom: How much did you make on it?<br>Me: Nothing.<br>Mom: I don&#x2019;t understand your industry.<br>Me: Me either.</p>&#x2014; Nicholas C. Zakas (@slicknet) <a href="https://twitter.com/slicknet/status/1086053326007881728?ref_src=twsrc%5Etfw">January 18, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<h1 id="whatisopensource">What is Open Source?</h1>
<p>At its core open source is about finding solutions for problems and sharing those solutions with others.</p>
<p>David Heinemeier Hansson, the creator of Ruby on Rails, summarizes this well:</p>
<blockquote>
<p>My core philosophy about open source is that we should all be working on the things that we personally use and care about. ... if we work on the things we care about and then share those solutions between us, the world gets richer much faster.</p>
</blockquote>
<h2 id="whyopensourceworks">Why open source works</h2>
<p>A commonly misunderstood aspect of open source is its incentive structure, a critical component of successful open source communities. I&apos;ll start by making an argument that might run contrary to your intuition: it&apos;s in the best interest of individuals and organizations to open source certain projects. For companies, this usually means open sourcing projects their product depends on, not the product itself. It&apos;s quite common for a company&apos;s competitor to depend on software it has open sourced. The counterintuitive idea of competing companies collaborating on software baffles many who are new to open source, but to insiders, it makes perfect sense.</p>
<p>Open source is a <a href="https://en.wikipedia.org/wiki/Nash_equilibrium">Nash equilibrium</a> between competing companies, meaning organizations with opposing interests can collaborate in such a way that each organization better off than it would be working independently. Microsoft and Amazon, fierce competitors in cloud computing, make frequent contributions to the <a href="https://www.rust-lang.org/">Rust programming language</a> and its surrounding ecosystem. Each contribution made by one organization benefits itself and all other organizations that depend on the project. It&apos;s in the best interest of existing contributors to the project to onboard new contributors, which implies more contributions. Concisely, open source projects thrive off of <a href="https://en.wikipedia.org/wiki/Network_effect">network effects</a>. Similarly, increasing a number of users of a project also benefits the project since frequent users are likely to eventually become contributors.</p>
<h3 id="benefitstocontributors">Benefits to contributors</h3>
<p>The benefits of open source to software communities and ecosystems are quite hard to ignore. However, what&apos;s rarely discussed are the direct benefits to individual open source contributors.</p>
<blockquote>
<p>&quot;Why would anyone work for free?&quot;</p>
</blockquote>
<p>This is a good place to start. Contributors don&apos;t see open source as work; instead, they see it as an outlet for creative expression and experimentation, an opportunity to dabble in new domains of software engineering, and a way to be part of a community. Additionally, contributors have the flexibility to switch between projects, choose what and when they contribute, and even choose if they want to contribute at all.</p>
<h2 id="formsofopensourceprojects">Forms of open source projects</h2>
<p>Open source projects largely fall into four categories:</p>
<table>
<thead>
<tr>
<th>Category</th>
<th>Characteristics</th>
<th>Examples</th>
</tr>
</thead>
<tbody>
<tr>
<td>single owner, single contributor</td>
<td>unmaintained, few users</td>
<td></td>
</tr>
<tr>
<td>single owner, multiple contributor</td>
<td>frequently maintained, many users</td>
<td><a href="https://github.com/mrdoob/three.js">three.js</a></td>
</tr>
<tr>
<td>single organization owner, multiple contributors</td>
<td>frequently maintained, many users</td>
<td><a href="https://github.com/microsoft/typescript">typescript</a>, <a href="https://github.com/facebook/react">react</a></td>
</tr>
<tr>
<td>distributed ownership, multiple contributors</td>
<td>frequently maintained, many users</td>
<td><a href="https://github.com/git/git">git</a>, <a href="https://github.com/rust-lang/rust">rust</a></td>
</tr>
</tbody>
</table>
<h1 id="opensourcein5steps">Open Source in 5 Steps</h1>
<h2 id="1opensourceyourprojects">1. <strong>Open source your projects</strong></h2>
<p>One of the easiest ways to try something new is to try the easiest version of that thing. One way of making something easier to do is lowering the barrier to trying that thing. The easiest way to get started is to open source projects you already have, whether or not you want to contribute to them later on. I recommend this for two reasons: (1) it showcases what you&apos;ve worked on and (2) it helps you practice open sourcing projects and showcasing them well. If you want to bring attention to certain projects, use GitHub&apos;s pinned repositories feature to highlight them. Don&apos;t worry about your projects being new or ground breaking, since your first goal should be to showcase your interests. Consider open sourcing notes or other kinds of organized information that could be of value to others. These projects tend to be some of the most popular while also being the easiest to bootstrap and contribute to.</p>
<p>Below are some examples of popular lists and notes:</p>
<ul>
<li><a href="https://github.com/sindresorhus/awesome">https://github.com/sindresorhus/awesome</a></li>
<li><a href="https://github.com/stanfordnlp/cs224n-winter17-notes">https://github.com/stanfordnlp/cs224n-winter17-notes</a></li>
<li><a href="https://github.com/amilajack/project-checklist">https://github.com/amilajack/project-checklist</a></li>
</ul>
<p>A common pitfall I see is lack of communication around projects. It&apos;s common to see projects with profound technical accomplishments that are very poorly understood. These projects usually lack READMEs and channels for discussion such as Slack, Discord, or the new GitHub discussions feature. I&apos;ve outlined a set of <a href="https://github.com/amilajack/project-checklist#-initial-presentation">high level tips for project communication</a> that you might find useful.</p>
<h2 id="2pickaproject">2. <strong>Pick a project</strong></h2>
<p>After adding your projects to your GitHub profile, decide on a project you want to contribute to.</p>
<p>There are two ways you could go about finding a project you want to contribute to:</p>
<p>(1). Pick a project you depend on that you want to improve. That project, for example, may be lacking certain features you require, difficult to use, or suboptimal in performance. If you&apos;re actively working on a project and you find a dependency lacking certain features you depend on, contribute these features.</p>
<p>(2). Find the problem spaces you are interested in and pick an actively maintained project in the problem space you find most interesting. If the project has been inactive for over a year I recommend considering another project. Be careful to not pick a large project as the first project you contribute to since they tend to be harder to ramp up on.</p>
<p>Most existing contributors tend to favor option (1) since it adds immediate value to themselves and the community. It also has a much clearer end goal compared to (2). Option (2) is ideal if you are already a software engineer who&apos;s dabbled in open source and your primary goal is to ramp up in new problem spaces. Most who are new to open source try to start with option (2) but the immediate and practical benefits of option (1) make it a better option for most.</p>
<h2 id="3startcontributing">3. <strong>Start contributing</strong></h2>
<p>Once you&apos;ve picked a project, decide what you want to contribute. Contributions can include anything from helping answer questions in the community to helping resolve open GitHub issue tickets to adding or improving documentation. Again, lower the barrier to contributing by finding the easiest way to contribute. Contributing these small improvements can be seen as ramp up tasks which will eventually familiarize yourself enough with the project to contribute more technical changes later on.</p>
<p>After you&apos;re familiar enough with the project, try addressing more technical aspects of the project. This includes bug fixes or implementing small features. For larger changes, ask the project&apos;s maintainers if they will welcome the change you have in mind. Don&apos;t hesitate to ask the maintainers for some guidance around what you want to contribute.</p>
<h3 id="maintainersvscontributors">Maintainers vs contributors</h3>
<p>When you think it&apos;s appropriate, reflect on whether you want to be a contributor or a maintainer.</p>
<p>I often see open source beginners think of making one time contributions to open source projects as a learning experience. This makes sense but it&#x2019;s often a much better learning experience to be a long term contributor to a project.</p>
<p>Long term contributors learn to take ownership for changes they make to a project. This is comparable to the experience of a full time employee. They have the opportunity to see a project to completion and observe how it evolves over time. One-off contributions are analogous to contract work. Depending on the project, long term contributors can also be much more aware of customer demands in the problem space. This can give them an edge in understanding new challenges and seed ideas for new projects.</p>
<h3 id="becomingamaintainer">Becoming a Maintainer</h3>
<p>So you&apos;ve now found a project and you&apos;ve made a number of contributions to it. You&apos;re excited about its trajectory and you&apos;re fascinated by its technical capabilities. You&apos;ve familiarized yourself with the project and you&apos;ve made a number of ramp up contributions. What then?</p>
<p>One option is to expand your role and influence in the project. If you disagree with the roadmap, start a discussion with the maintainers and share your suggestions. This is about as far you can go as a contributor. To have greater influence on the project, you&apos;ll need to join the core team of the project or, in open source jargon, become a maintainer.</p>
<h2 id="4joinacommunity">4. <strong>Join a Community</strong></h2>
<h3 id="listentotheconversation">Listen to the conversation</h3>
<p>Twitter is the platform of choice for open source maintainers and the tech community in large.</p>
<p>Twitter is a tool -- use it with intention and browsing your feed will be analogous to listening in on a conversation amongst the greatest minds in the field.</p>
<blockquote>
<p>You&#x2019;re the average of the five people you spend the most time with.</p>
</blockquote>
<p>Use twitter to surround yourself with great engineers and you will learn so much. You can listen to their opinions, see them clash, see their predictions in the problem space, and see what they identify as key problems.</p>
<h3 id="jointheconversation">Join the conversation</h3>
<p>Actively participate in conversations that you find interesting. If you have questions, tweet about what you&apos;re working on.</p>
<p>Once you build something new, tweet and blog about it.</p>
<h2 id="5stayintheloop">5. <strong>Stay in the loop</strong></h2>
<p>Stay on top of recent news and trends. Paying attention to new ideas can hint at some suggestions for new project ideas. I recommend subscribing to the domain specific and generalist newsletters.</p>
<h3 id="generalist">Generalist</h3>
<ul>
<li><a href="https://changelog.com/weekly">https://changelog.com/weekly</a></li>
</ul>
<h3 id="domainlanguagespecificnewsletters">Domain/language specific newsletters</h3>
<ul>
<li><a href="https://this-week-in-rust.org/">Rust Newsletter</a></li>
<li><a href="https://www.pythonweekly.com/">Python Weekly</a></li>
<li><a href="https://rubyweekly.com/">Ruby Weekly</a></li>
<li><a href="https://javascriptweekly.com/">JavaScript Weekly</a></li>
<li><a href="https://nodeweekly.com/">Node Weekly</a></li>
</ul>
<hr>
<h2 id="appendix">Appendix</h2>
<h3 id="recommendedreadings">Recommended Readings</h3>
<ul>
<li><a href="https://amasad.me/github">https://amasad.me/github</a></li>
<li><a href="https://dhh.dk/posts/36-work-on-what-you-use-and-share-the-rest">https://dhh.dk/posts/36-work-on-what-you-use-and-share-the-rest</a></li>
<li><a href="http://www.paulgraham.com/opensource.html">http://www.paulgraham.com/opensource.html</a></li>
<li><a href="https://opensource.guide/how-to-contribute/">https://opensource.guide/how-to-contribute/</a></li>
</ul>
<hr>
<p>I hope you now have a bit more insight on where to get started in open source. If you feel like I have missed certain topics or if you have questions please feel free to comment or reach out.</p>
<ul>
<li><a href="https://twitter.com/amilajack">Twitter @amilajack</a></li>
<li><a href="https://github.com/amilajack">Github @amilajack</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Alfred - A Modular Toolchain for JavaScript]]></title><description><![CDATA[<!--kg-card-begin: markdown--><h1 id="whatisalfredtldr">What is Alfred? TL;DR</h1>
<p>Alfred is toolchain for JavaScript that aims to:</p>
<ul>
<li>Provide tools that work out of the box</li>
<li>Simplify the process of using JavaScript tooling</li>
<li>Make JavaScript tooling more reliable</li>
<li>Serve as an alternative for boilerplates/&quot;starter kits&quot;</li>
</ul>
<p>Here&apos;s an example of how</p>]]></description><link>https://amilajack.com/alfred/</link><guid isPermaLink="false">5e0554bfa2380f5b95ecd07a</guid><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Sun, 15 Mar 2020 23:11:00 GMT</pubDate><media:content url="https://amilajack.com/content/images/2020/03/alfred-banner-1.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h1 id="whatisalfredtldr">What is Alfred? TL;DR</h1>
<img src="https://amilajack.com/content/images/2020/03/alfred-banner-1.jpg" alt="Alfred - A Modular Toolchain for JavaScript"><p>Alfred is toolchain for JavaScript that aims to:</p>
<ul>
<li>Provide tools that work out of the box</li>
<li>Simplify the process of using JavaScript tooling</li>
<li>Make JavaScript tooling more reliable</li>
<li>Serve as an alternative for boilerplates/&quot;starter kits&quot;</li>
</ul>
<p>Here&apos;s an example of how Alfred is be used:</p>
<pre><code class="language-bash"># Create a new Alfred project
alfred new my-react-app --project app.browser
cd my-react-app

# Add react support to your project
alfred learn @alfred/skill-react

# Run commands
alfred run start
alfred run build
alfred run lint

# Deploying to Github Pages
alfred learn @alfred/skill-github-pages
alfred run deploy
</code></pre>
<p>To get a better understand what Alfred is trying solve, its improtant to understand the current state of JavaScript tooling.</p>
<h1 id="thestateoftooling">The State of Tooling</h1>
<p>Maintaining over 200 open source JavaScript projects for the last 6 years has exposed me to the best and worst parts of JavaScript infrastructure. JavaScript infrastructure shines when it comes to flexibility. They make few assumptions about the user of the tools, but they don&apos;t assume you&apos;ll be using other tools. Making no assumptions is nice because it allows users to use whatever tools they want. Infrastructure usually doesn&apos;t come with integration for other tools out of the box support so integration is usually added by 3rd party plugins. This model for infrastructure is convenient because it allows developers to write plugins which extend the functionality of the tools they use, therefore allowing the tools to be used in a much wider range of scenarios than anticipated by maintainers. The downside of this customizability is that the tools usually don&#x2019;t work out of the box. This comes at a huge cost to the user experience of beginners who have never used that tool before.</p>
<p>The JS ecosystem responds to this complexity by creating &#x2018;<a href="https://github.com/search?q=boilerplate">boilerplates&#x2019;</a>, or <a href="https://github.com/topics/starter-kit">&#x2018;starter kits&#x2019;</a>, which are essentially template projects that have their infrastructure preconfigured for the tools the template project supports. For example, <a href="https://github.com/electron-react-boilerplate/electron-react-boilerplate"><code>electron-react-boilerplate</code></a> is a boilerplate that configures electron, react, eslint, webpack, and jest. Boilerplates solve the out-of-the-box problem but they sacrifice extensibility because they don&#x2019;t expect users to change the tools they come with or even change the configurations of those tools.</p>
<p>Alfred proposes a new solution that allows each tool to configure itself with respect to other tools. To better understand Alfred&#x2019;s solution, it is important to dive deeper into the current drawbacks of JS infrastructure.</p>
<h1 id="toolingdrawbacks">Tooling Drawbacks</h1>
<h4 id="jstoolingisbrittle">JS Tooling is Brittle</h4>
<p>When trying new tools, newcomers often spend a significant amount of time configuring tools. The difficulty of configuring a tool or library can discourage the user from using the it alltogether. Even users of widely adopted libraries and tools tend to experience issues related to configuration. The tweet below describes the situation well:</p>
<p>&quot;Looking at the issues on <a href="https://github.com/storybookjs/storybook"><code>storybooks/storybook</code></a>:</p>
<ul>
<li>2,479 total issues</li>
<li>732 mention &quot;webpack&quot; (30%)</li>
<li>428 mention &quot;babel&quot; (17%)</li>
</ul>
<p>That&apos;s crazy! Other keywords that come up that often would be treated as requiring architectural change, but those are just for configuration.&quot;</p>
<blockquote>
<p>It&apos;s a little mind-boggling how many issues are purely for dealing with Babel or Webpack configuration. And those are by far some of the most frustrating issues to debug when you do run into them. So much time wasted. Makes you really understand the &quot;zero config&quot; movement.</p>
</blockquote>
<h4 id="incorrectsuboptimalinfrastructure">Incorrect, Suboptimal Infrastructure</h4>
<p>One of the great strengths of JS tooling is its customizability. This customizability allows JS tools to be used in a wide different use cases. But leaving the configuration of tools up to users allows for the possibility of misconfiguring tools, which often results in tools that are used sub-optimally or even incorrectly. For example, it is common for libraries to ship with polyfills or compiled code. This is considered an anti pattern because this makes it harder for applications to optimize apps which use the libraries (<a href="https://en.wikipedia.org/wiki/Tree_shaking">tree shaking</a>) and it increases the bundle sizes of apps that use the libraries.</p>
<h1 id="thesolution">The Solution</h1>
<p>Alfred aims to solve these problems by enabling tools to configure themselves out of the box. Each tool should know how to configure itself so that it can be compatible with other tools the user is using. Alfred achieves this &apos;out of the box&apos; solution by generating minimal configurations for the user&apos;s tools. Advanced users can override or extend generated configurations. Alfred tests each combination of tools before publishing new versions.</p>
<h4 id="skills">Skills</h4>
<p>A <em><a href="https://alfred.js.org/docs/skills/">skill</a></em> is an abstraction over a tool that allows it to configure itself with respect to other tools. For example, a babel &#x2018;skill&#x2019; which wants to add react support would add the <code>babel-preset-react</code> preset to its config if the user is using the react skill.</p>
<p>Here is an example of a skill:</p>
<pre><code class="language-js">export default {
  name: &quot;eslint&quot;,
  devDependencies: {
    &quot;eslint-config-airbnb&quot;: &quot;18.0.0&quot;
  },
  configs: [
    {
      // Config&apos;s filename
      filename: &quot;.eslintrc.js&quot;,
      // The base eslint config
      config: {
        plugins: [&quot;eslint-plugin-prettier&quot;]
      }
    }
  ],
  transforms: {
    // Make eslint config compatible with react
    react(eslintSkill) {
      return eslintSkill
        .extendConfig(&quot;eslint&quot;, {
          plugins: [&quot;eslint-plugin-react&quot;]
        })
        .addDevDeps({
          &quot;eslint-plugin-react&quot;: &quot;7.18.0&quot;
        });
    }
  }
};
</code></pre>
<p>For more on skills, see the <a href="https://alfred.js.org/docs/skills/">skills section of the docs</a>.</p>
<p>Alfred comes with skills out of the box but it also allows users to use 3rd party skills as well. Users can customize configs through Alfred&apos;s configs:</p>
<p>Here is an example of what an Alfred config looks like:</p>
<pre><code class="language-json">// package.json
{
  // ...
  &quot;alfred&quot;: {
    &quot;skills&quot;: [
      [
        &quot;@alfred/skill-eslint&quot;,
		// A which extends the generated config
        {
          &quot;extends&quot;: [&quot;eslint-config-airbnb&quot;],
          &quot;rules&quot;: {
            &quot;no-console&quot;: &quot;off&quot;
		  }
        }
      ]
    ]
  }
}
</code></pre>
<h4 id="entrypoints">Entrypoints</h4>
<p>Alfred formalizes the concept of <em><a href="https://alfred.js.org/docs/concepts#entrypoints">entrypoints</a></em>, which are files that determine the project type and platform a project will run on. For example, the entrypoint <code>src/app.browser.js</code> will be built as a browser app, app being the project type and &apos;browser&apos; being the platform. Entrypoints determine which skills should be used to act on the entrypoint for a specific subcommand. Running the <code>build</code> subcommand on a project that has a <code>./src/lib.browser.js</code> entrypoint should build the entrypoint with <a href="https://rollupjs.org/">rollup</a>, a bundler that is optimal for libraries.</p>
<p>Skills can declare which project types, platforms, and environments they support. Here&apos;s how the <a href="https://parceljs.org/">parcel</a> skill defines which environments, platforms, and projects it supports:</p>
<pre><code class="language-js">const supports = {
  envs: [&quot;production&quot;, &quot;development&quot;, &quot;test&quot;],
  platforms: [&quot;browser&quot;, &quot;node&quot;],
  projects: [&quot;lib&quot;]
};

export default {
  name: &quot;rollup&quot;,
  tasks: [
    [&quot;@alfred/task-build&quot;, { supports }],
    [&quot;@alfred/task-start&quot;, { supports }]
  ],
  // ...
};
</code></pre>
<h4 id="tasks">Tasks</h4>
<p><a href="https://alfred.js.org/docs/tasks"><em>Tasks</em></a> determine which skill should be used when a certain subcommand is called. For example, when <code>alfred run build</code> is called, either the parcel, webpack, or rollup skill could be used. They also specify how skills are called and provide information about the task. Below is an example of a task:</p>
<pre><code class="language-js">// @alfred/task-build
export default {
  subcommand: &quot;build&quot;,
  description: &quot;Build, optimize, and bundle assets in your app&quot;,
  runForEachTarget: true,
  resolveSkill(skills, target) {
    // return whichever skill you want to resolve...
  }
};
</code></pre>
<p>Skills can then implement certain tasks:</p>
<pre><code class="language-js">export default {
  name: &quot;parcel&quot;,
  tasks: [&quot;@alfred/task-build&quot;, &quot;@alfred/task-start&quot;],
  // ...
};
</code></pre>
<p>Tasks allow for skills to be interchanged while maintaining a consistent developer workflow. For example, all skills that lint a user&#x2019;s project will use the <code>@alfred/task-lint</code> task so all of these skills are invoked through the <code>lint</code> subcommand that the task registers.</p>
<p>Alfred comes with the following tasks built-in: <code>build</code>, <code>start</code>, <code>lint</code>, <code>format</code>, and <code>test</code>.</p>
<h4 id="filesanddirectories">Files and Directories</h4>
<p>Sometimes, adding or changing configuration may not be enough to add support for a certain tool or library. <a href="https://redux.js.org/">Redux</a>, for example, requires <code>configureStore.js</code>, <code>root.js</code>, and other files. To allow skills to fully add out of the box support for tools they wrap, Alfred allows them to define <a href="https://alfred.js.org/docs/files-and-directories">files and directories</a> which are added to the user&apos;s project. Similar to configs, <em>files</em> can also be modified by skill <em>transforms</em>. Below is an example of how the redux skill transforms the <code>configureStore.prod.js</code> file to be compatible with typescript:</p>
<pre><code class="language-js">export default {
  name: &quot;redux&quot;,
  files: [
    {
      alias: &quot;configureStore.prod&quot;,
      src: path.join(__dirname, &quot;../boilerplate/store/configureStore.prod.js&quot;),
      dest: &quot;src/store/configureStore.prod.js&quot;
    }
    // ...
  ],
  transforms: {
    typescript(skill) {
      skill.files
        .get(&quot;configureStore.prod&quot;)
        .rename(&quot;configureStore.prod.ts&quot;)
        .applyDiff(
`@@ -12 +12 @@
-function configureStore(initialState) {
-  return createStore(rootReducer, initialState, enhancer);
+function configureStore(initialState?: State): Store {
+  return createStore(rootReducer, initialState, enhancer);`
        );
      return skill;
    }
  }
};
</code></pre>
<p>Files can be transformed by either applying <a href="https://en.wikipedia.org/wiki/Diff#Unified_format">diffs</a> to files or by replacing strings that match a regular expression.</p>
<h1 id="gettingstartedwithalfred">Getting Started with Alfred</h1>
<p>To get started with alfred,</p>
<pre><code class="language-bash"># Create a new project
npx alfred new my-project
cd my-project

# Build your project
npx alfred run build
</code></pre>
<p>Here is an example of what an Alfred config looks like:</p>
<pre><code class="language-json">// package.json
{
  // ...
  &quot;alfred&quot;: {
    // Extend a shared Alfred config
    &quot;extends&quot;: &quot;alfred-config-web-app&quot;,
    // 3rd party skills the project uses
    &quot;skills&quot;: [&quot;@alfred/skill-react&quot;],
    // The package manager to be used
    &quot;npmClient&quot;: &quot;yarn&quot;
  }
}
</code></pre>
<p>For more details on how to use Alfred, <a href="https://alfred.js.org/docs/getting-started">see the docs</a>.</p>
<h4 id="directorystructure">Directory Structure</h4>
<p>The following is an example of the directory structure of an Alfred browser app project:</p>
<pre><code>my-project/
&#x251C;&#x2500;&#x2500; .gitignore
&#x251C;&#x2500;&#x2500; README.md
&#x251C;&#x2500;&#x2500; src/
&#x2502;   &#x2514;&#x2500;&#x2500; app.browser.js
&#x251C;&#x2500;&#x2500; targets/
&#x2502;   &#x2514;&#x2500;&#x2500; app.browser.dev/
&#x2502;        &#x2514;&#x2500;&#x2500; index.js
&#x2502;   &#x2514;&#x2500;&#x2500; app.browser.prod/
&#x2502;        &#x2514;&#x2500;&#x2500; index.js
&#x2514;&#x2500;&#x2500; package.json
</code></pre>
<h1 id="excitingopportunities">Exciting Opportunities</h1>
<p>Alfred creates some exciting new oppertunities for workflows and tooling integration. Expect to see the oppertunities below in future releases!</p>
<h4 id="entrypointspecificcommands">Entrypoint specific commands</h4>
<p>Sometimes, it is useful to run subcommands for a specific entrypoint. Alfred will allow user&apos;s to do so through the CLI:</p>
<pre><code class="language-bash"># Building a specific entrypoint
alfred entrypoint lib.browser run build

# Building all app entrypoints
alfred entrypoint app.* run build
</code></pre>
<p>This will make maintaining apps with multiple entrypoints much easier.</p>
<h4 id="publishingdeployingwithalfred">Publishing/Deploying with Alfred</h4>
<p>Alfred integration with publishing and deploying can significantly simplify the deployment process for many web developers. Ideally, developers can deploy to their platform of choice just by learning a skill:</p>
<pre><code class="language-bash"># Publishing a specific entrypoint
# By default, libs and node apps are published to npm registry
alfred entrypoint lib.browser run publish

# Publish all entrypoints
alfred run publish

# Publishing all app entrypoints
alfred entrypoint app.* run publish

# Publish app to GitHub Pages
alfred learn @alfred/skill-github-pages
alfred entrypoint app.browser run publish

# Publish app to Now
alfred learn @alfred/skill-now
alfred entrypoints app.browser app.node run publish
</code></pre>
<h4 id="documentationtooling">Documentation Tooling</h4>
<p>It can be said that one of the most undervalued pieces of JS tooling is its documentation tooling. There is much to be learned from the success of <a href="https://docs.rs">docs.rs</a>, the standard for documentation generation for <a href="https://rust-lang.org">Rust</a>. A JS equivalent of <a href="https://docs.rs">docs.rs</a> might be of much use to the JS ecosystem.</p>
<h4 id="pluginsforalfred">Plugins for Alfred</h4>
<p>It is very common for JS tools to allow plugins to add extra functionality to tools. Take, for example, a simple rollup plugin that prints the sizes of chunks after bundling:</p>
<p><img src="https://amilajack.com/content/images/2020/03/9c0KN6W.png" alt="Alfred - A Modular Toolchain for JavaScript" loading="lazy"></p>
<p>A useful plugin indeed! But if we want to use this plugin across all our bundlers of all our entrypoints (parcel or webpack if you have an app entrypoint) we would need to create a new plugin for both webpack and parcel.</p>
<p>Alfred can reduce the duplication of plugins with skills and tasks. Skills can return metadata from the tools they wrap. Tasks can provide an interface which skills should conform their metadata responses to.</p>
<p>Here is an example of what a task may look like:</p>
<pre><code class="language-js">// @alfred/task-build
export default {
  subcommand: &quot;build&quot;,
  description: &quot;Build, optimize, and bundle assets in your app&quot;,
  runForEachTarget: true,
  resolveSkill(skills, target) {
    // return whichever skill you want to resolve...
  },
  metadataInterface: {
    ast: type.object,
    output: type.array.of(type.string)
  }
};
</code></pre>
<p>Below is an example of a skill that takes rollup&apos;s AST and return an object that conforms to the interface defined by the task.</p>
<pre><code class="language-js">// @alfred/skill-rollup
export default {
  name: &quot;rollup&quot;,
  tasks: [&quot;@alfred/task-build&quot;],
  // ...
  metadata(rollupAst) {
    // ...
    return {
      ast: {...},
      outputs: [...]
    };
  }
};
</code></pre>
<p>A plugin can now receive this metadata from any skill that uses the <code>build</code> task:</p>
<pre><code class="language-js">// @alfred/plugin-size
export default {
  name: &quot;size&quot;,
  hooks: {
    afterBuild({ metadata }) {
      const outputSizes =
        metadata.outputs.map(output =&gt;
          `${output.name} size: ${output.size}`
        );
      console.log(outputSizes);
    }
  }
}
</code></pre>
<h4 id="sharedasts">Shared ASTs</h4>
<p>Sharing AST&apos;s between tools is an interesting area for investigation that can provide significantly improve the quality of JS tooling. This can improve the performance and developer experience of all JS tooling. <a href="https://romejs.dev/">Rome</a> is already doing this!</p>
<h1 id="acknowledgements">Acknowledgements</h1>
<h4 id="priorart">Prior Art</h4>
<ul>
<li><a href="https://github.com/rust-lang/cargo">Cargo</a></li>
<li><a href="https://npmjs.org">NPM</a>, <a href="https://yarnpkg.com">Yarn</a></li>
<li><a href="http://yeoman.io">Yeoman</a></li>
<li><a href="http://romejs.dev">Rome</a></li>
<li><a href="https://github.com/facebook/create-react-app">create-react-app</a></li>
<li><a href="https://www.github.com/react-boilerplate/react-boilerplate">react-boilerplate</a>, <a href="https://www.github.com/electron-react-boilerplate/electron-react-boilerplate">electron-react-boilerplate</a>, and <a href="https://github.com/search?q=boilerplate">many many other boilerplates</a></li>
</ul>
<h4 id="inspiration">Inspiration</h4>
<ul>
<li><a href="https://parceljs.org">parcel</a></li>
<li><a href="https://docker.com">docker</a></li>
<li><a href="https://elm-lang.org">elm</a></li>
<li><a href="https://github.com/rust-lang/cargo">Cargo</a></li>
<li><a href="https://yarnpkg.com">Yarn</a></li>
<li><a href="https://github.com/survivejs/webpack-merge">webpack-merge</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Finding the Browser Support for All Web APIs]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Ensuring browser compatibility of apps is an ongoing concern among browser developers. It is common for web apps to be required to run on multiple browsers.</p>
<h2 id="understandingtheproblem">Understanding the Problem</h2>
<p>It is very common for businesses to require that their app works on certain browsers. Facebook, for example, requires that a</p>]]></description><link>https://amilajack.com/compat-db/</link><guid isPermaLink="false">5e0554bfa2380f5b95ecd086</guid><category><![CDATA[compat-db]]></category><category><![CDATA[infrastructure]]></category><category><![CDATA[tooling]]></category><category><![CDATA[eslint-plugin-compat]]></category><category><![CDATA[browser]]></category><category><![CDATA[compatibility]]></category><category><![CDATA[static-analysis]]></category><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Sun, 28 Apr 2019 18:34:27 GMT</pubDate><media:content url="https://amilajack.com/content/images/2019/04/Screen-Shot-2019-04-27-at-1.06.29-PM-1.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://amilajack.com/content/images/2019/04/Screen-Shot-2019-04-27-at-1.06.29-PM-1.png" alt="Finding the Browser Support for All Web APIs"><p>Ensuring browser compatibility of apps is an ongoing concern among browser developers. It is common for web apps to be required to run on multiple browsers.</p>
<h2 id="understandingtheproblem">Understanding the Problem</h2>
<p>It is very common for businesses to require that their app works on certain browsers. Facebook, for example, requires that a version of their web app should still work on Internet Explorer, a browser known for its gaping holes in browser API support. Enforcing this requirement is met by testing the app on different browsers but doing so usually introduces development overhead because it requires tests to be written and time for the tests to be run.</p>
<p>In place of tests, it is common for developers to reference compatibility tables, which are tables which list all the browsers a given API is supported in. However many of these tables are either incomplete or non-existent for certain APIs because they are manually filled in by developers, which is not easy. There are roughly 10K APIs and 131 variants of browsers, which amounts to 1,310,000 API compatibility entries that must be filled in. Compatibility records are maintained by two projects: <a href="https://developer.mozilla.org/en-US/">Mozilla Developer Network (MDN)</a> and <a href="http://caniuse.com">caniuse</a>.</p>
<h2 id="mdn">MDN</h2>
<p>Examples of unknown API records:</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch"><img src="https://amilajack.com/content/images/2019/04/Screen-Shot-2019-04-27-at-1.06.29-PM.png" alt="Finding the Browser Support for All Web APIs" loading="lazy"></a></p>
<h2 id="caniuse">caniuse</h2>
<p><a href="https://github.com/Fyrd/caniuse/issues">caniuse</a> is the most complete collection of these API compatibility records. But this solution is difficult to scale. With a limited amount of developers with limited time and resources, it is difficult to maintain a table with thousands of records.</p>
<p>As you can see, caniuse has over <a href="https://github.com/Fyrd/caniuse/issues">1K issues</a> and <a href="https://github.com/Fyrd/caniuse/graphs/contributors">only one active maintainer</a> to address them.</p>
<p><a href="https://github.com/Fyrd/caniuse/issues"><img src="https://amilajack.com/content/images/2019/04/Screen-Shot-2019-04-27-at-1.30.33-PM.png" alt="Finding the Browser Support for All Web APIs" loading="lazy"></a></p>
<p>Furthermore, developers manually checking a compatibility table isn&apos;t a scalable solution for handling browser compatibility inconsistencies. <code>caniuse</code> provides no scalable solution for integrating with existing static analysis (i.e. code analysis) tools.</p>
<h2 id="proposedsolutioncompatdb">proposed solution: compat-db</h2>
<p><a href="https://github.com/amilajack/compat-db"><strong>compat-db</strong></a> is a project that automates the generation of compatibility records of APIs. It takes APIs as input and return compatibility records as output. To generate all the browser compatibility records, it is given all the standard browser APIs as input and it returns all the corresponding compatibility records.</p>
<h3 id="inputwebidl">Input: WebIDL</h3>
<p>APIs are defined with a special language called <a href="https://developer.mozilla.org/en-US/docs/Mozilla/WebIDL_bindings">WebIDL</a>. API authors write the specification for APIs in the form of <a href="https://developer.mozilla.org/en-US/docs/Mozilla/WebIDL_bindings">WebIDL</a>, a language which specifies the interface of the API. Here&apos;s an example of WebIDL corresponding to the <a href="https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder/encodeInto">TextEncoder.encodeInto</a> API:</p>
<pre><code>dictionary TextEncoderEncodeIntoResult {
  unsigned long long read;
  unsigned long long written;
};

[Constructor]
interface TextEncoder {
  TextEncoderEncodeIntoResult encodeInto(USVString source, Uint8Array destination);
};
</code></pre>
<p>JavaScript tests are generated from the WebIDL.</p>
<p>Here is a simplified version of the corresponding compatibility tests that are generated from the <a href="https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder/encodeInto">TextEncoder.encodeInto</a> API WebIDL example above:</p>
<pre><code class="language-javascript">if (typeof TextEncoder === &apos;undefined&apos;) {
  return false;
}

if (typeof TextEncoder.encodeInto === &apos;undefined&apos;) {
  return false;
}

if (typeof TextEncoder.encodeInto === &apos;function&apos;) {
  return false;
}

return true;
</code></pre>
<h2 id="determiningcompatibilitybrowservms">Determining Compatibility: Browser VMs</h2>
<p>The next step is to run these generated compatibility tests in each browser. This is done by dispatching the tests to run in remote browsers where it is then evaluated. These browsers are hosted by a number of services, including <a href="http://browserstack.com">browserstack</a> and <a href="http://saucelabs.com">saucelabs</a>. The results of the evaluated tests are then returned as responses to compat-db.</p>
<h2 id="performanceconsiderations">Performance Considerations</h2>
<h3 id="naiveimplementation">Naive implementation</h3>
<p>The naive implementation would need to run tests for <strong>every version</strong> of <strong>every browser</strong> for <strong>every API</strong> in order to build a complete compatibility table.</p>
<pre><code class="language-javascript">for (const API of APIs) {
  for (const browser of browsers) {
    for (const version of browser.versions) {
      dispatchCompatTest(API, version);
    }
  }
}
</code></pre>
<p>This algorithm is an <code>O(m * n)</code> algorithm, where <code>m</code> is the number of APIs that are tested and <code>n</code> is the total number of browser versions that are tested.</p>
<p>There are 10K API&apos;s, and 131 versions of all the browsers:</p>
<table>
<thead>
<tr>
<th>Browser</th>
<th># of Versions</th>
</tr>
</thead>
<tbody>
<tr>
<td>chrome</td>
<td>50</td>
</tr>
<tr>
<td>Firefox</td>
<td>50</td>
</tr>
<tr>
<td>safari</td>
<td>10</td>
</tr>
<tr>
<td>edge</td>
<td>10</td>
</tr>
<tr>
<td>ie</td>
<td>11</td>
</tr>
</tbody>
</table>
<p>Summing the total number of browser versions, we get 131 total versions.</p>
<p>The naive method would require $$10,000*131=1,310,000$$ tests &#x1F631;.</p>
<h3 id="optimizations">Optimizations</h3>
<p>We can observe some certain browser heuristics to reduce the number of tests required to build a complete compatibility table. Once a browser implements an API, it cannot be taken out. This is a general principle web browsers follow because they can&apos;t &quot;break the web&quot;. If a browser yanks a previously supported API then it will break pages that depended on that API existing in that browser. APIs are deprecated but never removed (only in some extremely rare scenarios i.e. <code>SharedArrayBuffer</code>).</p>
<p>Using this heuristic, we run a modification that finds the first version of a browser that supports a given API. The algorithm almost identical to binary search: look at the sorted versions of any given browser.</p>
<p>Consider the example sorted versions of a browser:</p>
<pre><code>[12, 14, 16, 18, 22]
</code></pre>
<p>If we execute compatibility tests against the &quot;middle&quot; version (16 in this example) of the browser and they return <code>false</code> then we know all the previous versions of that browser must not have had that API implemented before. So we look at the versions &quot;right&quot; of the &quot;middle&quot; version: <code>[18, 22]</code> and then recursively perform the previous operation.</p>
<p>This can be done in <code>O(m * log n)</code> time for one browser where <code>n</code> is the number of versions of a browser and <code>m</code> is the number of APIs that need to be tested.</p>
<p>When determining the runtime for all the browers we need to make some changes. First we&apos;ll create a list of all the browser versions and then sum over it:</p>
<p>$$ \sum_{i=0}^{|x|} m * log x_i = m * \sum_{i=0}^{|x|} log x_i = 64,393$$</p>
<p>This brings down our initial number of tests from 1,310,000 to 64,393, a <strong>95% drop in the number of tests needed</strong> to determine the browser compatibility of all APIs.</p>
<h2 id="usecasesforcompatdb">Use cases for compat-db</h2>
<p>The future of compat-db includes integration with static analysis tools, like the following projects.</p>
<h4 id="staticanalysis">Static Analysis</h4>
<p><a href="https://github.com/amilajack/eslint-plugin-compat">eslint-plugin-compat</a>, an ESLint plugin which lints the compatibility of JavaScript code. Here&apos;s an example of it in use:</p>
<p><img src="https://amilajack.com/content/images/2019/04/eslint-plugin-compat-demo.gif" alt="Finding the Browser Support for All Web APIs" loading="lazy"></p>
<p>compat-db will serve as the source which contains the compatibility records which <a href="https://github.com/amilajack/eslint-plugin-compat">eslint-plugin-compat</a> refers to for API compatibility lookups.</p>
<h4 id="automaticallyincludingpolyfillsandshims">Automatically Including Polyfills and Shims</h4>
<p>Polyfills and shims are pieces of code which implement an API if it is not supported by the runtime. For example, if chrome does not support the <code>fetch</code> API then a polyfill for it would implement that function using native JavaScript.</p>
<p>At the time of writing, there is no way of automatically including the necessary polyfills or shims for a codebase given a list of target browsers. Library authors include polyfills for their libraries with the intention of simplifying the process of using libraries. This way, library consumers do not have to worry about including polyfills themselves. However, this comes at the cost of bloating sizes of apps and libraries which consume these libraries.</p>
<p>An ideal solution, now made possible with compat-db, is iterating through every API used, check compat-db to see if it is supported by the browsers the user is targeting, and then append the polyfills to the user&apos;s build. This solution, which should be used only in the context of apps as opposed to libraries, ensures that only the necessary polyfills and shims are included in the compiled output of apps.</p>
<h2 id="theproject">The Project</h2>
<p>compat-db is <a href="https://github.com/amilajack/compat-db">hosted on GitHub</a>. I&apos;m actively looking for contributors so let me know if you&apos;re interested in contributing! There&apos;s some work that needs to be done to make compat-db production ready.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[The Languages of Mathematics]]></title><description><![CDATA[<p>Mathematics is a language through which we express our understanding of the world. With this in mind, I have created an ongoing list of the ideas captured by fields of mathematics.</p><ul><li>Calculus and Differential Equations: Language of <strong>change</strong></li><li>Graph Theory: Language of <strong>relationships</strong></li><li>Linear Algebra: Language of <strong>systems</strong></li><li>Probability: Language</li></ul>]]></description><link>https://amilajack.com/the-languages-of-mathematics/</link><guid isPermaLink="false">5e0554bfa2380f5b95ecd085</guid><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Tue, 16 Apr 2019 02:46:01 GMT</pubDate><content:encoded><![CDATA[<p>Mathematics is a language through which we express our understanding of the world. With this in mind, I have created an ongoing list of the ideas captured by fields of mathematics.</p><ul><li>Calculus and Differential Equations: Language of <strong>change</strong></li><li>Graph Theory: Language of <strong>relationships</strong></li><li>Linear Algebra: Language of <strong>systems</strong></li><li>Probability: Language of the <strong>future</strong></li><li>Statistics: Language of the <strong>past</strong></li><li>Logic: Language of <strong>truth</strong></li><li>Chaos Theory: Language of <strong>perturbation</strong></li><li>Game Theory: Language of <strong>decisions</strong></li><li>Combinatorics: Language of <strong>counting</strong></li><li>Algebra: Language of <strong>classification, structure, and properties</strong></li></ul>]]></content:encoded></item><item><title><![CDATA[My Heroes]]></title><description><![CDATA[<p>An ongoing list of my heroes (in no order)</p><p>I believe everyone has something to teach me. This is a list of people who have made the most significant influence on me.<br></p><!--kg-card-begin: markdown--><ul>
<li>Martin Luther King</li>
<li>Richard Feynmann</li>
<li>Carl Sagan</li>
<li>My brother</li>
<li>Henry David Thoreau</li>
<li>Yan Zhang (One of my discrete</li></ul>]]></description><link>https://amilajack.com/my-heros/</link><guid isPermaLink="false">5e0554bfa2380f5b95ecd084</guid><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Thu, 11 Apr 2019 19:06:43 GMT</pubDate><media:content url="https://amilajack.com/content/images/2019/04/2017-11-20-assemblea-nazionale-fit.png" medium="image"/><content:encoded><![CDATA[<img src="https://amilajack.com/content/images/2019/04/2017-11-20-assemblea-nazionale-fit.png" alt="My Heroes"><p>An ongoing list of my heroes (in no order)</p><p>I believe everyone has something to teach me. This is a list of people who have made the most significant influence on me.<br></p><!--kg-card-begin: markdown--><ul>
<li>Martin Luther King</li>
<li>Richard Feynmann</li>
<li>Carl Sagan</li>
<li>My brother</li>
<li>Henry David Thoreau</li>
<li>Yan Zhang (One of my discrete math teachers)</li>
<li>Jean-Paul Sartre</li>
<li>Steve Jobs</li>
<li>Christy Hallford (my English teacher)</li>
<li>Naval Ravikant</li>
<li>Paul Graham</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[eslint-plugin-compat]]></title><description><![CDATA[<p><a href="https://github.com/amilajack/eslint-plugin-compat">eslint-plugin-compat</a> is an open source static analyzer that lints the compatability of your JS code.<br></p><p>Here is a short demo:<br></p><!--kg-card-begin: markdown--><p><img src="https://raw.githubusercontent.com/amilajack/eslint-plugin-compat/master/img/eslint-plugin-compat-demo.gif" alt="demo" loading="lazy"></p>
<!--kg-card-end: markdown--><h2 id="inspiration">Inspiration</h2><p>The idea for this project was inspired by toolchains for native platforms, like iOS and Android. They&apos;ve had API linting from the start. It&apos;s about</p>]]></description><link>https://amilajack.com/eslint-plugin-compat/</link><guid isPermaLink="false">5e0554bfa2380f5b95ecd082</guid><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Wed, 23 Jan 2019 02:37:52 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://github.com/amilajack/eslint-plugin-compat">eslint-plugin-compat</a> is an open source static analyzer that lints the compatability of your JS code.<br></p><p>Here is a short demo:<br></p><!--kg-card-begin: markdown--><p><img src="https://raw.githubusercontent.com/amilajack/eslint-plugin-compat/master/img/eslint-plugin-compat-demo.gif" alt="demo" loading="lazy"></p>
<!--kg-card-end: markdown--><h2 id="inspiration">Inspiration</h2><p>The idea for this project was inspired by toolchains for native platforms, like iOS and Android. They&apos;ve had API linting from the start. It&apos;s about time that the web had similar tooling.</p><p>This project was inspired by a two hour conversation I had with someone on the experience of web development and if it is terrible or not. The premise they argued was that <code>x</code> browser doesn&apos;t support <code>y</code> feature while <code>z</code> browser does. Eventually, I agreed with him on this and checked made this plugin to save web developers from having to memorize browser compatibility of specs.</p>]]></content:encoded></item><item><title><![CDATA[Falcon - A Modern, Cross Platform Database Client]]></title><description><![CDATA[Falcon is an open source, cross-platform database client that focuses on performance, extensibility, and data visualization]]></description><link>https://amilajack.com/falcon/</link><guid isPermaLink="false">5e0554bfa2380f5b95ecd07d</guid><category><![CDATA[open source]]></category><category><![CDATA[falcon]]></category><category><![CDATA[database]]></category><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Wed, 23 Jan 2019 02:05:54 GMT</pubDate><media:content url="https://amilajack.com/content/images/2019/01/falcon-demo-1.png" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://amilajack.com/content/images/2019/01/falcon-demo-1.png" alt="Falcon - A Modern, Cross Platform Database Client"><p>I have recently open sourced <a href="http://github.com/falcon-client/falcon">Falcon</a>.</p>
<h2 id="whatisfalcon">What is Falcon?</h2>
<p>Falcon is a modern, cross-platform SQLite database client. It is in a very experimental stages at the moment.</p>
<p><img src="https://amilajack.com/content/images/2019/01/falcon-demo.png" alt="Falcon - A Modern, Cross Platform Database Client" loading="lazy"></p>
<h2 id="whyanotherdatabaseclient">Why another database client?</h2>
<ol>
<li>A lot of databases feel dated since they don&apos;t support modern features</li>
<li>Bad performance, use legacy java cross-platform gui&apos;s</li>
<li>Platform dependent. The best clients are only for macOS</li>
<li>Most clients are not extensible/pluggable</li>
<li>Most clients are specific to a certain database</li>
<li>Current clients only show data. They don&apos;t help explain what it means</li>
</ol>
<h2 id="future">Future</h2>
<ol>
<li>
<p>Add support for other database clients<br>
Adding support for MSSQL, MYSQL, PostgreSQL, Mongo, and other clients will be a high priority after pushing an initial stable version of the client.</p>
</li>
<li>
<p>Add plugin support<br>
Editors such as VSCode, Atom, and Hyper have seen huge successes because they allow developers to install plugins which can be written in Node. This allows users more fine grained control over their own experience and ability.</p>
</li>
</ol>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Project Ideas]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>This is an ongoing blog post that lists project ideas I am thinking of working on. If you are interested on working on any one of these ideas with me, feel free to reach out to me!</p>
<hr>
<h6 id="legend">Legend</h6>
<ul>
<li>&#x2615;&#xFE0F;: Small/Easy Project</li>
<li>&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;: Large/</li></ul>]]></description><link>https://amilajack.com/project-ideas/</link><guid isPermaLink="false">5e0554bfa2380f5b95ecd079</guid><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Wed, 16 Jan 2019 00:20:30 GMT</pubDate><media:content url="https://amilajack.com/content/images/2019/01/rawpixel-579231-unsplash.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://amilajack.com/content/images/2019/01/rawpixel-579231-unsplash.jpg" alt="Project Ideas"><p>This is an ongoing blog post that lists project ideas I am thinking of working on. If you are interested on working on any one of these ideas with me, feel free to reach out to me!</p>
<hr>
<h6 id="legend">Legend</h6>
<ul>
<li>&#x2615;&#xFE0F;: Small/Easy Project</li>
<li>&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;: Large/Difficult Project</li>
<li>&#x2705;: MVP Shipped</li>
<li>&#x1F528;: In Progress</li>
<li>&#x274C;: Not Yet Started</li>
</ul>
<h3 id="anycast">&#x1F528; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F; any-cast</h3>
<ul>
<li>Cast audio or video to any device with one API</li>
</ul>
<hr>
<h3 id="compatdb">&#x1F528; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F; compat-db</h3>
<ul>
<li>An automated browser compatibility database</li>
<li>Runs type checks on browser&apos;s to determine if API&apos;s are defined</li>
<li>Another way is by running w3c tests on each browser and checking if they pass.</li>
<li>Use the <a href="https://developer.microsoft.com/en-us/microsoft-edge/platform/catalog/">Microsoft API Catalog</a> for API&apos;s to be type-checked</li>
<li>Determine if an API can be polyfilled which API&apos;s can be polyfilled
<ul>
<li>This can be done by adding a property of <code>polyfillable: bool</code> to each spec record</li>
</ul>
</li>
</ul>
<hr>
<h3 id="vrperspectiveseatexperiment">VR Perspective Seat Experiment &#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;</h3>
<ul>
<li>What
<ul>
<li>Take <a href="https://tympanus.net/Development/SeatPreview/">Codrops&apos; Perspective Seat Preview</a> and create a VR experience out of it</li>
<li>Possible integrate this experience into popcorn time desktop</li>
</ul>
</li>
<li>How:
<ul>
<li>Experiment with WebVR to seem if a WebVR implementation is possible</li>
</ul>
</li>
</ul>
<h3 id="pagerank">Pagerank &#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;</h3>
<hr>
<h3 id="graphdrawer">Graph Drawer &#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F;</h3>
<ul>
<li>What:
<ul>
<li>A general purpose API that can draw graphs. This is intended to be used by falcon</li>
<li>Allow drawing graphs like those in game engines</li>
<li><img src="https://amilajack.com/content/images/2018/05/68747470733a2f2f666f72756d2e756e6974792e636f6d2f70726f78792e7068703f696d6167653d68747470732533412532462532466c68352e676f6f676c6575736572636f6e74656e742e636f6d25324655684231385565685a466b386a4d6f5f32563347572d68443277415241635157753646477a63.png" alt="Project Ideas" loading="lazy"></li>
<li><img src="https://amilajack.com/content/images/2018/05/68747470733a2f2f7261772e6769746875622e636f6d2f756e636f6e65642f73686164657267726170682f6d61737465722f646f63732f696d616765732f726571756972652e706e67.png" alt="Project Ideas" loading="lazy"></li>
<li><img src="https://amilajack.com/content/images/2018/05/Screen-Shot-2018-05-23-at-5.00.49-PM.png" alt="Project Ideas" loading="lazy"></li>
</ul>
</li>
</ul>
<p><img src="https://amilajack.com/content/images/2018/06/samples.png" alt="Project Ideas" loading="lazy"></p>
<h3 id="studyrooms">Study Rooms &#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;</h3>
<p><img src="https://amilajack.com/content/images/2018/05/Screen-Shot-2018-05-25-at-9.24.57-PM.png" alt="Project Ideas" loading="lazy"></p>
<ul>
<li>What:
<ul>
<li>Mimic great study environments</li>
<li>Play sounds that match that environment</li>
<li>The app is meant to be played on a screen (laptop or monitor) while they study
<ul>
<li>This is similar to a lot of asmr (asmr rooms and others)</li>
</ul>
</li>
<li>Sounds
<ul>
<li>Merging sounds together like Noizio</li>
<li>Example Sounds
<ul>
<li>Chatter sounds</li>
<li>Rain</li>
<li>Thunder</li>
<li>Space</li>
<li>Cabin forest</li>
<li>Cabin snow</li>
<li>Etc...</li>
</ul>
</li>
</ul>
</li>
<li>Environments
<ul>
<li>Will be from many different places, some fictional and some real</li>
<li>Will have people moving around in them.</li>
<li>The music and sounds of the environments should match real life
<ul>
<li>Example: A coffee shop would have jazz playing in the backround</li>
</ul>
</li>
<li>The goal is to be as realistic as possible with the environments</li>
<li>The time of day in real life should match the time in the environment</li>
<li>Examples of environments
<ul>
<li>Stormy cathedral</li>
<li>Coffee shops</li>
<li>Lord of the rings bar</li>
<li>Libraries</li>
<li>Small cabin</li>
<li><a href="https://www.homeanddesign.com/2015/08/26/writers-refuge">Writer&apos;s Refuge</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>How:
<ul>
<li>Models
<ul>
<li>Take models from sketchfab</li>
<li>Also generate own models</li>
</ul>
</li>
<li>Sound
<ul>
<li>Go to similar places in real life and record those environments</li>
<li>Sounds can be taken from soundcloud or youtube (using their api&apos;s)</li>
</ul>
</li>
<li>Graphics Performance
<ul>
<li>This will be difficult on low end laptops</li>
<li>We can detect if a laptop is</li>
<li>For low end</li>
</ul>
</li>
<li>Infra:
<ul>
<li>App will be served over github pages</li>
<li>Will use https</li>
<li>Will use service worker to cache textures</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h3 id="extensiblejstypechecker">&#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F; Extensible JS Type Checker</h3>
<p><strong>Inspired by:</strong></p>
<ul>
<li><a href="https://cstheory.stackexchange.com/questions/22117/language-with-extensible-type-system">https://cstheory.stackexchange.com/questions/22117/language-with-extensible-type-system</a></li>
<li>Create a type system for JS and allow plugins to extend it</li>
</ul>
<hr>
<h3 id="warnnonuicritical">&#x274C; warn-non-ui-critical</h3>
<ul>
<li>iOS and Android native platforms, for example, restrict (by default) the usage of any APIs not critical to UI manipulation on the main thread. (from <a href="https://github.com/GoogleChromeLabs/tasklets">tasklet</a>)</li>
<li>Make a static analyzer that can warn when using APIs not critical for UI</li>
</ul>
<h3 id="prettyprinterrors">&#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F; pretty-print-errors</h3>
<ul>
<li>Should have browser console fallback</li>
<li>Source map support</li>
<li>Automatic script blackboxing</li>
<li>Path <code>Error.prototype.toString</code></li>
<li>Use project root as root of errors: <code>Error in &apos;project-root/foo/bar.js&apos;</code></li>
<li>Lower opacity of code that does not error</li>
<li>Show line numbers</li>
<li>Highlight rows with errors</li>
<li>Use like <code>babel-polyfill</code>, <code>babel-node -r pretty-print-errors some.js</code></li>
</ul>
<p><strong>Inspired by:</strong></p>
<ul>
<li><a href="https://github.com/sindresorhus/eslint-formatter-pretty">eslint-formatter-pretty</a></li>
<li><a href="https://github.com/filp/whoops">Laravel &apos;Woops&apos; Errors</a> <strong><a href="http://filp.github.io/whoops/demo/">demo</a></strong></li>
<li><a href="https://github.com/AriaMinaei/pretty-error">pretty-error</a></li>
<li><a href="https://github.com/Qix-/better-exceptions">better-exceptions</a></li>
<li><a href="https://github.com/AndreasMadsen/clarify">clarify</a></li>
</ul>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr"><a href="https://twitter.com/emberjs">@emberjs</a> I&apos;m loving the new error messages in Ember 2.15! <a href="https://t.co/TYrtPLlOKc">pic.twitter.com/TYrtPLlOKc</a></p>&#x2014; Jordan Vincent (@jordan_vinc) <a href="https://twitter.com/jordan_vinc/status/911391396229083136">September 23, 2017</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p><img src="https://amilajack.com/content/images/2020/04/EWtPNVYWoAEYLQA.jpeg" alt="Project Ideas" loading="lazy"></p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Making my stack traces a little more readable with a quick regex and some CSS line height <a href="https://t.co/AvivrDHIAt">pic.twitter.com/AvivrDHIAt</a></p>&#x2014; Wes Bos (@wesbos) <a href="https://twitter.com/wesbos/status/831958242406367236">February 15, 2017</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<p><strong>Stacktrace Parsing Library</strong></p>
<ul>
<li><a href="https://github.com/felixge/node-stack-trace">https://github.com/felixge/node-stack-trace</a></li>
<li><a href="https://github.com/stacktracejs/stacktrace.js">https://github.com/stacktracejs/stacktrace.js</a></li>
<li><a href="https://www.npmjs.com/package/error-stack-parser">https://www.npmjs.com/package/error-stack-parser</a></li>
</ul>
<p><strong>Some terminal highlighting libraries</strong></p>
<ul>
<li><a href="https://medium.com/@gauntface/pretty-printing-d80639fb8881">https://medium.com/@gauntface/pretty-printing-d80639fb8881</a></li>
<li><a href="https://github.com/chalk/chalk">https://github.com/chalk/chalk</a></li>
<li><a href="https://github.com/thlorenz/cardinal">https://github.com/thlorenz/cardinal</a></li>
<li><a href="https://github.com/mikaelbr/marked-terminal">https://github.com/mikaelbr/marked-terminal</a></li>
<li><a href="https://github.com/dtao/console-highlight">https://github.com/dtao/console-highlight</a></li>
<li><a href="https://github.com/felixfbecker/cli-highlight">https://github.com/felixfbecker/cli-highlight</a></li>
<li><a href="https://github.com/eush77/v8-print-code-highlighter">https://github.com/eush77/v8-print-code-highlighter</a> (not maintained)</li>
</ul>
<p><img src="https://amilajack.com/content/images/2017/03/screen.png" alt="Project Ideas" loading="lazy"></p>
<p><img src="https://raw.githubusercontent.com/amilajack/backward-cpp/master/doc/pretty.png" alt="Project Ideas" loading="lazy"></p>
<p><img src="https://amilajack.com/content/images/2017/04/Version-4-2.jpg" alt="Project Ideas" loading="lazy"></p>
<pre><code class="language-js">const config = {
  blackbox: bool = true,
  root: string = __dirname,
  lineNumbers: bool = true,
  previousLinesCount: number = 5
}
</code></pre>
<p><strong>Research</strong></p>
<ul>
<li>Elm stack trace errors</li>
</ul>
<hr>
<h3 id="stylelintplugincompat">&#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F; stylelint-plugin-compat</h3>
<ul>
<li>Lint css style compatibility by using caniuse db</li>
<li>Check if using autoprefixer. If not, warn if missing prefix</li>
</ul>
<hr>
<h3 id="compatwebpackplugin">&#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F; compat-webpack-plugin</h3>
<ul>
<li>Automatically polyfill browser API&apos;s (ex. <code>fetch()</code>) by using <code>browserlist</code> or <code>babel-env-preset</code> config</li>
<li>Use polyfills from <a href="https://github.com/inexorabletash/polyfill">inexorabletash/polyfill</a></li>
<li>Base off <a href="https://github.com/zloirock/core-js">zloirock/core-js</a></li>
<li>Automatically include polyfills based on <code>browserslist</code> targets. Find necessary polyfills from <code>eslint-plugin-compat</code></li>
<li>Allow for dynamically requiring polyfills to reduce build size. (ex. if 90% of target browsers support feature, force network request instead of polyfill)</li>
<li>Borrow from <a href="https://github.com/Financial-Times/polyfill-service">https://github.com/Financial-Times/polyfill-service</a></li>
</ul>
<hr>
<h3 id="eslintplugindom">&#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F; eslint-plugin-dom</h3>
<ul>
<li>Lint dom API performance, warn of sync layout calc, error on forced reflow</li>
<li>Paul Irish as an eslint rule?</li>
</ul>
<hr>
<h3 id="eslintplugindeps">&#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F; eslint-plugin-deps</h3>
<ul>
<li>Warn on installation/usage of unstable dependency. Determine dependency quality</li>
<li>Use npm-check to determine is depinstalled</li>
<li>Use the new &quot;npm audit&quot;</li>
</ul>
<hr>
<h3 id="compatcheck">&#x274C; &#x2615;&#xFE0F; compat-check</h3>
<p>cli tool used to analyze the build to see if any deprecated or unsupported API&apos;s are being used</p>
<hr>
<h3 id="webpackstrippolyfills">&#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F; webpack-strip-polyfills</h3>
<p>Detect all the supported browsers and remove all the polyfills which are included but will never be used by the targets</p>
<hr>
<h3 id="alfredruntime">&#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F; Alfred Runtime</h3>
<ul>
<li>A linter that can collect runtime errors</li>
<li>Examples: <a href="https://github.com/garbles/why-did-you-update">why-did-you-update</a>: Instead of logging warnings to the console, what if errors could be sent to a server which collects runtime errors and displays them in an interface for the user to see?</li>
</ul>
<hr>
<h3 id="alfredrunner">&#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F; Alfred Runner</h3>
<ul>
<li>Given a list of routes, automate a nightmare/selenium instance to traverse the routes, simulate action, and detect performance weak points/fps drops/memory leaks</li>
<li>Interaction to Simulate
<ul>
<li>Clicks</li>
<li>Route navigation</li>
</ul>
</li>
</ul>
<h3 id="alfredlinter">&#x274C; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F; Alfred Linter</h3>
<ul>
<li>An alternative to ESLint that suggests solutions to errors</li>
<li>Similar to Cargo</li>
</ul>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">- a minifier that does constant folding and inlining<br> - a compiler transforms that don&apos;t rely on order<br> - a compiler that uses an immutable AST to perform transforms, with accurate scope tracking<br> - a linter that gives me suggestions on how to fix my code<br> - ...</p>&#x2014; Sebastian McKenzie (@sebmck) <a href="https://twitter.com/sebmck/status/1063574509272199169?ref_src=twsrc%5Etfw">November 16, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 
<hr>
<h3 id="eslintplugincompat">&#x2705; &#x2615;&#xFE0F;&#x2615;&#xFE0F; eslint-plugin-compat</h3>
<ul>
<li><mark>Allow css-in-js to be linted for CSS compat</mark></li>
<li>Integration with aphrodite, styled-components, react-style, radium, JSS, <a href="http://survivejs.com/react/advanced-techniques/styling-react/">others</a></li>
<li>Each will likely need its own parser. Should be able to detect which css-in-js framework is being used</li>
<li>Integration with CSS preprocessors (ex. <code>autoprefixer</code>)</li>
<li>Determine if an API can be polyfilled which API&apos;s can be polyfilled
<ul>
<li>This can be done by adding a property of <code>polyfillable: bool</code> to each spec record</li>
</ul>
</li>
<li>If <strong>compat-webpack-plugin</strong> detected, fail on <strong>only</strong> non-polyfillable API&apos;s</li>
<li><a href="https://medium.com/@steida/css-in-js-the-argument-refined-471c7eb83955#.szfhfbl3d">Why CSS in JS</a></li>
</ul>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Now, this is a configuration that makes sense to me. Specify browsers once, let Babel and Autoprefixer do the work. <a href="https://t.co/KgOtIyw0wH">https://t.co/KgOtIyw0wH</a> <a href="https://t.co/vVPeECXGY3">pic.twitter.com/vVPeECXGY3</a></p>&#x2014; Dan Abramov (@dan_abramov) <a href="https://twitter.com/dan_abramov/status/808123126403973121">December 12, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">A big advantage of CSS in JS(X): One language (JS), not three (JS, HTML, CSS).<br>One linter. One code style. One type system. One test system.</p>&#x2014; Guillermo Rauch (@rauchg) <a href="https://twitter.com/rauchg/status/802328362341384192">November 26, 2016</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
<h3 id="freesoundnodeclientlibrary">&#x2705; &#x2615;&#xFE0F; FreeSound Node Client Library</h3>
<ul>
<li><a href="https://freesound.org/docs/api/">https://freesound.org/docs/api/</a></li>
<li>Current one is utter trash</li>
<li>Maybe if time permits, we can redo the web interface for <a href="https://freesound.org">https://freesound.org</a> because it&apos;s open source</li>
</ul>
<h3 id="babelpluginfailexplicit">&#x2705; &#x2615;&#xFE0F;&#x2615;&#xFE0F; babel-plugin-fail-explicit</h3>
<p><strong>Force javascript to be stricter in development environment</strong></p>
<blockquote>
<p><strong>Coercion and silent failure are dead. Long live usable JavaScript</strong></p>
</blockquote>
<ul>
<li>Fail on Coercion</li>
<li>Fail on array out of bounds access</li>
<li>Fail on non-existent property access</li>
</ul>
<p><strong>Get the values of functions:</strong></p>
<ul>
<li><a href="https://github.com/power-assert-js/power-assert">https://github.com/power-assert-js/power-assert</a></li>
</ul>
<p><strong>Inspiration</strong></p>
<ul>
<li><a href="https://www.destroyallsoftware.com/talks/wat">wat js talk</a></li>
</ul>
<hr>
<h3 id="webglspecs">webgl-specs &#x2705; &#x2615;&#xFE0F;&#x2615;&#xFE0F;</h3>
<ul>
<li>What:
<ul>
<li>Detect the specs of a graphics card using web apis</li>
</ul>
</li>
<li>How:
<ul>
<li>Extract source from <a href="https://github.com/AnalyticalGraphicsInc/webglreport">webglreport</a> and create an API from it</li>
</ul>
</li>
</ul>
<h3 id="modelinggrowthofprojects">Modeling Growth of Projects &#x2705; &#x2615;&#xFE0F;&#x2615;&#xFE0F;</h3>
<ul>
<li>Consider using <a href="https://en.wikipedia.org/wiki/Compartmental_models_in_epidemiology#The_SIR_model">SIR Model</a></li>
<li>Variables
<ul>
<li>Initial stars (because we can&apos;t get view metrics, assume star count prop. to view count)</li>
<li>code quality</li>
<li>tags</li>
<li>language
<ul>
<li>size of language ecosystem</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="astmetadatainferer">&#x2705; &#x2615;&#xFE0F; ast-metadata-inferer</h3>
<ul>
<li>Generate a large collection of the ast node types of different API&apos;s</li>
</ul>
<h3 id="compattestrunner">&#x1F528; &#x2615;&#xFE0F;&#x2615;&#xFE0F;&#x2615;&#xFE0F; compat-test-runner</h3>
<ul>
<li>Given <code>compat-db</code> records, return if each record is supported in a specific browser</li>
<li>Run tests in every browser
<ul>
<li>How: use <code>testcafe</code> and download binaries for each browser</li>
</ul>
</li>
</ul>
<h3 id="xwing">xwing &#x2705; &#x2615;&#xFE0F;&#x2615;&#xFE0F;</h3>
<ul>
<li>What:
<ul>
<li>Emulate the trench run scene from star wars. The game involves avoiding obstacles in the trench and avoiding fire from tie fighters</li>
</ul>
</li>
<li>How:
<ul>
<li>Take models from sketchfab</li>
<li>Use three.js to build a small game</li>
<li>Should have sound affects</li>
<li>Adapt game textures to device. Use lower quality resources for low powered devices (laptops)</li>
</ul>
</li>
<li>Resources:
<ul>
<li><a href="https://sketchfab.com/models/94b745226cc64333becfdad566dbdce3">https://sketchfab.com/models/94b745226cc64333becfdad566dbdce3</a></li>
<li><a href="https://sketchfab.com/amilajack/likes">https://sketchfab.com/amilajack/likes</a></li>
</ul>
</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Electron React Boilerplate]]></title><description><![CDATA[<h2 id="an-introduction-to-electron">An Introduction to Electron</h2><p>The web environment has seen many advancements within the last few years. We&apos;ve seen advancements in rendering (react), significant improvements in serving assets quickly (service worker), and near native performance (WebAssembly). The web has seen improvements at such a rapid pace and Electron is</p>]]></description><link>https://amilajack.com/electron-react-boilerplate/</link><guid isPermaLink="false">5e0554bfa2380f5b95ecd07f</guid><category><![CDATA[open source]]></category><category><![CDATA[electron-react-boilerplate]]></category><category><![CDATA[electron]]></category><category><![CDATA[react]]></category><category><![CDATA[Javascript]]></category><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Wed, 31 Oct 2018 22:57:42 GMT</pubDate><media:content url="https://amilajack.com/content/images/2021/08/Screen-Shot-2021-08-16-at-2.58.21-PM.png" medium="image"/><content:encoded><![CDATA[<h2 id="an-introduction-to-electron">An Introduction to Electron</h2><img src="https://amilajack.com/content/images/2021/08/Screen-Shot-2021-08-16-at-2.58.21-PM.png" alt="Electron React Boilerplate"><p>The web environment has seen many advancements within the last few years. We&apos;ve seen advancements in rendering (react), significant improvements in serving assets quickly (service worker), and near native performance (WebAssembly). The web has seen improvements at such a rapid pace and Electron is what is brining these improvements to cross-platform desktop apps. It was only two years ago that electron had really started catching on. <a href="https://en.wikipedia.org/wiki/Electron_(software_framework)">Electron</a> is a derivative of the chromium project that embeds the <a href="nodejs.org">node.js</a> runtime.</p><h2 id="bare-bones-electron">Bare-bones Electron</h2><p>Out of the box, Electron doesn&apos;t do much other than provide the API&apos;s. And because Electron is solely a library, does not have the responsibility of setting up infrastructure around electron apps. Infrastructure decisions are let to the developer. But it is rarely the case that new developers to electron know the ins and outs of Electron specific infrastructure.</p><h2 id="enter-electron-react-boilerplate">Enter electron-react-boilerplate</h2><p>Enter electron-react-boilerplate (ERB). ERB provides solutions for the following infrastructure around Electron apps:</p><ul><li>Auto Updates: Allowing developers to publish updates to their apps</li><li>Asset Optimization: Optimizing JS, CSS, images, and other assets</li><li>DevTools Integration: Support for React, Redux, and Devtron DevTools</li><li>Packaging: Out of the box support for packaging apps to Windows, Mac, and Linux</li><li>Compilation: Out of the box support for <a href="http://babeljs.io">Babel</a> and <a href="https://webpack.js.org">Webpack</a></li><li>Code Analysis: <a href="https://eslint.org">ESLint</a> and <a href="https://flow.org">Flow</a> integration out of the box (TypeScript support planned)</li><li>Hot Module Replacement: Saved changes to app are reflected instantaneously without refreshing the app</li><li>State Management and Routing: &#xA0;Comes with Redux and <a href="https://reacttraining.com/react-router/">react-router</a> support out of the box</li></ul><h2 id="target-audience">Target Audience</h2><p>There is a balancing act when it comes to creating a boilerplate: adding too many features and configurations would intimidate newcomers and too little would not fulfill the demands of more mature developers with requirements.</p><h3 id="newcomers">NewComers</h3><p>We think ERB will add value to developers who are new to the Electron ecosystem and are trying to quickly scaffold Electron apps without worrying about the infrastructure. The base of the app is kept simple in order to ease the entry of newcomers.</p><h3 id="mature-electron-devs">Mature Electron Devs</h3><p>While the base is kept simple, we also wanted to make sure that it could be extended as well. For example, all of our WebPack configs are exposed to the user of the boilerplate and therefore can be easily extended. If mature devs want a slight permutation of the infrastructure, we offer examples of configuring ERB for the configuration they want. For example, if a user preferred <a href="https://www.typescriptlang.org">TypeScript</a> over <a href="http://flow.org">Flow</a>, they can refer to examples of ERB that are configured with TypeScript instead of the default, which is Flow.</p><h2 id="future-of-electron-react-boilerplate">Future of electron-react-boilerplate</h2><p>Since the creation of ERB, a number of new projects in the JS and Electron ecosystems have emerged and influenced the direction of ERB.</p><h4 id="typescript"><a href="https://www.typescriptlang.org">TypeScript</a></h4><p>Flow was the initial choice for ERB a couple of years ago. Much has changed since then: TypeScript has thrived in the ecosystem and has proven itself to be a significant competitor to Flow. It previously presented compatibility issues with our with our existing infrastructure. Babel, ESLint, and React integration with TypeScript presented a number of issues and Flow could be implemented with much less friction to existing JS infrastructure. But with TypeScript embracing compatibility with &#xA0;existing JS infra, we are considering migrating to TypeScript from.</p><h4 id="create-react-app"><a href="https://github.com/facebook/create-react-app">create-react-app</a></h4><p>The explosion of new React apps created with create-react-app (CRA) was hard for anyone in the JS ecosystem to ignore. CRA was a breakthrough in infrastructure because it removed the tight coupling between infrastructure of React apps and the source code of the apps themselves. The infrastructure of CRA apps are encapsulated in a single package: <code><a href="https://github.com/facebook/create-react-app/tree/master/packages/react-scripts">react-scripts</a></code>. I believe ERB should go down this direction as well and embrace the separation from infrastructure and apps. Here&apos;s what I imagine creating apps with ERB will look like in the future:</p><pre><code># With npm
$ npx create-erb-app my-app
# With yarn
$ yarn create erb-app my-app
cd my-app

# Some examples of commands that can be run
yarn start
yarn package
yarn build
yarn publish
yarn lint</code></pre><p>All the infrastructure would be configured with a few simple scripts which would be our equivalent of <code>react-scripts</code></p><h4 id="webassembly">WebAssembly</h4><p>Many electron apps rely on native dependencies, which are dependencies which interoperate with C and C++ code. These modules interoperate with C and C++ for performance increases and for simply having a way to bind to those languages. But native compilation requires recompiling those modules on a machine each time they are installed. More complications are introduced when the user does not have the dependencies to build these modules installed on their machine. These issues can be solved by compiling native modules to WebAssembly. Library authors can compile the C/C++ on their machines and distribute the compiled WebAssembly. Adding WebAssembly support to ERB can dramatically simplify the process of using native dependencies with Electron.</p>]]></content:encoded></item><item><title><![CDATA[xwing - A Star Wars WebGL Game Built with Three.JS]]></title><description><![CDATA[After learning the basics of WebGL, shaders, and ThreeJS, I thought I'd start a project that incorporates all these technologies. That project is xwing]]></description><link>https://amilajack.com/xwing/</link><guid isPermaLink="false">5e0554bfa2380f5b95ecd080</guid><category><![CDATA[threejs]]></category><category><![CDATA[webgl]]></category><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Fri, 07 Sep 2018 07:53:16 GMT</pubDate><media:content url="https://amilajack.com/content/images/2018/09/Screen-Shot-2018-09-20-at-9.08.40-PM.png" medium="image"/><content:encoded><![CDATA[<h2 id="beginnings">Beginnings</h2><img src="https://amilajack.com/content/images/2018/09/Screen-Shot-2018-09-20-at-9.08.40-PM.png" alt="xwing - A Star Wars WebGL Game Built with Three.JS"><p>Every year I have a personal goal of learning something new each summer to make sure I don&apos;t stagnate as a programmer. This summer, my focus is to learn about the graphics stack of the web platform--namely, <a href="https://en.wikipedia.org/wiki/WebGL">WebGL</a>. After learning the basics of WebGL, <a href="https://en.wikipedia.org/wiki/Shader">shaders</a>, and <a href="https://en.wikipedia.org/wiki/Three.js">ThreeJS</a>, I thought I&apos;d start a project that incorporates all these technologies. That project is <a href="https://github.com/amilajack/xwing">xwing</a>, a game which recreates the trench run scene from Star Wars. If you&apos;ve every seen Star Wars, you&apos;re probably familiar with the trench run scene. If not, here&apos;s a short clip showing what that is:</p><!--kg-card-begin: markdown--><iframe width="560" height="315" src="https://www.youtube.com/embed/2WBG2rJZGW8?start=600" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe><!--kg-card-end: markdown--><h2 id="inspiration">Inspiration</h2><p>This game was heavily inspired by Star War Squadron Rogue Leader:</p><!--kg-card-begin: markdown--><iframe width="560" height="315" src="https://www.youtube.com/embed/uXpi-Yybv-k?start=300" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe><!--kg-card-end: markdown--><h2 id="goals">Goals</h2><p>The goal of this project is to design a gameplay experience that is similar to Star War Squadron Rogue Leader. Here are the following goals that are unique to xwing: </p><ul><li>Published to the web</li><li>Optimize game for slower internet connections</li><li>Run on multiple devices with different levels of graphics performance</li><li>Leverage high resolution assets and textures for the game</li><li>Leverage modern web graphics technologies (<a href="https://webgl2fundamentals.org/">WebGL 2</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas">OffscreenCanvas</a>)</li></ul><h2 id="current-state">Current State</h2><p>The current state of xwing is a very experimental work in progress. The <a href="https://github.com/amilajack/xwing">source code is available here</a>. Feel free to contribute if you&apos;re interested! Subscribe for follow up blog posts tracking my progress on xwing and other projects. </p><h2 id="prior-art">Prior Art</h2><ul><li><a href="https://blog.openbloc.fr/gamedev-with-three-js-on-the-modern-web/">DroneWorld</a></li></ul>]]></content:encoded></item><item><title><![CDATA[Killing Coercion and Silent Failure in JavaScript With Babel]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>TL;DR:</p>
<p><img src="https://amilajack.com/content/images/2017/06/demo.gif" alt="babel-plugin-fail-explicit-demo" loading="lazy"></p>
<p>The tale of Brendan Eich&apos;s notorious 10 days of writing what he was told would be Java&apos;s &quot;sidekick&quot; language in the browser, &quot;JavaScript&quot;, has taken off like no one would have ever expected. But Brendan could only do so much</p>]]></description><link>https://amilajack.com/nailing-the-coffin-of-javascript-coercion/</link><guid isPermaLink="false">5e0554bfa2380f5b95ecd07b</guid><category><![CDATA[Javascript]]></category><category><![CDATA[DX]]></category><category><![CDATA[Coercion]]></category><category><![CDATA[Babel]]></category><category><![CDATA[babel-plugin-fail-explicit]]></category><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Thu, 01 Jun 2017 02:35:56 GMT</pubDate><media:content url="https://amilajack.com/content/images/2018/09/flames-580x358.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://amilajack.com/content/images/2018/09/flames-580x358.jpg" alt="Killing Coercion and Silent Failure in JavaScript With Babel"><p>TL;DR:</p>
<p><img src="https://amilajack.com/content/images/2017/06/demo.gif" alt="Killing Coercion and Silent Failure in JavaScript With Babel" loading="lazy"></p>
<p>The tale of Brendan Eich&apos;s notorious 10 days of writing what he was told would be Java&apos;s &quot;sidekick&quot; language in the browser, &quot;JavaScript&quot;, has taken off like no one would have ever expected. But Brendan could only do so much in those 10 days and one of the things he didn&apos;t have time to do was add exceptions and error handling to the language.</p>
<p>JS was designed so that it would &quot;fail silently&quot;. These issues still persist in the language.</p>
<p>Here&apos;s some examples of JS silent failure semantics:</p>
<pre><code class="language-js">const foo = []
foo[1000]      // No exception thrown
foo.bar        // No exception thrown

[] + []        // No exception thrown
{} + []        // No exception thrown
// etc..
</code></pre>
<h2 id="fixingjavascript">Fixing JavaScript</h2>
<blockquote>
<p>Why can&apos;t you just fix the problems in JavaScript?</p>
</blockquote>
<p>TC39, the committee that decides the language specification for JS, follows a &quot;Don&apos;t break the web&quot; philosophy. All changes to the language <strong>must</strong> be semantically backwards compatible with all previous versions of the language.</p>
<p>There are also a number of attempts to fix the silent failure semantics of JS. Some time ago, <a href="https://docs.google.com/document/d/1Qk0qC4s_XNCLemj42FqfsRLp49nDQMZ1y7fwf5YjaI4/view">Google proposed a &quot;Strong Mode&quot; for JS</a>, which would eliminate all silent failure semantics from JS in a backwards compatible way. Unfortunately, the proposal did not pass and we&apos;re still left with the same broken semantics.</p>
<h2 id="anewhopetranspilers">A New Hope: Transpilers</h2>
<p>A couple years go by and writing vanilla JS has become a dreaded pastime. Transpilers, namely <a href="http://babeljs.io/">Babel</a>, have taken the JS community by storm. Transpilers allow transformation of JS source code to compiled JS source code. What if we could write unsafe JS code and transform it to a stricter subset?</p>
<p>That&apos;s exactly what I&apos;ve been experimenting with for a few weeks and the results have been quite promising:</p>
<h2 id="whatitdoes">What it does</h2>
<p>Here&apos;s a simple example that shows failure of binary operators (<code>-</code>, <code>+</code>, <code>*</code>, etc) with unexpected types:</p>
<script type="text/javascript" src="https://asciinema.org/a/2lg8ewea9jhwdib7xhdutvsv1.js" id="asciicast-2lg8ewea9jhwdib7xhdutvsv1" async></script>
<p>Here&apos;s a more real world example that shows:</p>
<ul>
<li>Failure on access of non-existent property</li>
<li>Index out of bounds errors</li>
</ul>
<script type="text/javascript" src="https://asciinema.org/a/cum49dt2w74sicwsq0qg3cptt.js" id="asciicast-cum49dt2w74sicwsq0qg3cptt" async></script>
<p>Here&apos;s an informal spec of what the plugin (each will throw a <code>TypeError</code> on failure):</p>
<ul>
<li>Prevents out of bound array access</li>
<li>Prevents access of non-existent property</li>
<li>Allows usage of <code>+</code> (and other forms: <code>+=</code>, etc) only between strings and numbers. Other binary operators will fail on operation that contains at least one expression that is not a number</li>
<li>Only comparisons between strings and numbers is<br>
allowed. Comparisons are only allowed between the same type. ex: <code>&apos;12&apos; &gt; 12</code> throws while <code>12 &gt; 12</code> does not</li>
</ul>
<h2 id="howitworks">How it works</h2>
<p>The transformations that are applied are pretty simple: all binary expressions are wrapped in a <a href="https://github.com/amilajack/safe-access-check">function that checks the types</a> of each expression and throws when the types are invalid. Here&apos;s an example of the comparison transformation:</p>
<pre><code class="language-js">{} + []

// transforms to:

safeComparison({}, &quot;+&quot;, [])
</code></pre>
<p>Other transformations are similar. Here&apos;s the property access transformation:</p>
<pre><code class="language-js">const some = {}
some.foo.bar.baz

// transforms to:

safePropertyAccess(some, [&apos;foo&apos;, &apos;bar&apos;, &apos;baz&apos;])
</code></pre>
<h2 id="tryingitout">Trying it out</h2>
<h5 id="usingthedemo">Using the demo</h5>
<pre><code>git clone https://github.com/amilajack/babel-plugin-fail-explicit-demo.git
cd babel-plugin-fail-explicit-demo
npm i -g babel-cli
babel-node index.js
</code></pre>
<h5 id="manualinstall">Manual install:</h5>
<pre><code class="language-bash">npm i babel-plugin-fail-explicit
npm i transform-es2015-modules-commonjs
npm i -g babel-cli
</code></pre>
<p>Create a <code>.babelrc</code> file:</p>
<pre><code class="language-json">{
  &quot;plugins&quot;: [
    &quot;fail-explicit&quot;,
    &quot;transform-es2015-modules-commonjs&quot;
  ]
}
</code></pre>
<p>Write some JS:</p>
<pre><code class="language-js">// index.js
const some = []
some += 12
</code></pre>
<p>Run <code>babel-node index.js</code>  ? ? ?</p>
<h2 id="challenges">Challenges</h2>
<p>Transforming code and wrapping expressions in functions comes at the cost of debugging the code. The stacktraces of the transformed code is far more convoluted when compared to those of source code. Here&apos;s what the stack trace of the transformed code looks like for the following source:</p>
<pre><code class="language-js">const foo = []
foo[1111]
</code></pre>
<pre><code>/safe-access-check/lib/index.js
          throw new TypeError(`&quot;${separators.join(&apos;&apos;)}&quot; is out of bounds`);
          ^

TypeError: &quot;Array[1111]&quot; is out of bounds
    at protoChain.forEach.each
    at Array.forEach (native)
    at safePropertyAccess
    at Object.&lt;anonymous&gt;
    at Module._compile
    at loader
    at Object.require.extensions.(anonymous function)
    at Module.load
    at tryModuleLoad
    at Function.Module._load
</code></pre>
<p>Ideally, <code>safePropertyAccess()</code> and other added checks could be removed from the stack trace, giving the impression that the checks were made natively by the language. I have noticed that <a href="https://github.com/codemix/flow-runtime/tree/master/packages/babel-plugin-flow-runtime">flow-runtime</a> somehow does this. The way it manipulates the stack trace is definitely worth investigating.</p>
<h2 id="whatsnext">What&apos;s Next</h2>
<p>I&apos;m currently looking for feedback from users and language designers. I&apos;d really appreciate test case contributions or bug reports.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Mad Science With WebAssembly]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>This article provides a short background of WebAssembly and provides a tutorial to get you started.</p>
<h2 id="background">Background</h2>
<p><strong>&#x201C;Write once, work everywhere&#x201D;</strong> is the beauty of the web. This cannot be said for the many native platforms, including iOS, OSX, Android, Windows, Gnome, and other. Just remember the last</p>]]></description><link>https://amilajack.com/mad-science-with-webassembly/</link><guid isPermaLink="false">5e0554bfa2380f5b95ecd078</guid><category><![CDATA[webassembly]]></category><category><![CDATA[asm.js]]></category><category><![CDATA[emscripten]]></category><dc:creator><![CDATA[Amila Welihinda]]></dc:creator><pubDate>Sat, 25 Jun 2016 01:39:00 GMT</pubDate><media:content url="https://amilajack.com/content/images/2018/09/mad-scientist.jpeg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://amilajack.com/content/images/2018/09/mad-scientist.jpeg" alt="Mad Science With WebAssembly"><p>This article provides a short background of WebAssembly and provides a tutorial to get you started.</p>
<h2 id="background">Background</h2>
<p><strong>&#x201C;Write once, work everywhere&#x201D;</strong> is the beauty of the web. This cannot be said for the many native platforms, including iOS, OSX, Android, Windows, Gnome, and other. Just remember the last time you tried compiling or installing something and it would just work! Nothing beats <code>npm i &amp;&amp; npm start</code> ? .</p>
<p>But the high-level environment that the browser offers comes at the cost of performance. <strong>&#x201C;Write once, work everywhere&#x201D;</strong> also means that the web can&apos;t be broken. Providing a high-level also means that developers are stuck with the API&apos;s that the browser has. Want truly multithreaded apps? Too bad. You&apos;re stuck with WebWorkers and will have to wait until the Web API&apos;s or ES6 standards change. Want to build a graphics intensive app</p>
<p>Or at least this <em>was</em> the case.</p>
<p><strong>WebAssembly</strong> is what changes all of that.</p>
<h3 id="whatiswebassembly">What is WebAssembly?</h3>
<p>In short, Webassembly (wasm) is a <strong>binary format for the web</strong> that aims to <strong>match native performance</strong>, <strong>extend the JavaScript language</strong> (kernel semantics). For a more in-dept explanation, refer to the sources at the end of this article. Check out an <a href="http://webassembly.github.io/demo/">Angry Bots</a> and compare the differences between asm.js and wasm performance.</p>
<h3 id="possibilities">Possibilities</h3>
<p>Some practical use cases of wasm include migrating the bottlenecked parts of a JavaScript application to wasm and importing them as scripts (very similar to node c++ bindings):</p>
<pre><code class="language-javascript">// vDOM reconciliation in react
import diff from &apos;wasm-diff&apos;

// Check if react update the DOM
function reconcileDOM(vDOM, html) {
    diff(vDOM, html)
}
</code></pre>
<p>wasm can also be used as a compile target for games, video editing, and other native applications.</p>
<p>At the moment, this is pretty difficult. I&apos;ve been messing around with wasm but haven&apos;t found any tutorials to help me out so I thought I would shed some light on how to get started.</p>
<h3 id="madscience">Mad Science</h3>
<p>First, let&apos;s try to compile a native application so that we have something to compare wasm to. We will be using, openFrameworks a mature graphics library that supports compilation to wasm through emscripten, build tool which compiles C/C++ to wasm. I should note that this tutorial assumes that you are running on macOS. If you are using another platform, please reference the <a href="http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html">docs</a>.</p>
<p>First, we&apos;ll need to go to <a href="http://openframeworks.cc/download/">openframeworks</a> and download the version for osx. Preferably, you should move this to your projects directory. (Note: Avoid cloning from the github repo)</p>
<p>Then we need to generate the files needed to run the openFrameworks examples, located in of <code>v0.9.x_osx_release/examples</code>. To do this, open <code>projectGenerator.app</code> inside of <code>projectGenerator-osx</code>. If you don&apos;t prefer manually entering the path to the download, click on the search icon and open the openFrameworks folder.</p>
<p>The result should resemble this:<br>
<img src="https://amilajack.com/content/images/2016/06/Screen-Shot-2016-06-24-at-12-24-31-PM.png" alt="Mad Science With WebAssembly" loading="lazy"></p>
<p>Cool! Now click generate. This should notify you to open xCode. When it opens, click on the &apos;scheme&apos; at the top right and select the library icon:</p>
<p><img src="https://amilajack.com/content/images/2016/06/some.jpg" alt="Mad Science With WebAssembly" loading="lazy"></p>
<p>Perfect! Now, <code>cd</code> to the <code>examples/3d/3DPrimitivesExample</code> directory inside of <code>v0.9.x_osx_release</code>, open <code>3DPrimitivesExample.xcodeproj</code>, and click xCode&apos;s &apos;play&apos; button.</p>
<p>You should see something similar to this:<br>
<img src="https://amilajack.com/content/images/2016/06/Screen-Shot-2016-06-24-at-1-05-42-PM.png" alt="Mad Science With WebAssembly" loading="lazy"></p>
<p>Impressive! Now let&apos;s see how well wasm performs.</p>
<p>==Requirements: <strong>cmake</strong>, <strong>git</strong>, <strong>node</strong> ==</p>
<p>To get started, we&apos;ll need to <a href="http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html">download the emscripten sdk</a> and &apos;Portable Emscripten SDK for Linux and OS X&apos;. After unzipping the folder:</p>
<pre><code class="language-bash"># Move it to your mode directory.
mv emsdk_portable ~/

# cd into it.
cd ~/emsdk_portable

# Fetch the latest registry of available tools.
./emsdk update

# Download and install the latest SDK tools.
./emsdk install latest

# Make the &quot;latest&quot; SDK &quot;active&quot;
./emsdk activate latest

# Set the env variables for the current session
source ./emsdk_env.sh
</code></pre>
<p><mark>Requirement: Your default browser should support WebGL</mark></p>
<p>Now that we have <code>emsdk</code>, let&apos;s use it to compile an openFrameworks project. Inside the same terminal window, <code>cd</code> back to the <code>examples/3d/3DPrimitivesExample</code> directory inside of <code>v0.9.x_osx_release</code> and run:</p>
<pre><code class="language-bash"># This will take a while. Come back after a cup of coffee
emmake make

# Run the demo in your default browser
emrun bin/3DPrimitivesExample.html
</code></pre>
<p><img src="https://amilajack.com/content/images/2016/06/Screen-Shot-2016-06-24-at-2-07-48-PM.png" alt="Mad Science With WebAssembly" loading="lazy"></p>
<p>&quot;...wth... HOW?&quot; Alon Zakai (creator of emscripten) explains this well:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/JhMlWj4tCDo" frameborder="0" allowfullscreen></iframe>
<p><mark>This blog post is a work in progress. I am in the process of asking Alon Zakai about how to migrate asm.js code to wasm and will update this blog post when I get the answer</mark></p>
<hr>
<p><mark>I do not have a comments system at the time of writing this so feel free to email me if you have any questions (<a href="mailto:amilajack@gmail.com">amilajack@gmail.com</a>).</mark></p>
<h3 id="sourcesrecommendedreading">Sources/Recommended Reading:</h3>
<ul>
<li><a href="http://webassembly.github.io/">Official WebAssembly page</a></li>
<li><a href="https://github.com/WebAssembly/design">WebAssembly Design</a></li>
<li><a href="https://medium.com/javascript-scene/what-is-webassembly-the-dawn-of-a-new-era-61256ec5a8f6">What is WebAssembly? The dawn of a new era</a></li>
<li><a href="https://medium.com/javascript-scene/why-we-need-webassembly-an-interview-with-brendan-eich-7fb2a60b0723">Why we need WebAssembly an interview with Brendan Eich</a></li>
<li><a href="https://brendaneich.com/2015/06/from-asm-js-to-webassembly/">From asm.js to WebAssembly</a></li>
<li><a href="https://auth0.com/blog/2015/10/14/7-things-you-should-know-about-web-assembly/">Things you should know about webassembly</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>