<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="386589" data-post-id="386589">
  <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">
								<p>Fwiw I agree 100%.</p>
<p>Instant just posted more info on their approach. Granted they make a bunch of different tech choices (triple stores, clojure, etc) but there are some similarities and the spirit of their DX is nice.</p>
<aside class="onebox allowlistedgeneric" data-onebox-src="https://www.instantdb.com/essays/architecture">
  <header class="source">
      <img src="https://www.instantdb.com/img/icon/favicon-196x196.png" class="site-icon" alt="" width="196" height="196">

      <a href="https://www.instantdb.com/essays/architecture" target="_blank" rel="noopener nofollow ugc">instantdb.com</a>
  </header>

  <article class="onebox-body">
    <div class="aspect-image" style="--aspect-ratio:690/617;"><img src="https://www.instantdb.com/img/essays/architecture.jpg" class="thumbnail" alt="" width="690" height="617"></div>

<h3><a href="https://www.instantdb.com/essays/architecture" target="_blank" rel="noopener nofollow ugc">A backend for AI-coded apps</a></h3>

  <p>Instant 1.0 is out! This essay shows a bunch of demos, to explain why we think Instant is the best backend for AI-coded apps. We also cover the architecture that makes all of it work.</p>


  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>
 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="386589" 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/designing-local-first-features-for-hologram-whats-your-dream-dx/74862/32">Post #31</a>
	                </div>
	            </div>
              <div id="likers-container-386589" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="386589"
                     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 #31"></div>
  </section>
</div>
    <div class="postbit" id="386874" data-post-id="386874">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hey, <a class="mention" href="/u/bartblast" rel="nofollow">@bartblast</a></p>
<p>The underlying architecture I’m proposing does not conflict with these concerns you’ve raised, IMO.</p>
<aside class="quote no-group" data-username="bartblast" data-post="31" data-topic="74862">
<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><strong>Server-authoritative doesn’t mean client-passive.</strong> These aren’t mutually exclusive - the server can remain the final arbiter of truth while the client runs the same logic locally for instant validation and offline autonomy.</p>
</blockquote>
</aside>
<aside class="quote no-group" data-username="bartblast" data-post="31" data-topic="74862">
<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><strong>Hologram has a unique advantage we could leverage here.</strong> Hologram compiles Elixir to JavaScript - so for most cases, the same business logic that runs on the server can run on the client.</p>
</blockquote>
</aside>
<p>I hundred percent agree. As per the example in my original post, <code>MyApp.Support.Ticket.open(subject)</code> runs the same validation fully on the client when you call it from the action. That’s Hologram’s Elixir-to-JS compilation doing its thing.</p>
<aside class="quote no-group" data-username="bartblast" data-post="31" data-topic="74862">
<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><strong>DX.</strong> The developer still writes to the local store <strong>and</strong> dispatches a command. I think that’s boilerplate that could be eliminated</p>
</blockquote>
</aside>
<p>Syntactic sugar can take care of this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">MyApp.Support.Ticket.open(subject, sync: true)  # Writes locally + dispatches a command under the hood
MyApp.Support.Ticket.open(subject, sync: false) # Writes locally only, no server sync

# This can default to whichever makes sense for Hologram
MyApp.Support.Ticket.open(subject)
</code></pre>
<p>The framework creates a simple command underneath and handles command dispatch for <code>sync: true</code>.</p>
<p>I consider the <code>Hologram.Extension.IndexedDb</code> in my original post and the Hologram sync protocol you earlier suggested as syntactic sugar for the simple case where <code>Ticket</code> (the server-side resource + validation) and <code>TicketStore</code> (the client-side store) overlap cleanly and are glued together into <code>Ticket</code>.</p>
<aside class="quote no-group" data-username="bartblast" data-post="31" data-topic="74862">
<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>Command-sync is simpler to build but pushes boilerplate and edge cases onto the developer - managing the two-step writes, handling deferred validation errors, reasoning about uncertain optimistic state, etc.</p>
</blockquote>
</aside>
<p>I don’t view this as “pushing” to the developer. Once again, almost every common case we anticipate can be layered with syntactic sugar on the underlying architecture, while allowing the developer complete control when they need to look under the hood and handle things in interesting ways. The point is: the underlying architecture is command-sync, and that difference matters when the developer needs to step outside the happy path.</p>
<p>One more thought: handling commands when the app is offline is already a problem Hologram has to solve. What happens right now if a user triggers an action that dispatches a command while disconnected? There’s presumably already a queue or retry mechanism in place (or planned). Command-sync simply formalises and extends that existing pattern into a full offline story.</p>
<aside class="quote no-group" data-username="bartblast" data-post="31" data-topic="74862">
<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>Queued commands are also tied to the version of business logic that created them - a schema or code migration while the user is offline means those commands replay against a server they weren’t written for.</p>
</blockquote>
</aside>
<p>This is a real concern, but it’s not specific to command-sync. Regardless of the approach, offline-capable apps will always need to deal with schema or code migrations that happen while a user is disconnected. Simple cases can come with pre-packaged Hologram solutions e.g. versioning, where the server knows how to handle or reject stale versions gracefully. More complex cases are genuinely hard, and perhaps the developer <strong>should</strong> actually think about them, but they’re hard for every offline architecture.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="386874" 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/designing-local-first-features-for-hologram-whats-your-dream-dx/74862/33">Post #32</a>
	                </div>
	            </div>
              <div id="likers-container-386874" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="386874"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>