Lissome
View SourceLissome is a library to integrate the Gleam frontend framework Lustre with Phoenix Live View.
[!WARNING] This project is on early stage of development and breaking changes are expected.
Setup
First, make sure you have the Gleam compiler installed. Instructions can be found here
We will use a tool called
mix_gleam
to manage a Gleam project with Mix. Follow the instructions to setup it.Add
lissome
to yourmix.exs
file:
def deps do
[
...,
{:lissome, "~> 0.2.0"},
]
end
- Create a
gleam.toml
file with your Gleam dependencies:
name = "your_app_name"
[dependencies]
gleam_stdlib = ">= 0.44.0 and < 2.0.0"
lustre = ">= 4.6.3 and < 5.0.0"
[dev-dependencies]
gleeunit = ">= 1.0.0 and < 2.0.0"
- Run:
mix deps.get
gleam deps download
[!NOTE] Although
mix_gleam
is able to install Gleam dependencies, it doesn't manages dependencies well outside Erlang target. For that reason, we useagleam.toml
file and the Gleam tooling to manage Gleam dependencies.
Usage
To render a Lustre app, we need to define a Gleam module that contains a public main
function. This function must start a Lustre app created with the lustre.simple
function.
//// src/hello.gleam
pub fn init() {
...
}
pub fn update(msg, model) {
...
}
pub fn view(model) {
...
}
pub fn main() {
let app = lustre.simple(init, update, view)
let assert Ok(_) = lustre.start(app, "#app", Nil)
Nil
}
Now, inside HEEX
we can render it using the lustre
component:
defmodule MyApp.MyLiveView do
use MyApp, :live_view
import Lissome.Component
def mount(_params, _session, socket) do
{:ok, socket}
end
def render(assigns) do
~H"""
<div>
<div>Content rendered with Phoenix Live View</div>
<div>
<.lustre id="app" name="hello" />
</div>
</div>
"""
end
end
Check out the project in the example
directory for a complete code example.
SSR
Thanks to the ability of Gleam to compile to both Erlang and JavaScript, we can do server-side rendering of Lustre without having to install Node.js. This is why Lissome
has SSR enabled by default, but you can disable it by passing ssr={false}
to the lustre
component.
Keep in mind that Lissome
will call the init
and the view
functions of your Gleam module in order to render the initial HTML. By default Lissome
will look for functions with that name in your module. If you happen to named them differently, you can pass to the lustre
component init_fn
with the name of your function responsible for initializing the model and view_fn
with the name of your function responsible for rendering the view. Also, both functions must be public.
<.lustre
id="app"
name="hello"
init_fn="my_init_function"
view_fn="my_view_function"
/>
Use cases
In my experience, many part of the UI in Phoenix apps could be done with Phoenix LiveView
; even for parts that are heavily interactive we have ways to build components like modals using JS commands and perform optimistic updates by combining JS commands and Tailwind CSS classes.
However, there are still parts of the UI that are very complex to implement in Phoenix LiveView
, often because they have a non-trivial client-side state.
In that situations, we could use Gleam and its fronted framework, Lustre, as they are well suited to handle that kind of state in a simple way. Also, Gleam has interopability with Elixir and both shares many concepts, such as immutability, functional paradigms and pattern matching.
Lissome
is designed to address only the gaps of Phoenix LiveView
when it comes to client-side state.
Roadmap
- [ ] Improvements to the SSR.
- [ ] Gleam's helpers for communicating with Phoenix LiveView and supporting Lustre's effects.
- [ ] Hot module replacement for Gleam.
- [ ] Support for
LiveJson
. - [ ] Support for Lustre's
server components
.