bartblast
Composability Patterns for Hologram - Looking for Your Ideas
I recently started a discussion about reactive patterns in Hologram, but I realized I need to step back and design the composability architecture first - the reactive patterns should fit within that broader framework.
Quick Context on Hologram
Hologram is a framework that compiles Elixir to JavaScript, letting you write isomorphic web applications entirely in Elixir. Components can run on both client and server.
Currently, a Hologram component is represented by a Component struct containing:
- State - the component’s data
- Emitted context - data passed down to child components
- Next operations - instructions for what should happen next (e.g., “run action X”)
Components can define:
- Actions - functions that run client-side and update local state
- Commands - functions that execute on the server
However, don’t feel constrained by this - I’m open to completely different approaches.
The Challenge
We’ll likely need some reactive patterns - things like:
- Memoization/derived state
- Effects (à la React’s
useEffect) - Watchers (à la Vue)
Or maybe something completely different! These are just examples from other frameworks.
In React, hooks provide elegant composability:
// Extract reusable logic
function useToggle(initialValue = false) {
const [value, setValue] = useState(initialValue);
const toggle = () => setValue(v => !v);
return [value, toggle];
}
// Compose it:
function Panel() {
const [isOpen, toggleOpen] = useToggle(false);
return (
<div>
<button onClick={toggleOpen}>Toggle</button>
<div>{isOpen ? 'Open' : 'Closed'}</div>
</div>
);
}
What I’m Looking For
How could actions, state operations, reactive patterns, and other patterns compose in Hologram?
Due to Elixir’s functional/immutable nature, the patterns will likely manifest differently than in React/Vue. That’s the interesting part!
Show me your ingenuity and creativity - every idea matters, no matter how unconventional or silly you think it is. Everything is on the table:
- Function composition
- Macros
- Explicit or implicit namespacing
- Flat keys
- Mixins
- Something else entirely?
Also worth noting: Hologram has compile-time access to the full call graph, which could potentially help solve this problem (though it doesn’t have to).
What patterns would you explore? Feel free to share anything from high-level ideas to concrete code examples or even full system designs.
Most Liked
AstonJ
Bit off-topic for the thread but I’ll quickly respond.
While I would agree that following your heart/what feels right is generally a good way to go I also really like how Bart has been seeking feedback on things he feels might benefit from it ![]()
It helps people feel like what they want matters and often leads to comments like this:
It’s something which plays a role in project confidence and helps create a deep and personal affiliation.
I would go as far as to say Hologram, and the way Bart has been involving everyone (/his meticulous attention to these kinds of details) has all the hallmarks of it potentially obtaining that all-elusive cult status
(This won’t just be good for Bart or Hologram, but for the entire Elixir community).
Back on topic, I don’t have any specific thoughts myself other than saying I hope whatever Bart decides echoes his goal of making Hologram as easy (natural and intuitive) and enjoyable to use as possible.
bartblast
While I do make the final decisions based on what feels right, I’ve learned that designing in isolation would likely create a project perfect for some past version of me, but not necessarily for the broader community. Hologram has grown beyond just my personal project - there’s already a growing number of projects using it, including in production. The broader success of Hologram means more Elixir use cases and potential new jobs for the ecosystem.
I hear you both on this. The challenge is that after 5+ years, nearly 10k commits and 1M lines of code, the project has real inertia. Changing core APIs at this stage isn’t a quick iteration - it’s measured in months of work, especially with plans for component libraries and other tooling that depend on these decisions. I don’t have infinite time to experiment, which is exactly why I’m being deliberate about these crucial architectural choices now.
To be clear, I’m not trying to please everyone - I’m trying to understand the solution space and how different patterns might serve real use cases. The feedback here helps with that, even if the final direction is my call.
derek-zhou
I think you are thinking too much. Honestly, nobody else matters, it is your project, so do whatever your heart lead you to. If I were you, I will just pick the path that require the least amount of work, as long as it does not prevent you from picking a more adventurous path later. You can have breaking changes! you can have multiple APIs!
Popular in Discussions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








