Change JSX output from React to SolidJs?

hi everyone, is it possible to change jsx compiled code from React to SolidJs?

14 Likes

I’m very much interested in this as well. I think Solid is a very interesting framework, not only because of performance but first and foremost because it has hooks-like API without the stale closure problem. We probably won’t have a solid (pardon the pun) story for statically checking the rules of hooks, and anyway, after a couple of years, I still find hooks rather hard to reason about, so getting read of that accidental complexity could be really nice.

The problem is that both ReScript and Solid include compilation steps (and not just typechecking). There’s a (closed) issue in the compiler repo requesting keeping JSX as is and allowing the Solid compiler to do all the compilation, but that, I presume, is not possible. This means some work is required on the team’s (mostly, on @hongbo’s :sweat_smile:) part. I’m sure they have quite enough on their plate already, yet SolidJS compatibility looks extremely attractive, so it would be terrific to see it happen!

4 Likes

I agree that ReScript should be framework agnostic, so user doesn’t stuck with React, and more user will adopt ReScript.
yet NextJS, still insist to use Webpack.
mention here:

instead they make NextJs Live
which is cool, but i don’t want to code in the browser.

2 Likes

I won’t go into NextJS decision (a quick 2 cents: I’d like to see them adopt Vite, but I can see why they’re conservative). At the end of the day, I think NextJS is a third-party problem. If the community wants to bind to some other React-based problem, it can, and therefore it should because the team is busy otherwise.

But the community cannot solve Solid JXS compatibility. We need the compiler changes for that. What we can do, if we’re interested enough (am I interested enough? :thinking:) is to try and experiment with ReScript, Solid and Hyper expressions (even if the lack of Solid compilation means unoptimized code). That way, the community can validate some parts of Solid approach, create some bindings and, if all goes well, pave the way for full Solid support.

You can always implement your own React module with your own definition of createElement, createVariadicElement etc. There are users out there that e.g. created their own Preact bindings instead. Probably not ideal that the module is called React, but this is something that could potentially be improved in a future react syntax extension version? Not sure.

Yes, but the problem is, that’s not what Solid compiles JSX to.

1 Like

I am aware of that. Just saying that our builtin react JSX transform is coupled to an interface that can practically be adapted (at least this works for react like frameworks).

Since Solid is way different, this doesn’t work obviously.

3 Likes

I am eagerly watching vite-plugin-ssr.

Also, I personally would be interested to see the opposite direction, where instead of ReScript becoming more general purpose, that it becomes more wedded to one framework and starts to implement it’s own ecosystem around it, like Elm.

I tried a few things. First I tried integrating svelte. Then tried a few simple libs and then also Solid. All things had ppx’es involved. Then I just tried it without any ppx and lib. So just define a Html module with a div function, parse props and apply children. Somehow I really liked that. Simple and easy, if there would just be an easy way to give all my functions the same props… My dream would be to just write normal html like jsx in rescript, integrate some ppx for class checking and a simple reactive store.

I also thought about compiling rescript jsx to GitHub - BuilderIO/jsx-lite: Write components once, run everywhere. Compiles to Vue, React, Solid, Angular, Svelte, and Liquid.

8 Likes

Nice idea, @adrianhunter. I didn’t know this exists.

I just found this thread. There has been some work to create a babel plugin that converts a function (similar to react.createElement) into JSX that can be fed to the solid compiler. The barriers to making this happen are twofold. First, we need to write a ppx that will convert JSX to calls to this function. The second barrier is to create rescript bindings for the SolidJS API. I’m not capable of doing either of these (nor is anyone else on the Solid team, I believe). Should anyone attempt the above, however I will be happy to assist.

Edit: all this is to say, that it is possible to Solid/rescript compatibility without any compiler changes, what we need is a custom PPX for JSX, and the appropriate types/function bindings.

5 Likes

Note that Solid has h (hyperscript) API that can be used here instead of React API. It won’t be as fast for during setup, but after setup it should be as fast as regular Solid JSX.

Example code is something like:

const view = h('div', [
  h('p', h('span', 'Hello'))
], {style: "color: red;"})

(I didn’t verify if that works, but you get the idea).

So you can at least make it output h-compatible code. You might have to import it and re-export as createElement.

3 Likes

FYI someone got Rescript+HyperScript partially working in a gist here.

3 Likes

@Hongbo I think ReScript should be able to output the JSX, instead of React.createElement.

To more output closely output JS how it would have been hand-written in a real life setting (most if not all would use Babel to transform the JSX anyway). It improves the escape hatch to JS, since rewriting a bunch of React.createElement to JSX would be a lot of work if you decide to move back to pure JS/TS. It would have the side benefit of improving compatibility with SolidJS and other compilers that take JSX as input.

11 Likes

Hey! Just bumping this thread as I’m looking for this use case as well (ReScript + SolidJS)! I think ReScript should aim to be flexible and not rely solely on React as the only frontend framework it supports. The web moves too fast to be that strict.

10 Likes

While I would also prefer the variant, that the compiler optionally outputs JSX directly, I made a test with the proposal from @ryyppy to replace the createElement and createElementVariadic function.
And it worked pretty well.

These bindings allow the usage of solidJs in conjunction with JSX: https://github.com/Fattafatta/rescript-solidjs

You can also find a more elaborate explanation on how it actually works here github discussion.

4 Likes

This is a thread where emitting jsx directly can be explored: JSX v4 & next rescript-react 0.10.x - #12 by cristianoc

Is it correct that solidjs support would then come for free, as well as enabling a few things on react that createElement does not provide?

How about compatibility with older react versions? Is that something one should worry about?

Is there something else that direct jsx would enable supporting, besides SolidJs? If not, what else is missing, and are there opportunities to support more.

Direct JSX support is essential to SolidJS (as it applies its own JSX transform that is very different from the React JSX transform) However all the bindings should be done for sure.

Moreover, direct JSX support would also enable supporting Vue (with JSX) much smoother, and will probably make it easier for users to migrate away from ReScript :laughing:

Edit: Looks like enough amount of bindings are available in rescript-solidjs

What are the expectations for the generated code?
jsx calls / _jsx calls, without any imports?

Or is the idea to support something like TypeScript’s jsx preserve mode?