bartblast

bartblast

Creator of Hologram

Hey there! There’s a new kid on the block! :smiley:

What is it?

Full stack isomorphic Elixir web framework that can be used on top of Phoenix.
https://github.com/segmetric/hologram

Inspired by

Elm, Phoenix LiveView, Surface, Svelte, Vue.js, Mint, Ruby on Rails.

How it works

To build your web app, you use basic Hologram blocks: pages, layouts and components.

Hologram builds a call graph of your code (which must follow some basic conventions) and determines which code is used on the client, and it then transpiles such code to JavaScript.

Because the state is kept on the client it makes the programming model simpler, and thanks to stateless or stateful components the app is easily scalable.

Code that is run on the client is encapsulated in “actions”, and code that runs on the server is encapsulated in “commands”. Actions can trigger commands, commands can trigger actions. Both actions and commands can be triggered directly by DOM events.

Client communicates with server through websockets - there is no boilerplate code to make it work, Hologram figures this out automatically.

What is already done

This is work in progress (although usable and used in production). To check what works and what is planned - take a look at the roadmap in the readme: GitHub - bartblast/hologram: Full stack Elixir web framework that intelligently compiles Elixir client-side code to JavaScript · GitHub

History / background

I tried to write this kind of framework first in Ruby, and I actually managed to create a working prototype, but the performance was not satisfactory. Then I tried Crystal, but it was very hard to work with its AST. Then I moved to Kotlin, but I realised that it’s better to use a dynamically typed language for that… Then I found Elixir in 2018 and fell in love with it. I started to work on Hologram in the summer of 2020.

Is it used in production?

Yes, it is used in Segmetric: https://www.segmetric.com/ Take a look at the “join beta” and “contact pages" which showcase form handling, or check the mobile menu. This all works on transpiled Elixir code! (But please, submit the forms only if you actually want to join the Segmetric beta or contact Segmetric - it is a live page, thanks!)

I want to see some code!

To see how Hologram app is structured, and see some actual code, take a look at the Hologram’s E2E modules: https://github.com/segmetric/hologram/tree/master/e2e

Basic example

defmodule MyPage do
  use Hologram.Page

  route "/my-page-path"

  def init do 
    %{
      count: 0
    }
  end

  def template do
    ~H"""
    <div>Count is {@count}</div>
    <button on:click={:increment, by: 3}>Increment by</button>
    <Link to={MyOtherPage}>Go to other page</Link>
    """
  end

  def action(:increment, params, state) do
    put(state, :count, state.count + params.by)
  end

  def command(:save_to_db, _params) do
    # Repo.update (…)
    :counter_saved
  end
end

# Action can return a new state, or a tuple {new_state, command, params}
# Command can return an action or a tuple {action, params}
# (This is similar to Elm architecture.)

I’m in the process of creating a basic website with installation guide. Let me know what you think about the project? What do you need to try it out? I will be glad to answer your questions :slight_smile:

Showing Posts 1 to 10

christhekeele

christhekeele

Interesting! What are you using to transpile Elixir, elixirscript?

tommica

tommica

Wow, this is really cool! Would love to see a “real” project with this to get an idea of how to structure things.

bartblast

bartblast OP

Creator of Hologram

@christhekeele I initially tried to use ElixirScript, but I couldn’t make it work. When I went through its GitHub issues I realized the creator stopped maintaining the project and focused all of his efforts on Lumen: Still alive? · Issue #495 · elixirscript/elixirscript · GitHub So I tried Lumen, but too much work was in progress. And now it looks that the project is stalled at the moment: Project Status · Issue #698 · GetFirefly/firefly · GitHub

I also tried another route: Erlang → PureScript → JavaScript through Erlscripten, Erlscripten – Transpiling Erlang to Javascript. Yes, you read it right - News and Announcements - æforum but I wasn’t convinced with it, because one of my goals was easy debugging of the transpiled code, and for that it helps if the transpiled code resembles what was actually written in Elixir.

So I decided to write my own transpiler, because that gives me much more control over the output code and I can fix any errors myself. I do this by first converting the code to AST, then building IR (intermediate representation) containing context and metadata, which makes it easier to reason about the code and finally the IR is encoded into JavaScript. You can take a glance at its structure here: hologram/lib/hologram/compiler at master · bartblast/hologram · GitHub

11
Post #3
bartblast

bartblast OP

Creator of Hologram

@tommica Thanks! :slight_smile: I’m building a website that will have a basic getting started guide with installation instructions. I’ve been also thinking about creating a basic demo project. Do you have any ideas for that?

derek-zhou

derek-zhou

Very cool. Can the pre-transpiled code run in elixir for testing purpose? One of the pain point of LV is that it is hard to do testing the cover the client side functionalities too.

bartblast

bartblast OP

Creator of Hologram

@derek-zhou If I understand correctly what you mean, then yes, it should be possible.
You could theoretically run the whole event loop in Elixir, e.g. some action triggers some command, which then triggers some other action, and the new state is used to rerender - all of this can be executed inside tests. You can also simulate some browser use without E2E tests, by triggering events directly (without the DOM) through tests. Is that what you meant?

Un3qual

Un3qual

Not sure if the goal was for the API to be closer to elm than elixir, but maybe action and command could be switched to handle_call and handle_cast to be closer to elixir conventions. Love the project btw

J3RN

J3RN

I love the route annotation (route "/my-page-path")! I wanted to do this for a toy framework I was working on, but the whole problem of how to aggregate those routes at compile-time (if you aggregate those routes at compile-time) is very non-trivial; I see you did quite a bit to accommodate that!

Also when I was investigating this, it was pointed out to me that any such work done at compile-time will not apply to “pages” added at runtime, e.g. by a hot code reload, unless you explicitly write some hooks to do that. Just some food for thought.

Good luck, I wish you tremendous success!

stevensonmt

stevensonmt

Any plans to split out the transpiler into a separate library?

derek-zhou

derek-zhou

Yes. Being able to run regression tests without needing a javascript counterpart or a fake browser is huge.

I am looking forward for a detailed write up of how to do this. Keep up with the good work!

Where Next? Top

Trending in News & Updates Top

sorenone
Today we’re releasing Oban for Python. Not an Oban client in Python. Not a pythonx wrapper embedded in Elixir. Nope, it’s a fully operati...
New
kip
I’m a bit excited to announce that Localize and friends are now at release 1.0. Even though it’s a 1.0 release, it stands on 8 years of w...
New
bartblast
Hologram v0.11 is out! Two headline features this release. First, Elixir regexes now run in the browser. They were server-only until now,...
New
nseaSeb
Just published search_ash 0.5.0 (with search_core 0.4.0) on Hex. What’s new: synonyms You can now declare a synonym dictionary per lang...
New
mudasobwa
After years of struggling I made StreamData dependency optional. Finitomata.ExUnit got testing primitives for Persistence. Full back co...
New
mudasobwa
MdexMultilineCells is an MDEx plugin enabling multi-line cells in Markdown tables with full inline/block Markdown rendering and automati...
New
sullyMusty
ActiveMemory 0.8.0 — in-memory tables that speak Ecto ActiveMemory 0.8.0 is now on Hex. ActiveMemory is an in-memory store built on ETS ...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews