That said, in all honesty, I would advocate for a redesign.
The concept to keep in mind is to think of JavaScript as a virtual machine for the browser. Then, ElixirScript should build on top of JavaScript in the way Elixir builds upon Erlang. This means that if I put JS in an EXJS file, the JS will work (interoperability). So ElixirScript is just the building block that converts Elixir to JavaScript. It shouldn’t have opinions.
Next, we use React as the structure for our JSX. React should be implemented as a behaviour. It should require a @spec render(props :: map, state :: map | pid)
function or macro that accepts a do:
block with JSX. If implemented as a string, there is already the syntax to interpolate Elixir code. Then the string can be converted to JS, which can handle the parsing. It would be nice to have a JSX linter for .ex
files though.
Beyond that, the React
behaviour should allow for optional lifecycle methods (e.g. mount
, unmount
), a constructor (maybe call it init
to follow Elixir convention), and I’d argue for an optional data
method, ideally modeled after Relay…
Last, I would suggest a documentation revamp.
A great starting point for using plain ElixirScript would be a socket.ex
in a Phoenix project. I’d love to see an example of this, or receive enough instruction from the documentation that I would know how to set this up for myself.
And a final note: I really like your implementation of state inside of a process. I think this is really powerful because then the backend and frontend can now share the same state (SEE: “Functional Web Development with Elixir” re: stateful servers). Add in Mnesia (in-memory database) and your React/React Native app will be faster than anything out there.
Reviewing React’s implementation notes, I definitely think the role of ElixirScript should simply be to convert Elixir to JavaScript. Likewise, React.EX should simply convert to React components.
I think you’ve already built those parts. I just want to see them refactored to be closer to the React experience.