<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="376832" data-post-id="376832">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="AstonJ" data-post="5" data-topic="73073">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/astonj/48/15_2.png" class="avatar"> AstonJ:</div>
<blockquote>
<p>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 <img src="https://forum.elixirforum.com/uploads/default/original/2X/4/425cf8a2af1868cc834c0a12b6f0c9ef0e530de9.gif?v=15" title=":icon_biggrin:" class="emoji emoji-custom" alt=":icon_biggrin:" loading="lazy" width="20" height="20"></p>
<p>It helps people feel like what they want matters and often leads to comments like this:</p>
<aside class="quote no-group" data-username="garrison" data-post="10" data-topic="72968">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"><a href="https://forum.elixirforum.com/t/signals-computed-properties-and-other-reactivity-patterns-in-hologram/72968/10" rel="nofollow">Signals, computed properties and other reactivity patterns in Hologram</a></div>
<blockquote>
<p>BTW, your dedication to responding to feedback on here is amazing. Don’t think it goes unnoticed!</p>
</blockquote>
</aside>
<p>It’s something which plays a role in project confidence and helps create a deep and personal affiliation.</p>
<p>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 <img src="https://forum.elixirforum.com/uploads/default/original/2X/d/d6aafab20efae12a589086d31e135401088e8cf1.gif?v=15" title=":icon_cool:" class="emoji emoji-custom" alt=":icon_cool:" loading="lazy" width="20" height="20"> (This won’t just be good for Bart or Hologram, but for the entire Elixir community).</p>
</blockquote>
</aside>
<p>Wow, thank you! <img src="https://forum.elixirforum.com/images/emoji/apple/blush.png?v=15" title=":blush:" class="emoji" alt=":blush:" loading="lazy" width="20" height="20"> I’ll admit I overthink things constantly (just ask anyone who knows me), but at least it’s paying off in ways that matter. The cult status thing made me laugh though - let’s see if we can earn it!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376832" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/composability-patterns-for-hologram-looking-for-your-ideas/73073/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-376832" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376832"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="376836" data-post-id="376836">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="jam" data-post="7" data-topic="73073">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jam/48/36266_2.png" class="avatar"> jam:</div>
<blockquote>
<p>I think it depends on the overarching goal and vision for Hologram. Zooming out for a second, it seems like these design decisions are mainly influenced by these opposing forces:</p>
<ol>
<li>Offering complete control and explicitness</li>
<li>Abstracting complexity and optimizing for ergonomics</li>
</ol>
<p><span class="hashtag-raw">#1</span> seems to generally lead to verbosity but you as the engineer have full control over how things work. <span class="hashtag-raw">#2</span> generally results in having to write less code but more trust in the framework. If we’re keeping in line with Hologram’s goal to make web dev simple, then I think it should lean more heavily into <span class="hashtag-raw">#2</span> even if it means sacrificing some sense of control.</p>
</blockquote>
</aside>
<p>Great insight, <a class="mention" href="/u/jam" rel="nofollow">@jam</a>! I completely agree with your framing of these opposing forces.</p>
<p>What’s interesting is that this tension probably maps quite directly to the macro question: <span class="hashtag-raw">#1</span> (complete control and explicitness) likely means minimal or no macros, while <span class="hashtag-raw">#2</span> (abstracting complexity) would lean heavily on macros.</p>
<p>This puts me in a tricky position. The Elixir community has historically been quite reluctant about macro-heavy APIs, and for good reason - explicitness is one of the core values that attracts people to Elixir in the first place. You can see this playing out with Ash Framework right now. It’s extremely macro-heavy, which lets it elegantly solve complex problems and reduce boilerplate dramatically. But that same characteristic creates polarized opinions: some developers swear by it because of the power and conciseness, while others can’t get past all those macros because they value explicitness and direct control.</p>
<p>If I go the macro route with Hologram, I’d likely deter a significant portion of Elixir developers who prioritize that explicitness. On the other hand, macros could eliminate a lot of the plumbing code and enable powerful compile-time analysis (which Hologram is uniquely positioned to leverage with its full call graph visibility).</p>
<p>The challenge is that Hologram’s North Star is developer experience (DX), but that means different things to different people in this context - and that’s exactly the problem. For some developers, great DX means explicitness and control: no magic, always clear what’s happening under the hood. For others, great DX means less boilerplate and cognitive load: abstractions that “just work” and let you focus on your application logic. Both are valid perspectives on what makes development enjoyable and productive.</p>
<p>So I can’t simply say “optimize for DX” - I need to decide which developer experience I’m optimizing for, knowing that choice will resonate strongly with some developers while alienating others.</p>
<p>The question is: does it even make sense to look for middle ground here? Or would that middle ground end up being the worst of both worlds - not explicit enough for the control-oriented developers, yet not ergonomic enough for those seeking simplicity? You’d potentially end up with something that doesn’t fully satisfy either group.</p>
<p>That said, there are counter-examples. Phoenix’s routing DSL and Plug’s pipeline builder are heavily macro-based, yet they’ve been widely accepted by the Elixir community. Maybe the key is whether the abstraction feels “worth it” - whether what you gain justifies the magic you’re accepting.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376836" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/composability-patterns-for-hologram-looking-for-your-ideas/73073/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-376836" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376836"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="376839" data-post-id="376839">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="jam" data-post="7" data-topic="73073">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jam/48/36266_2.png" class="avatar"> jam:</div>
<blockquote>
<p>I think the main area that wouldn’t fall directly inside of a component would be some sort of shared store. I typically reach for stores seldomly though, most of my composition is done with components.</p>
<p>Currently, for a store in Hologram, it looks like I’d use <code>Context</code>. If I wanted a global store, I suppose I’d have a <code>Context</code> at the app’s root (if I have this wrong, let me know). It might be nice to be decouple a store completely from a component and be able to use them in any component (maybe this is already possible?).</p>
</blockquote>
</aside>
<p>Just to clarify - <code>Context</code> isn’t really meant to be a store. It’s for avoiding prop drilling by letting components emit data that flows down to their children (who access it via props with <code>from_context</code>).</p>
<p>You could use <code>Context</code> at a page level as a “global store” and mutate it from anywhere by specifying the action target, but it would feel awkward/indirect. <code>Context</code> is component-bound, like React’s Context API. It’s not a decoupled store like Redux or Svelte stores.</p>
<p>I think what you’re describing - a truly decoupled store - is what <a class="mention" href="/u/nikfp" rel="nofollow">@nikfp</a> mentioned earlier too. I’d love to see what that would look like translated to Hologram if you have ideas!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376839" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/composability-patterns-for-hologram-looking-for-your-ideas/73073/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-376839" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376839"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="376840" data-post-id="376840">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="nikfp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/nikfp/120/37207_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  nikfp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="bartblast" data-post="11" data-topic="73073">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/48/17647_2.png" class="avatar"> bartblast:</div>
<blockquote>
<p>I’d also love to explore how Svelte stores would translate to Hologram, and how these concepts could enable composability patterns. Would you be interested in showing a simple code example of how you’d imagine this in Hologram?</p>
</blockquote>
</aside>
<p>I’d like to take a stab at what the usage would look like on this, if at least to inform my opinions better. Let me cook a while and I’ll reply again with what I come up with.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376840" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/composability-patterns-for-hologram-looking-for-your-ideas/73073/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-376840" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376840"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="376841" data-post-id="376841">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Lucassifoni" data-post="8" data-topic="73073">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lucassifoni/48/39057_2.png" class="avatar"> Lucassifoni:</div>
<blockquote>
<p>Users act on state via LiveView’s handle_events, that call a public API exposed by the pure state modules to update the sockets, then LiveView re-renders.</p>
<p>But programs can build up state outside of components by creating and calling the pure state module’s public API in isolation, then just ask LiveView for a single render of the built up state.</p>
<p>There’s still coupling since those pure state modules represent UI state, not application state, ( UI_state = fn(app_state, user_or_robot_intents) if you wish) but being able to handle them inside or outside components is very valuable to me. That and the ability to compose smaller state into bigger state.</p>
</blockquote>
</aside>
<p>This sounds interesting, would you mind sharing a simplified example of how you structure and compose these state modules?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376841" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/composability-patterns-for-hologram-looking-for-your-ideas/73073/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-376841" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376841"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="376921" data-post-id="376921">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="jam" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jam/120/36266_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  jam
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="bartblast" data-post="13" data-topic="73073">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/48/17647_2.png" class="avatar"> bartblast:</div>
<blockquote>
<p>Maybe the key is whether the abstraction feels “worth it” - whether what you gain justifies the magic you’re accepting.</p>
</blockquote>
</aside>
<p>Yep, I agree. It’s funny too because I had the same two examples in mind (Ash and Plug / Router). IMO, it’s possible to keep macros to a minimum where they truly impact ergonomics for the better and offer some unique capabilities. I’d imagine there’s probably something on the order of a handful of macros max that would fall in that category.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376921" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/composability-patterns-for-hologram-looking-for-your-ideas/73073/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-376921" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376921"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="376932" data-post-id="376932">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="bartblast" data-post="10" data-topic="73073">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/48/17647_2.png" class="avatar"> bartblast:</div>
<blockquote>
<p>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.</p>
</blockquote>
</aside>
<p>Indeed, but it’s also the cost of getting things right. To again use React as an example, they essentially redesigned the entire thing (backend and frontend) with fiber/hooks after about 5 years. Post-hooks React may as well have been a new framework. Honestly, the fact that they got away with pretending it <em>wasn’t</em> a new framework is kinda hilarious. They <em>did</em> go out of their way to maintain backwards compatibility and interop, which is impressive. Presumably that was a business requirement.</p>
<p>I stand by what I said: you can either spend years on this stuff or copy the things that already work, recognizing that those things have been through years of evolution already and that is, in fact, <em>why</em> they work. Personally I choose to do a lot of copying because I don’t have infinite resources, but if you want to greenfield stuff I have nothing but respect for that. It just takes a while!</p>
<p>WRT the macro discussion, I don’t really have anything against macros. I <em>do</em> like the expressive power of a real programming language, but I think that’s actually orthogonal. My concern, which I have probably already expressed enough, is that the direction you’re proposing is equivalent to creating a new programming language in Hologram. It may not seem like it now, but I think it would end up that way. So the question becomes: is your programming language going to be good? And if you haven’t even accepted that you <em>are</em> rolling your own programming language, the answer is almost certainly going to be “no”. This is the curse of DSLs.</p>
<p>One more thing: Hologram’s raison d’etre as I understand it is to be “Elixir on the client”. If you lean too heavily into a DSL, <em>even if that DSL is good</em> you are working against that mission. That could be a branding problem.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376932" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/composability-patterns-for-hologram-looking-for-your-ideas/73073/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-376932" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376932"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="376933" data-post-id="376933">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Can you explain in more detail what you mean with the call graph stuff? Is the call graph static? What happens if I try to make a function call dynamically?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376933" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/composability-patterns-for-hologram-looking-for-your-ideas/73073/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-376933" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376933"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #18"></div>
  </section>
</div>
    <div class="postbit" id="376966" data-post-id="376966">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Lucassifoni" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Lucassifoni/120/39057_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Lucassifoni
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I fear it isn’t, my work is deep in the depths of what I call officetech or boringtech <img src="https://forum.elixirforum.com/images/emoji/apple/grinning_face_with_smiling_eyes.png?v=15" title=":grinning_face_with_smiling_eyes:" class="emoji" alt=":grinning_face_with_smiling_eyes:" loading="lazy" width="20" height="20"> .</p>
<p>Most of my work involves tools that produce book-like or slides-like material, with a data structure that is tree-like, but their physical projection is a flat list of pages in the end. Or a list / tree of such documents, but a single document ends up a flat list. Backend state is nice to interact with programmatically and frontend state is nice to interact with from an user’s point of view. Both are linked but very different. Users acting on the tree model would be an horrible UX and interacting with the flat model programmatically would be horrible DX.</p>
<p>So it simply is deeply nested structures of very simple Elixir structs + their management functions. The UI is a function of the tree structure by the frontend framework (Vue* in my case - a bit of a regret). The frontend sends events to the backend through websockets, applies optimistic updates, then applies partial or full updates from the backend’s answers, to the projected state.</p>
<p>Re : composition, I liked the spreadsheet-like example I shared in the other thread because of an explicit composition operation where a sub-graph’s outputs could become a wider graph’s inputs. I will see if that stands the test of time and resists to feeding a bigger UI.</p>
<p>To summarize it, I am posting in those threads because I am looking for ideas about interesting state managment and transition patterns, fully isolated from the UI.</p>
<p>Sorry, it’s a bit confused, because I am actively thinking about different re-structures and a bit “in the depths” of it these days.</p>
<p>(*Well Vue or Liveview depending on acceptable latency)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376966" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/composability-patterns-for-hologram-looking-for-your-ideas/73073/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-376966" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376966"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #19"></div>
  </section>
</div>
    <div class="postbit" id="376981" data-post-id="376981">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="bartblast" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/bartblast/120/17647_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  bartblast
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Hologram</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="garrison" data-post="18" data-topic="73073">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/letter_avatar_proxy/v4/letter/g/3bc359/48.png" class="avatar"> garrison:</div>
<blockquote>
<p>I stand by what I said: you can either spend years on this stuff or copy the things that already work, recognizing that those things have been through years of evolution already and that is, in fact, <em>why</em> they work. Personally I choose to do a lot of copying because I don’t have infinite resources, but if you want to greenfield stuff I have nothing but respect for that. It just takes a while!</p>
</blockquote>
</aside>
<p>I appreciate the perspective, but I want to clarify - I’m not choosing to greenfield for its own sake. The reality is I <em>can’t</em> simply copy React or Vue patterns because they’re deeply tied to mutable, object-oriented architectures.</p>
<p>React Server Components (Next.js) might seem relevant, but that architecture is ridiculously complex - it requires distinguishing “use client” vs server components, managing serialization boundaries, handling two separate component models, and coordinating between them. It’s essentially a retrofit onto React’s client-centric design.</p>
<p>Take React hooks specifically as an example of patterns that don’t translate:</p>
<ol>
<li>
<p><strong>Architectural mismatch</strong> - Hooks rely on hidden mutable state in React’s fiber tree. The render function <em>pretends</em> to be pure (<code>props → JSX</code>), but secretly accesses and mutates global framework state. In Elixir, you’d need explicit Agents/GenServers, making this hidden complexity visible and fundamentally changing the architecture.</p>
</li>
<li>
<p><strong>Rules of Hooks</strong> - Call order dependency (can’t use hooks conditionally) exists because React identifies hooks by position, not semantically. This fights against natural Elixir pattern matching and control flow.</p>
</li>
<li>
<p><strong>Testing complexity</strong> - You can’t just call a component function and test it. You need <code>act()</code> wrappers to coordinate async updates, React Testing Library to provide runtime context, and complex state setup just to test what should be simple render logic.</p>
</li>
<li>
<p><strong>Initialization vs. rendering separation</strong> - Hologram explicitly separates <code>init()</code> (runs once to set up initial state) from <code>template()</code> (a pure function that transforms state/props into DOM). React hooks deliberately interleave these - your component function runs on every render, re-executing hook initialization logic that relies on call-order tracking to “remember” state. This interleaving is core to the hooks design, but it’s fundamentally incompatible with Hologram’s architecture where state is explicit data, not implicit framework-tracked position.</p>
</li>
</ol>
<p>I was genuinely hoping someone would enlighten me on how to elegantly port these patterns while addressing these concerns. But the more I examine it, the more it seems like forcing a square peg into a round hole. Patterns that work in JavaScript with mutable objects don’t translate cleanly to Elixir’s immutable, functional paradigm.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="376981" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/composability-patterns-for-hologram-looking-for-your-ideas/73073/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-376981" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="376981"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #20"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/73073/load_more?page=3">Load more posts (20 remaining)</a>
</div></template></turbo-stream>