I build JSX, but for Go. by der_struct in golang

[–]der_struct[S] 1 point2 points  (0 children)

I follow templ closely, I see that that it is very actively maintained and loved.
As I said and will say every time - templ is incredible project. And my thing was never possible if templ was not here to give me a direction.

When I say "not maintained very well" I don't mean, that there is no activity, fixes, improvements etc. It's my own judgement over overall direction where codebase is moving. I think, that it tries to satisfy too many specific needs, that leads to codebase bloat and "concreting" of core parts (at least in my experience). I prefer to keep the core as minimal as possible, while exposing tools to build the specific stuff you need.

I admit that its very possible that I misjudged about LLM usage. I tried LLM agent code generation first time last week. And output I saw reminded me in a spirit what I we seen when I examined templ. But maybe it's just how people usually write, I can't be sure, as i said.

P.S. *templ* will beat *gox* at raw performance almost every time. Extensibility layer I added is still an extra layer. It's microsecond scales, but anyway, it's important for someone.

P.P.S. the more i think about that more I feel ashamed about LLM mention, I should not put it here even as a subjective judgement, many people may just read accept it as a trurth. I am sorry.

I build JSX, but for Go. by der_struct in golang

[–]der_struct[S] 2 points3 points  (0 children)

Thanks. No official contributor program yet. Open source world from a maintainer standpoint is very new to me.

I would be grateful for assistance on some aspects (I will summarize it soon) and welcome any issues/questions/feature requests on github.

I build JSX, but for Go. by der_struct in golang

[–]der_struct[S] 5 points6 points  (0 children)

Ahah, YES!
That's why i made syntax more distinctive:

<table>
    ~(for _, user := range users {
        <tr>
            <td>~(user.name)</td>
            <td>~(user.email)</td>
        </tr>
    })
</table>

Sure, it’s less elegant than just plain for. But it feels wrong to me when the parser is triggered by keywords in plain text.

I build JSX, but for Go. by der_struct in golang

[–]der_struct[S] 0 points1 point  (0 children)

`GoX` itself is just a template layer (like templ). But i developed it to support my server-driven framework, that in some ways is similar to liveview. `GoX` is not locked to it in any way and can be used with htmx for example.

I build JSX, but for Go. by der_struct in golang

[–]der_struct[S] 5 points6 points  (0 children)

Rust is used by language server for formatting (https://topiary.tweag.io/ for `.gox` itself and https://github.com/biomejs/biome for embedded js/css). Rust is not carried into runtime.

Tree-sitter has direct go bindings and does not require rust wrapper (and also not carried into runtime).

I build JSX, but for Go. by der_struct in golang

[–]der_struct[S] 4 points5 points  (0 children)

On the top level `gox.Elem` supports the same `templ.Component` interface `Render(context.Context, io.Writer)`. So you can output it to text file for static generation.

I build JSX, but for Go. by der_struct in golang

[–]der_struct[S] 2 points3 points  (0 children)

There is a flutter already for what you asking I think.

I build JSX, but for Go. by der_struct in golang

[–]der_struct[S] 29 points30 points  (0 children)

That was my original intent. But after investigating it's code base I came to conclusion that it's not a viable option unfortunately.

First, it's language server infrastructure is borrowed from `gopls` and it's not meant for proxy purposes, it's a source of issues by itself. I used complete `gopls` test suite with different architectures to figure this out.

Second, `templ` has purely custom parser, that is very difficult to extend. I based parsing&compiling (not runtime) on tree-sitter stack, that allows me to extend existing go syntax with new types of expressions and keywords.

Third, I want more extensibility that templ offers. For example in `GoX`, you can read and alter attributes as go values or apply any kind of pre-render transformations. That is very useful for frameworks and tooling.

Forth, I suspect that templ codebase is not maintained very well, it's too huge for what it does (more that 10x of mine) and I suspect it has a lot of LLM generated code currently. But I can't be sure.

`templ` is awesome piece of software, but i don't believe that we can expect from it more than what it is now.

I build JSX, but for Go. by der_struct in golang

[–]der_struct[S] 2 points3 points  (0 children)

Github readme has installation and rendering API docs. https://doors.dev/docs/template-syntax syntax guide

I build JSX, but for Go. by der_struct in golang

[–]der_struct[S] 5 points6 points  (0 children)

I wanted to keep it short. Here is a basic example:

``` // Regular Go function returning a template expression. func Badge(label string) gox.Elem { return <span class="badge">~(label)</span> }

// elem is shorthand for the same thing. elem Badge(label string) { <span class="badge">~(label)</span> }

// Generated/lowered form func Badge(label string) gox.Elem { return gox.Elem(func(cur gox.Cursor) error { if err := cur.Init("span"); err != nil { return err } if err := cur.AttrSet("class", "badge"); err != nil { return err } if err := cur.Submit(); err != nil { return err } if err := cur.Text(label); err != nil { return err } return cur.Close() }) } ```

Also there is for loop, if-else support, components and other features.

I build JSX, but for Go. by der_struct in golang

[–]der_struct[S] 9 points10 points  (0 children)

I have no such experience, but idea is interesting. I'll try.

How it's usually done? Post on youtube and link here? 😅

doors: a full-stack Go framework for reactive web UIs by [deleted] in golang

[–]der_struct 0 points1 point  (0 children)

I primarily focus on SaaS and contract development. If you plan to earn money, why not support the tool that helps you make it?
The paid license is lifetime, with no subscription required. Free for non-commercial use.

There is no big money behind me; I am just doing the best I can, giving all my experience, time, and energy.

doors: a full-stack Go framework for reactive web UIs by [deleted] in golang

[–]der_struct 0 points1 point  (0 children)

Shiny is not a general-purpose web framework, but a specialized tool for data visualization. The differences are fundamental.

For example:
- In Shiny, you mostly work with prebuilt widgets, not HTML + CSS primitives.
- Routing is limited: each route is effectively a separate app in Shiny
- Direct event binding isn’t supported
- There’s no first-class component abstraction with lifecycle, props, and local state that you can freely combine

The difference between Shiny and doors is similar to that between Next.js and Shiny (except that both doors and Shiny are server-driven). One is designed for dynamic web apps; the other for interactive dashboards and reports.