Change JSX output from React to SolidJs?

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

1 Like

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?

It seems that handling JSX like the preserve option from TypeScript, is the best solution. It would enable to use Rescript without React.
Here is the docs from solids about typescript configuration.

2 Likes

I thought “direct JSX” means JSX preserve mode. If that means the new React 17 JSX transform thing, it doesn’t change anything related to SolidJS support.

2 Likes

Thanks it’s clear now.

1 Like

I’ve created an issue with a rough outline on how to explore implementing preserve mode.

This is going to be pretty much orthogonal to the ppx work on JSX, as likely this won’t run the ppx at all (unless some preparation work is required and that’s the right spot for it).

1 Like

That issue is open to contribution if someone is interested.

In terms of planning, an open question remains on what else should one consider supporting, in addition to SolidJs (and whatever else can take advantage of preserve mode).

1 Like

+1 on preserve mode. It’s the safest and most future proof bet imo. We can then specialize further as we see where the community goes with the support - is any of the other fws outside of React gaining traction with ReScript?

First class support, like for React, is very valuable because it means any ReScript project could theoretically skip using Babel. Less transforming, faster, etc. That doesn’t matter with something like SolidJs of course, where the whole SolidJs optimizer/compiler is a Babel plugin. But there might be other fws around that gain traction, that have the same characteristics as React, where first classing could be a huge performance gain. Time will tell!

7 Likes

Actually, first-class support for SolidJS is also a viable option, especially looking at other players like Bun implementing SolidJS JSX transforms natively. While I also agree that relying on the preserve option makes much more sense for now, IMO building a PPX for it will be pretty considerable one if the user group grows large enough.

3 Likes