<story><title>VanillaJSX.com</title><url>https://vanillajsx.com/</url></story><parent_chain><item><author>spankalee</author><text>Returning actual DOM nodes entirely blunts the big advantage of JSX (and non-JSX libraries like Lit) - which is their immediate mode style API, and UI=f(state) model.&lt;p&gt;You want to return a description of the DOM, rather than the real DOM, because you want to be able to reevaluate your templates repeatedly with new state, and efficiently update the DOM where that template is rendered to.&lt;p&gt;All the examples here use imperative DOM APIs to do updates, like with this:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    function TodoInput(attrs: { add: (v: string) =&amp;gt; void }) {
      const input = &amp;lt;input &amp;#x2F;&amp;gt; as HTMLInputElement;
      input.placeholder = &amp;#x27;Add todo item...&amp;#x27;;
      input.onkeydown = (e) =&amp;gt; {
        if (e.key === &amp;#x27;Enter&amp;#x27;) {
          attrs.add(input.value);
          input.value = &amp;#x27;&amp;#x27;;
        }
      };
      return input;
    }

    class TodoList {
      ul = &amp;lt;ul class=&amp;#x27;todolist&amp;#x27; &amp;#x2F;&amp;gt; as HTMLUListElement;
      add(v: string) {
        const item = &amp;lt;li&amp;gt;{v}&amp;lt;&amp;#x2F;li&amp;gt; as HTMLLIElement;
        item.onclick = () =&amp;gt; item.remove();
        this.ul.append(item);
      }
    }
&lt;/code&gt;&lt;/pre&gt;
Avoiding those `input.onkeydown = ...` and `this.ul.append(item)` cases, and instead just iterating over items in your template, is probably the main benefit of a VDOM.&lt;p&gt;(The problem with VDOMs is that diffing is slow, a problem solved by using templates that separate static from dynamic parts, like Lit - a library I work on).</text></item></parent_chain><comment><author>francasso</author><text>From my experience creating complex  web UIs, the performance angle of using a vdom is pure fantasy if your application is complex enough.&lt;p&gt;In fact I now strongly believe it&amp;#x27;s counter productive, because most people come to it thinking &amp;quot;I can just trigger however many re-renders of this large piece of UI as I like, the vdom makes it ok&amp;quot; and it doesn&amp;#x27;t, the performance sucks, but now you have architected the app in a way that requires a rewrite to make the app perform well.&lt;p&gt;I have seen this exact sequence of events four times, by four different teams. The second, third and fourth, as a principal architect consulting for the team I tried to intervene and advocate for a vanilla architecture that is mindful about performance, citing the issues they would likely experience with react, but to no avail. There was a lot of &amp;quot;oh but there many ways to avoid those issues&amp;quot; followed by a list of things I was presumably ignorant about.&lt;p&gt;I guess most of us need to learn things the hard way.</text></comment>
<story><title>VanillaJSX.com</title><url>https://vanillajsx.com/</url></story><parent_chain><item><author>spankalee</author><text>Returning actual DOM nodes entirely blunts the big advantage of JSX (and non-JSX libraries like Lit) - which is their immediate mode style API, and UI=f(state) model.&lt;p&gt;You want to return a description of the DOM, rather than the real DOM, because you want to be able to reevaluate your templates repeatedly with new state, and efficiently update the DOM where that template is rendered to.&lt;p&gt;All the examples here use imperative DOM APIs to do updates, like with this:&lt;p&gt;&lt;pre&gt;&lt;code&gt;    function TodoInput(attrs: { add: (v: string) =&amp;gt; void }) {
      const input = &amp;lt;input &amp;#x2F;&amp;gt; as HTMLInputElement;
      input.placeholder = &amp;#x27;Add todo item...&amp;#x27;;
      input.onkeydown = (e) =&amp;gt; {
        if (e.key === &amp;#x27;Enter&amp;#x27;) {
          attrs.add(input.value);
          input.value = &amp;#x27;&amp;#x27;;
        }
      };
      return input;
    }

    class TodoList {
      ul = &amp;lt;ul class=&amp;#x27;todolist&amp;#x27; &amp;#x2F;&amp;gt; as HTMLUListElement;
      add(v: string) {
        const item = &amp;lt;li&amp;gt;{v}&amp;lt;&amp;#x2F;li&amp;gt; as HTMLLIElement;
        item.onclick = () =&amp;gt; item.remove();
        this.ul.append(item);
      }
    }
&lt;/code&gt;&lt;/pre&gt;
Avoiding those `input.onkeydown = ...` and `this.ul.append(item)` cases, and instead just iterating over items in your template, is probably the main benefit of a VDOM.&lt;p&gt;(The problem with VDOMs is that diffing is slow, a problem solved by using templates that separate static from dynamic parts, like Lit - a library I work on).</text></item></parent_chain><comment><author>JasonSage</author><text>I agree with the sibling comment that this really depends on the user. To take a different approach: JSX is just a different DSL to the createElement function call pattern (see Preact.h for example) and all of the benefits you’re describing come from the framework and runtime.&lt;p&gt;More concisely: JSX is just an alternate function call syntax with some useful applications.&lt;p&gt;For example at my last company we used JSX to make test data factories that had an XML-like look but were using a builder-pattern in the element creation that was able to make contextual decisions about what was in the final data. Nothing to do with React, DOM, or inability to express the same thing declaratively without JSX.</text></comment>