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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yes, would be happy to take PRs. The testbed project primarily exists to facilitate automated end to end testing in CI via github actions, it may not be the best example project to look at. I have several other examples listed in the main README tho. Can you elaborate on some of the features from Storex and StateChannel you’d find useful?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273170" 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/client-side-rendering-server-side-state-statechannel/52709/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-273170" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273170"
                     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 #21"></div>
  </section>
</div>
    <div class="postbit" id="273179" data-post-id="273179">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="superchris" data-post="22" data-topic="52709">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/superchris/48/23484_2.png" class="avatar"> superchris:</div>
<blockquote>
<p>I have several other examples listed in the main README tho</p>
</blockquote>
</aside>
<p>these are for the webcomponents, do you have an react-example?</p>
<aside class="quote no-group" data-username="superchris" data-post="22" data-topic="52709">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/superchris/48/23484_2.png" class="avatar"> superchris:</div>
<blockquote>
<p>Can you elaborate on some of the features from Storex and StateChannel you’d find useful?</p>
</blockquote>
</aside>
<p>I did not really look into LiveState too much yet, so I do not know how you do it, but here are some points:</p>
<ul>
<li>StateChannel provides the state in a Context which is very nice and easy to use</li>
<li>StateChannel allows you to either transform and then diff the state on the server <strong>or</strong> you apply the JSONpatch primitives manually using <a href="https://github.com/amberbit/state_channel/blob/55f20820405278348f100c52a6c7130ef225d891/lib/state_channel/helpers.ex#L26" rel="noopener nofollow ugc">patch_state</a> which collects the patches in an array which is then send over the wire and the same time patches the server state (using JSONPatch). This skips the JSONDiff step.</li>
<li>Storex store acts as a <code>subscribable</code> that can be consumed by most frameworks, eg using <a href="https://www.solidjs.com/docs/latest/api#from" rel="noopener nofollow ugc">solid’s from</a>.</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273179" 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/client-side-rendering-server-side-state-statechannel/52709/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-273179" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273179"
                     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 #22"></div>
  </section>
</div>
    <div class="postbit" id="273184" data-post-id="273184">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Sebb" data-post="23" data-topic="52709" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sebb/48/21818_2.png" class="avatar"> Sebb:</div>
<blockquote>
<p>these are for the webcomponents, do you have an react-example?</p>
</blockquote>
</aside>
<p>I don’t just yet, I’m more interested in web components. In that case, checking out the test bed might be your best bet after all. It should run if you clone the live_state repo, going into the testbed directory and do the standard <code>mix deps.get</code> and <code>mix phx.server</code>. If not do me a favor and file and issue with what you are seeing so I can investigate.</p>
<aside class="quote no-group">
<blockquote>
<p>I did not really look into LiveState too much yet, so I do not know how you do it, but here are some points:</p>
<ul>
<li>StateChannel provides the state in a Context which is very nice and easy to use</li>
</ul>
</blockquote>
</aside>
<p>My thought here is that a hook is the newer ‘preferred’ way for working with react. But be happy to take PRs</p>
<aside class="quote no-group">
<blockquote>
<ul>
<li>StateChannel allows you to either transform and then diff the state on the server <strong>or</strong> you apply the JSONpatch primitives manually using <a href="https://github.com/amberbit/state_channel/blob/55f20820405278348f100c52a6c7130ef225d891/lib/state_channel/helpers.ex#L26" rel="noopener nofollow ugc">patch_state</a> which collects the patches in an array which is then send over the wire and the same time patches the server state (using JSONPatch). This skips the JSONDiff step.</li>
<li>Storex store acts as a <code>subscribable</code> that can be consumed by most frameworks, eg using <a href="https://github.com/amberbit/state_channel/blob/55f20820405278348f100c52a6c7130ef225d891/lib/state_channel/helpers.ex#L26" rel="noopener nofollow ugc">solid’s from</a>.</li>
</ul>
</blockquote>
</aside>
<p>These are interesting, particularly the <code>subscribable</code> idea. I’ll look into that</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273184" 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/client-side-rendering-server-side-state-statechannel/52709/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-273184" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273184"
                     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 #23"></div>
  </section>
</div>
    <div class="postbit" id="273187" data-post-id="273187">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="superchris" data-post="24" data-topic="52709">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/superchris/48/23484_2.png" class="avatar"> superchris:</div>
<blockquote>
<p>checking out the test bed might be your best bet after all. It should run if you clone the live_state repo, going into the testbed directory and do the standard <code>mix deps.get</code> and <code>mix phx.server</code>. If not do me a favor and file and issue with what you are seeing so I can investigate.</p>
</blockquote>
</aside>
<p>I tried that already, does not work, I created an issue. Also some minor issues in the comments-demo, which I have running. That’s really cool, I should look into that webcomponents thing again.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273187" 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/client-side-rendering-server-side-state-statechannel/52709/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-273187" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273187"
                     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 #24"></div>
  </section>
</div>
    <div class="postbit" id="273246" data-post-id="273246">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="hubertlepicki" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/hubertlepicki/120/6822_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  hubertlepicki
                    <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>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="superchris" data-post="22" data-topic="52709">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/superchris/48/23484_2.png" class="avatar"> superchris:</div>
<blockquote>
<p>Can you elaborate on some of the features from Storex and StateChannel you’d find useful?</p>
</blockquote>
</aside>
<p>I think the differences, from what I see is that:</p>
<ul>
<li>
<p>I have patch_state function, that allows user to selectively update the state <em>and</em> generate JSON Patch at the same time. In fact, the Patch is first generated, then applied on server, and sent to client to set the state locally. It’s an optimization so the server doesn’t have to compute a diff at all after event, example here: <a href="https://github.com/hubertlepicki/shopper_umbrella/blob/main/apps/shopper_web/lib/shopper_web/channels/app_channel.ex#L34" class="inline-onebox" rel="noopener nofollow ugc">shopper_umbrella/apps/shopper_web/lib/shopper_web/channels/app_channel.ex at main · hubertlepicki/shopper_umbrella · GitHub</a></p>
</li>
<li>
<p>I keep versioning server state and client state, automatically. Whenever server changes state, it increments the version counter by 2, whenever client changes the state it does the same. By comparing the server and client version numbers, a component can see if the server is yet to react to some of the events the client sent out, or if the state it sees is up to date and won’t change. This is helpful for building “controlled inputs”, where we expect the server to transform the input of user and send back, or to skip some renders if we know the responses coming from server are not final just yet and there will be more coming shortly</p>
</li>
</ul>
<p>There are some things I plan to experiment with too:</p>
<ul>
<li>
<p>initialize server state in Phoenix controller request, and make it cached for a few seconds, so that when Phoenix channel connects we can skip the state initialization. This will probably change where I keep state, and I won’t keep it in the channel directly but rather in a separate process.</p>
</li>
<li>
<p>validation that the state being set is JSON-serializable, currently it just crashes. I think this extra validation will run in development &amp; test, maybe it’s unnecessary in production. Need to ponder about this.</p>
</li>
<li>
<p>Phoenix presence support (React component)</p>
</li>
<li>
<p>I want to be able to generate a unique “page token” or “tab token”, something like this, that would be shared between all processes on the current page the user sees so that server-side communication between state channels is possible. Basically an automatic pubsub for all channels currently open in the page user sees at given time.</p>
</li>
<li>
<p>graceful shutdown for channels</p>
</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273246" 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/client-side-rendering-server-side-state-statechannel/52709/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-273246" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273246"
                     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 #25"></div>
  </section>
</div>
    <div class="postbit" id="273307" data-post-id="273307">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group">
<blockquote>
<p>I tried that already, does not work, I created an issue. Also some minor issues in the comments-demo, which I have running. That’s really cool, I should look into that webcomponents thing again.</p>
</blockquote>
</aside>
<p>I just merged a PR from a co-worker with my details in the testbed README. Let me know if that helps.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273307" 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/client-side-rendering-server-side-state-statechannel/52709/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-273307" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273307"
                     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 #26"></div>
  </section>
</div>
    <div class="postbit" id="273315" data-post-id="273315">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>[quote="hubertlepicki, post:26, topic:52709]</p>
<ul>
<li>I have patch_state function, that allows user to selectively update the state <em>and</em> generate JSON Patch at the same time. In fact, the Patch is first generated, then applied on server, and sent to client to set the state locally. It’s an optimization so the server doesn’t have to compute a diff at all after event, example here: <a href="https://github.com/hubertlepicki/shopper_umbrella/blob/main/apps/shopper_web/lib/shopper_web/channels/app_channel.ex#L34" class="inline-onebox" rel="noopener nofollow ugc">shopper_umbrella/apps/shopper_web/lib/shopper_web/channels/app_channel.ex at main · hubertlepicki/shopper_umbrella · GitHub</a></li>
</ul>
<p>[/quote]</p>
<p>Hmm.. I see, so the user can have more fine grained control over the patch generation if they want it. Makes sense. I notice in your code example, you are using <code>patch_state</code> in all cases. I assume from looking at the <code>StateChannel</code> code it’s also possible to just return a new state and let the diff get computed for you? I’m assuming this to be the ‘normal’ case. In general, I like to optimize for library consumer code simplicity.</p>
<aside class="quote no-group">
<blockquote>
<ul>
<li>I keep versioning server state and client state, automatically. Whenever server changes state, it increments the version counter by 2, whenever client changes the state it does the same. By comparing the server and client version numbers, a component can see if the server is yet to react to some of the events the client sent out, or if the state it sees is up to date and won’t change. This is helpful for building “controlled inputs”, where we expect the server to transform the input of user and send back, or to skip some renders if we know the responses coming from server are not final just yet and there will be more coming shortly</li>
</ul>
</blockquote>
</aside>
<p>Yeah, this seems like a really good idea. I’ll likely try to implement this also.</p>
<aside class="quote no-group">
<blockquote>
<ul>
<li>I want to be able to generate a unique “page token” or “tab token”, something like this, that would be shared between all processes on the current page the user sees so that server-side communication between state channels is possible. Basically an automatic pubsub for all channels currently open in the page user sees at given time.</li>
</ul>
</blockquote>
</aside>
<p>Yeah, I can definitely see the value of something like this. I currently have the client side library be able to share a LiveState connection via a provider and consumer idea, something like React Contexts but not tied to React. It would be even better if I didn’t have to do this, and could have the server just figure out that multiple components were part of the same logical connection and share state appropriately.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273315" 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/client-side-rendering-server-side-state-statechannel/52709/28">Post #27</a>
	                </div>
	            </div>
              <div id="likers-container-273315" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273315"
                     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 #27"></div>
  </section>
</div>
    <div class="postbit" id="273363" data-post-id="273363">
  <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
                  </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">
								<p>You may also be interested in Hologram which transpiles Elixir to JS and keeps the state on the client (which solves the problems described). Take a look at this thread: <a href="https://forum.elixirforum.com/t/hologram-full-stack-isomorphic-elixir-web-framework/45200" class="inline-onebox" rel="nofollow">Hologram - full stack isomorphic Elixir web framework</a> I plan to speed up development the beginning of the year, a demo website with docs should be released q1 23, and the Elixir standard lib should be transpiled in the beginning of q2 23.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273363" 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/client-side-rendering-server-side-state-statechannel/52709/29">Post #28</a>
	                </div>
	            </div>
              <div id="likers-container-273363" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273363"
                     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 #28"></div>
  </section>
</div>
    <div class="postbit" id="273375" data-post-id="273375">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/superchris" rel="nofollow">@superchris</a></p>
<p>What drove you to authoring LiveState? Trying to get an impression of your vision on web development and the possible future directions of LiveState.</p>
<p>My question comes from a place of interest. Like what I see on the GitHub repo and have been working with web components more lately.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273375" 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/client-side-rendering-server-side-state-statechannel/52709/30">Post #29</a>
	                </div>
	            </div>
              <div id="likers-container-273375" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273375"
                     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 #29"></div>
  </section>
</div>
    <div class="postbit" id="273453" data-post-id="273453">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The original impetus for creating LiveState was that I wanted to see if I could use LiveView to build an embedded or third party app: something you could drop into a web page hosted somewhere else, like a comments section or shopping cart. My first attempt was to see if I could render a LiveView into a custom element, but this proved difficult technically and less appealing the deeper I got.</p>
<p>My next thought was: What if I did something like LiveView, but kept only the rendering on the client. This is what led me to LiveState. I realized that the core of LiveView is the pattern I named (for lack of an existing name) the Event State Reducer pattern: functions which take an event, the current state, and return a new state. The idea of LiveState is to implement this same pattern but keep rendering client side: I push events up over the channel, and push state back down. It started as an experiment to “see how it felt” to build applications this way. My experiences and the feedback from others seemed good, so I kept going, and here we are <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>As far as a “vision on web development” that is a big question, probably too much to fit a comment reply <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> I’m very interested in continuing to explore the embedded app problem space, but whether the LiveState approach is a good approach to web app development more generally is an interesting question. As always, the answer is almost certainly: it depends.</p>
<p>I’ve been a proponent of web components for many years, so my intention is to support custom elements in a “first class” way while making it as easy as possible to support other frameworks. My philosophy, is as much as I have one, is to use the capabilities provided by the browser as much as I am able and avoid anything that locks me into a specific framework. I continue to be amazed by how much I see frameworks invent their own solutions to problems already solved by web standard APIs, but that is another rant for another day <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="273453" data-batch-url="/posts/batch_likers">
                        8
                      </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/client-side-rendering-server-side-state-statechannel/52709/31">Post #30</a>
	                </div>
	            </div>
              <div id="likers-container-273453" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="273453"
                     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 #30"></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/52709/load_more?page=4">Load more posts (7 remaining)</a>
</div></template></turbo-stream>