<p dir="auto">Fueled by the success of React, several alternative virtual DOM implementations have emerged, such as <a href="https://muut.com/riotjs/" rel="nofollow">Riot</a>, <a href="http://lhorie.github.io/mithril/" rel="nofollow">Mithril</a>, <a href="https://github.com/Raynos/mercury">Mercury</a>, and <a href="https://github.com/Matt-Esch/virtual-dom">virtual-dom</a>.</p>
<p dir="auto">Atom <a href="http://blog.atom.io/2015/02/04/built-in-6to5.html" rel="nofollow">recently integrated Babel into core</a>, and one of our major goals with core is to be as framework-agnostic as possible. One area where it would be nice to be agnostic is in the usage of JSX... it would be great if any of these frameworks could create JSX adaptors so the same convenient syntax could be used with a variety of underlying implementations.</p>
<p dir="auto">Currently, JSX expressions are compiled to calls to <code class="notranslate">React.createElement</code>. While it's certainly possible to provide an alternative implementation of the <code class="notranslate">React</code> variable in a given scope, it would be nice if the language were a bit more neutral. One idea would be to call <code class="notranslate">JSX.createElement</code> instead if a <code class="notranslate">JSX</code> variable is in scope at the site of a JSX expression, or perhaps allow the create function to be specified via an option. Or maybe there's a better idea I haven't thought of. I'd prefer the <code class="notranslate">JSX</code> rule so it's consistent and we don't have to extend Atom's basic pragma system to support this option on every file.</p>
<p dir="auto">Would your team be open to something like this?</p>
<p dir="auto">The JSX transform is currently coupled to React, but other libraries could potentially make use of the syntax. There are libraries like jsx-transform (<a href="https://github.com/alexmingoia/jsx-transform">https://github.com/alexmingoia/jsx-transform</a>) that make the transform more generic and allow you to specific how the output should look:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/** @jsx React.createElement */
var React = require('react');

var profile = &lt;div&gt;
  &lt;img src=&quot;avatar.png&quot; class=&quot;profile&quot; /&gt;
  &lt;h3&gt;{[user.firstName, user.lastName].join(' ')}&lt;/h3&gt;
&lt;/div&gt;;"><pre class="notranslate"><span class="pl-c">/** <span class="pl-k">@jsx</span> React.createElement */</span>
<span class="pl-k">var</span> <span class="pl-v">React</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'react'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">var</span> <span class="pl-s1">profile</span> <span class="pl-c1">=</span> <span class="pl-c1">&lt;</span><span class="pl-ent">div</span><span class="pl-c1">&gt;</span>
  <span class="pl-c1">&lt;</span><span class="pl-ent">img</span> <span class="pl-c1">src</span><span class="pl-c1">=</span><span class="pl-s">"avatar.png"</span> <span class="pl-c1">class</span><span class="pl-c1">=</span><span class="pl-s">"profile"</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
  <span class="pl-c1">&lt;</span><span class="pl-ent">h3</span><span class="pl-c1">&gt;</span><span class="pl-kos">{</span><span class="pl-kos">[</span><span class="pl-s1">user</span><span class="pl-kos">.</span><span class="pl-c1">firstName</span><span class="pl-kos">,</span> <span class="pl-s1">user</span><span class="pl-kos">.</span><span class="pl-c1">lastName</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-en">join</span><span class="pl-kos">(</span><span class="pl-s">' '</span><span class="pl-kos">)</span><span class="pl-kos">}</span><span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">h3</span><span class="pl-c1">&gt;</span>
<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">div</span><span class="pl-c1">&gt;</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Transforms it to:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var React = require('react');

var profile = React.createElement('div', null, [
  React.createElement('img', { src: &quot;avatar.png&quot;, class: &quot;profile&quot; }),
  React.createElement('h3', null, [[user.firstName, user.lastName].join(' ')])
]);"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-v">React</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'react'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">var</span> <span class="pl-s1">profile</span> <span class="pl-c1">=</span> <span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-en">createElement</span><span class="pl-kos">(</span><span class="pl-s">'div'</span><span class="pl-kos">,</span> <span class="pl-c1">null</span><span class="pl-kos">,</span> <span class="pl-kos">[</span>
  <span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-en">createElement</span><span class="pl-kos">(</span><span class="pl-s">'img'</span><span class="pl-kos">,</span> <span class="pl-kos">{</span> <span class="pl-c1">src</span>: <span class="pl-s">"avatar.png"</span><span class="pl-kos">,</span> <span class="pl-c1">class</span>: <span class="pl-s">"profile"</span> <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">,</span>
  <span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-en">createElement</span><span class="pl-kos">(</span><span class="pl-s">'h3'</span><span class="pl-kos">,</span> <span class="pl-c1">null</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-kos">[</span><span class="pl-s1">user</span><span class="pl-kos">.</span><span class="pl-c1">firstName</span><span class="pl-kos">,</span> <span class="pl-s1">user</span><span class="pl-kos">.</span><span class="pl-c1">lastName</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-en">join</span><span class="pl-kos">(</span><span class="pl-s">' '</span><span class="pl-kos">)</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
<span class="pl-kos">]</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">Alternative virtual DOM libraries can then use it:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="/** @jsx dom */
var {dom} = require('deku');

var profile = &lt;div&gt;
  &lt;img src=&quot;avatar.png&quot; class=&quot;profile&quot; /&gt;
  &lt;h3&gt;{[user.firstName, user.lastName].join(' ')}&lt;/h3&gt;
&lt;/div&gt;;"><pre class="notranslate"><span class="pl-c">/** <span class="pl-k">@jsx</span> dom */</span>
<span class="pl-k">var</span> <span class="pl-kos">{</span>dom<span class="pl-kos">}</span> <span class="pl-c1">=</span> <span class="pl-en">require</span><span class="pl-kos">(</span><span class="pl-s">'deku'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

<span class="pl-k">var</span> <span class="pl-s1">profile</span> <span class="pl-c1">=</span> <span class="pl-c1">&lt;</span><span class="pl-ent">div</span><span class="pl-c1">&gt;</span>
  <span class="pl-c1">&lt;</span><span class="pl-ent">img</span> <span class="pl-c1">src</span><span class="pl-c1">=</span><span class="pl-s">"avatar.png"</span> <span class="pl-c1">class</span><span class="pl-c1">=</span><span class="pl-s">"profile"</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
  <span class="pl-c1">&lt;</span><span class="pl-ent">h3</span><span class="pl-c1">&gt;</span><span class="pl-kos">{</span><span class="pl-kos">[</span><span class="pl-s1">user</span><span class="pl-kos">.</span><span class="pl-c1">firstName</span><span class="pl-kos">,</span> <span class="pl-s1">user</span><span class="pl-kos">.</span><span class="pl-c1">lastName</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-en">join</span><span class="pl-kos">(</span><span class="pl-s">' '</span><span class="pl-kos">)</span><span class="pl-kos">}</span><span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">h3</span><span class="pl-c1">&gt;</span>
<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-ent">div</span><span class="pl-c1">&gt;</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">And get the same benefits of using JSX.</p>
<p dir="auto">You could easily just add a setting for it rather than using the comment format too. If this is something that would be useful I can look at opening a PR for it.</p>