Launch HN: Pynecone (YC W23) – Web Apps in Pure Python
As a somewhat active Dash user, I wonder why is it that most of these frameworks have chosen to go this &quot;write-HTML-in-Python&quot; way, instead of what seems to me a much more natural approach: write some basic, stripped down HTML&#x2F;CSS in a separate file, then connect that automatically to your backend by e.g. using the right IDs.<p>Let me give an example. In the Increment&#x2F;Decrement we see the following Python code:<p><pre><code>  def index():
    return pc.hstack(
        pc.button(
            &quot;Decrement&quot;,
            color_scheme=&quot;red&quot;,
            border_radius=&quot;1em&quot;,
            on_click=State.decrement,
        ),
        pc.heading(State.count, font_size=&quot;2em&quot;),
        pc.button(
            &quot;Increment&quot;,
            color_scheme=&quot;green&quot;,
            border_radius=&quot;1em&quot;,
            on_click=State.increment,
        ),
    )
</code></pre>
Which is supposed to build the interface for this almost-too-simple example. Note how there is a lot of custom Python code for simple HTML and CSS things that are already directly available in, well, HTML and CSS. This is how it might look like instead (pardon the inline CSS, it&#x27;s just a quick comment, you can of course make this much better by writing the CSS separately):<p><pre><code>  &lt;button id=&quot;dec_btn&quot; class=&quot;red&quot; style=&quot;border-radius: 1em;&quot;&gt;Decrement&lt;&#x2F;button&gt;
  &lt;h2 id=&quot;count_h&quot; style=&quot;display: inline; font-size: 2em&quot;&gt;0&lt;&#x2F;h2&gt;
  &lt;button id=&quot;inc_btn&quot; class=&quot;green&quot; style=&quot;border-radius: 1em;&quot;&gt;Increment&lt;&#x2F;button&gt;
</code></pre>
Then in the Python side, something like:<p><pre><code>  pc.event(id=&#x27;dec_btn&#x27;, type=&#x27;on_click&#x27;, action=State.decrement)
  pc.event(id=&#x27;inc_btn&#x27;, type=&#x27;on_click&#x27;, action=State.increment)

  # Runs everytime the State changes (or something)
  def global_update():
    pc.print(id=&quot;count_h&quot;, f&#x27;{State.count}&#x27;)
</code></pre>
This way, presentation is separated from business logic, and &#x27;everything in its right place&#x27; (c).<p>I understand that many (most?) Python developers would like to stay away from JS, but I expect that most developers will know 80% of what is needed from basic HTML&#x2F;CSS in order to do something like this. If they don&#x27;t, it should be really easy to learn. I mean, come on, basic HTML&#x2F;CSS is like a foundational building block of computing, and anyway, to write &quot;HTML-in-Python&quot; you still need to learn the basics (and then twist them into their Python doppelganger).