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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                    <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>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="axelson" data-post="9" data-topic="24623">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/axelson/48/26351_2.png" class="avatar"> axelson:</div>
<blockquote>
<p>I agree that it makes sense to export the root module by default. But in order to have a flexible tool it would be nice to optionally not export a root module. Perhaps a syntax like this could work:</p>
<p><code>{MySystem, exports: [MySystem.User], export_root: false}</code></p>
</blockquote>
</aside>
<p>This is a nice solution, thanks!</p>
<p>I guess my question would be: what is the scenario where you want to export submodules and keep the root module internal?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="139851" 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/boundary-enforcing-boundaries-in-elixir-projects/24623/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-139851" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="139851"
                     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="139852" data-post-id="139852">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                    <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>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="blatyo" data-post="10" data-topic="24623">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/blatyo/48/4554_2.png" class="avatar"> blatyo:</div>
<blockquote>
<p>Looking at this on my phone, but I didn’t see it mentioned anywhere how this interacts with the standard library and packages. Do they also need to be defined as boundaries?</p>
</blockquote>
</aside>
<p>External code, as well as internal Erlang modules are currently not considered, so you don’t need to (in fact you can’t) define those as boundaries.</p>
<p>I’m definitely thinking about adding the support for deps, which would allow us to e.g. prevent Plug calls from the business logic.</p>
<aside class="quote no-group" data-username="blatyo" data-post="10" data-topic="24623">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/blatyo/48/4554_2.png" class="avatar"> blatyo:</div>
<blockquote>
<p>Also, I suspect this wouldn’t catch modules passes as variables? Would it notice you reference a module to store it into a variable?</p>
</blockquote>
</aside>
<p>The implementation uses <a href="https://hexdocs.pm/mix/Mix.Tasks.Xref.html#calls/1" rel="noopener nofollow ugc">Mix.Tasks.Xref.calls</a> to get a list of cross-module references. My understanding is that this will include any reference to another module, not just a function call.</p>
<p>I’ve also confirmed this experimentally. As explained in <a href="https://github.com/sasa1977/boundaries/blob/master/lib/mix/tasks/compile/boundaries.ex#L79" rel="noopener nofollow ugc">this paragraph</a>, if in <code>MySystem.App</code> you have a reference to <code>MySystemWeb.Endpoint</code>, it will be treated as a cross-module dependency, even though there’s no function call.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="139852" data-batch-url="/posts/batch_likers">
                        4
                      </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/boundary-enforcing-boundaries-in-elixir-projects/24623/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-139852" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="139852"
                     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="139862" data-post-id="139862">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mudasobwa" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mudasobwa/120/5298_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mudasobwa
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Cure</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Looks great!</p>
<p>My ¢2.</p>
<p>I think the suggestions for decoupling / establishing boundaries might bring a huge value to it. We might have a configurable threshold (default <code>1</code> or like) and if the <code>Xref.calls &lt;= @threshold</code> the library might issue a <em>suggestion</em> to decouple things.</p>
<p>Also, finding orphans might be valuable as well.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="139862" 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/boundary-enforcing-boundaries-in-elixir-projects/24623/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-139862" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="139862"
                     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="139867" data-post-id="139867">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                    <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>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Interesting suggestions, thanks!</p>
<p>More generally, I think that explicit boundaries open up potential for some interesting tools, such as producing a boundary dependency graph (which in a large project should be easier to grasp), or automatic extraction of a boundary into a separate project, in the cases where you want to split your project.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="139867" 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/boundary-enforcing-boundaries-in-elixir-projects/24623/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-139867" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="139867"
                     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="139869" data-post-id="139869">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/sasajuric" rel="nofollow">@sasajuric</a> I’m very happy to see this problem tackled. There’s a great potential in Elixir for not just defining but also reliably validating cross-module dependencies.</p>
<p>I myself have attempted to tackle it via static analysis (Credo check) and with a different approach towards defining a boundary (as any module with <code>@moduledoc</code> and its children). You can find a well-documented code <a href="https://github.com/surgeventures/fresha_checks/blob/master/lib/fresha_checks/area_access.ex" rel="noopener nofollow ugc">here</a>. We didn’t use it though due to me then discovering <code>mix xref</code> as proof of compiler acting as way better tool for tracking calls (which you’ve used) and for the <code>@moduledoc</code> approach being not flexible enough (which your solution is).</p>
<p>I have a few questions that come from my my experiences with the above attempt:</p>
<ol>
<li>
<p>Did you consider a decentralized solution towards defining boundaries - i.e. one in which the boundary root somehow (e.g. via module attribute) marks itself as such and somehow defines its exports as opposed to your <code>boundaries.exs</code>? In such solution exports could also be auto-inferred by tracking references from the root i.e. all modules exposed by root become part of the contract and validated (exports still must be marked as such in order to avoid mistakes).</p>
</li>
<li>
<p>Did you consider taking leverage of <code>@moduledoc</code> in any way? For instance you could consider all modules of 3rd party library that do have moduledoc (which can be checked after compilation) to be “exports” of the library. This <a href="https://hexdocs.pm/elixir/writing-documentation.html#documentation-code-comments" rel="noopener nofollow ugc">seems to be a convention of Elixir</a> although from my experience, developers are not that aware of this, so it may be a risky route to follow.</p>
</li>
<li>
<p>Even though you seem to advertise your library as kind of an alternative to umbrella I think both aren’t mutually exclusive and solve different problems. As such your library is IMO 100% viable for use in umbrella project. And so my question: do you plan to support umbrella projects in the library (like <code>mix xref</code> does via special options)?</p>
</li>
<li>
<p>Is it possible to have some parts of the code that are blacklisted from the check i.e. that could call anything or that could be called by anything. Does the library support such cases? It would be useful for larger projects that are in process of defining better boundaries but still having some “legacy” code that just can’t follow them. I think there’s a room in the documentary part of your project for tackling such conceptual problems.</p>
</li>
</ol>
<p>Again thanks for the great effort and looking forward for your insights on the above.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="139869" data-batch-url="/posts/batch_likers">
                        4
                      </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/boundary-enforcing-boundaries-in-elixir-projects/24623/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-139869" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="139869"
                     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="139874" data-post-id="139874">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                    <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>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Great questions, thanks!</p>
<aside class="quote no-group" data-username="karolsluszniak" data-post="16" data-topic="24623">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/karolsluszniak/48/1627_2.png" class="avatar"> karolsluszniak:</div>
<blockquote>
<p>Did you consider a decentralized solution towards defining boundaries</p>
</blockquote>
</aside>
<p>TBH I didn’t. This simple exs was a first thing that came to mind <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"></p>
<p>But now that you mention it, if we think about larger projects where developers want to be fine grained and so create a larger number of boundaries, I think that a decentralized approach would definitely scale better than a single .exs file which would possibly become bloated.</p>
<p>I guess a big unknown for me at this point is do we expect such fine granularity? I’d typically expect a much smaller amount of boundaries compared to the number of modules. And if I’m right, then perhaps a centralized solution might be simpler.</p>
<p>OTOH, I do have some ideas to support sub-boundaries (internal boundaries within boundaries), and for that approach, I think that decentralized definitely seems like a better option.</p>
<p>Another win for decentralized is that you don’t need to sync another file. So for example, if you delete or rename a module, the boundary info is auto updated.</p>
<p>One small issue with decentralized is that a root module always has to exist. So if I don’t have a root module, I need to create it for the sole purpose of having a boundary. Perhaps that’s fine.</p>
<p>Also, the usage would then probably look like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MyBoundary do
  use Boundary,
    exports: [...],
    deps: [...]
end
</code></pre>
<p>Which, under the hood would be persisted to BEAM, so they can be collected by the boundaries checker.</p>
<p>I’m a bit unhappy about using <code>use</code>, but ATM I don’t see a simple solution which isn’t built on use.</p>
<aside class="quote no-group" data-username="karolsluszniak" data-post="16" data-topic="24623">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/karolsluszniak/48/1627_2.png" class="avatar"> karolsluszniak:</div>
<blockquote>
<p>Did you consider taking leverage of <code>@moduledoc</code> in any way?</p>
</blockquote>
</aside>
<p>No, but that’s an interesting idea, thanks! I’ll keep it in mind.</p>
<aside class="quote no-group" data-username="karolsluszniak" data-post="16" data-topic="24623">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/karolsluszniak/48/1627_2.png" class="avatar"> karolsluszniak:</div>
<blockquote>
<p>Even though you seem to advertise your library as kind of an alternative to umbrella I think both aren’t mutually exclusive and solve different problems.</p>
</blockquote>
</aside>
<p>Absolutely agree! I advertise it as an alternative to umbrella <strong>for specifying and enforcing boundaries</strong>. Nothing more than that <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>
<aside class="quote no-group" data-username="karolsluszniak" data-post="16" data-topic="24623">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/karolsluszniak/48/1627_2.png" class="avatar"> karolsluszniak:</div>
<blockquote>
<p>And so my question: do you plan to support umbrella projects in the library (like <code>mix xref</code> does via special options)?</p>
</blockquote>
</aside>
<p>In theory, it already works (<a href="https://github.com/sasa1977/boundaries/blob/master/lib/mix/tasks/compile/boundaries.ex#L187" rel="noopener nofollow ugc">compiler is marked as recursive</a>). In practice, I have no idea because I haven’t tested it <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"> If boundaries in umbrella projects don’t work, open up an issue on the repo.</p>
<aside class="quote no-group" data-username="karolsluszniak" data-post="16" data-topic="24623">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/karolsluszniak/48/1627_2.png" class="avatar"> karolsluszniak:</div>
<blockquote>
<p>s it possible to have some parts of the code that are blacklisted from the check i.e. that could call anything or that could be called by anything. Does the library support such cases?</p>
</blockquote>
</aside>
<p>Currently no, but you make good argument why this might make sense.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="139874" data-batch-url="/posts/batch_likers">
                        5
                      </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/boundary-enforcing-boundaries-in-elixir-projects/24623/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-139874" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="139874"
                     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="139875" data-post-id="139875">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="sasajuric" data-post="13" data-topic="24623">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/48/991_2.png" class="avatar"> sasajuric:</div>
<blockquote>
<p>I’m definitely thinking about adding the support for deps, which would allow us to e.g. prevent Plug calls from the business logic.</p>
</blockquote>
</aside>
<p>+1 to supporting deps.  I currently have an umbrella project I’d like to move into a normal project, and having more fine grained deps checks would be helpful.</p>
<p>As a side comment related to the motivation to avoid the extra ceremony of umbrella projects, my understanding is that an umbrella project is required if you want to deploy different apps to different boxes, since <code>mix</code> handles the creation of <code>.app</code> files and currently can only do so from a <code>mix.exs</code> file.  So in my case I’m planning on storing all of my application logic in one app of the umbrella project and then using the other apps just for <code>mix.exs</code> and supervision tree details for the respective OTP applications.  The use of <code>boundaries</code> within the main app will be helpful in keeping the code clean and keeping me honest about where I’m using my external dependencies.</p>
<p>Thanks for sharing the library!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="139875" 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/boundary-enforcing-boundaries-in-elixir-projects/24623/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-139875" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="139875"
                     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="139878" data-post-id="139878">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                    <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>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="justincjohnson" data-post="18" data-topic="24623">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/justincjohnson/48/23636_2.png" class="avatar"> justincjohnson:</div>
<blockquote>
<p>my understanding is that an umbrella project is required if you want to deploy different apps to different boxes</p>
</blockquote>
</aside>
<p>I obviously need to improve the project readme <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>I’m not suggesting that umbrellas are bad in general. They do require extra ceremony, but if you have the problem which they solve, then it’s fine to pay the price.</p>
<p>However, drawing boundaries is, in my view, not the problem umbrellas are supposed to solve. The main hypothesis behind this experiment is that umbrellas are not needed for enforcing boundaries, and that it’s possible to write a tool which solves the same problem in a simpler way (hence, less ceremony), which is at the same time more powerful.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="139878" 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/boundary-enforcing-boundaries-in-elixir-projects/24623/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-139878" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="139878"
                     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="139879" data-post-id="139879">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><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">  Your readme is great.  I was just explaining how <code>boundaries</code> will help me with my specific challenges, and I decided to share why I need an umbrella project, in part because I’m hoping someone will correct my understanding and tell me it’s possible to have multiple OTP apps in a normal project.  <img src="https://forum.elixirforum.com/images/emoji/apple/pray.png?v=15" title=":pray:" class="emoji" alt=":pray:" 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="139879" 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/boundary-enforcing-boundaries-in-elixir-projects/24623/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-139879" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="139879"
                     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="139889" data-post-id="139889">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/justincjohnson" rel="nofollow">@justincjohnson</a> Yup, umbrella allows to have multiple OTP apps in one meta-project with less ceremony (although opinions on that vary :)) than managing multiple projects altogether.</p>
<p>And indeed umbrella’s main concern isn’t validating cross-module deps i.e. what <code>boundaries</code> does - <a href="https://elixir-lang.org/getting-started/mix-otp/dependencies-and-umbrella-projects.html#dont-drink-the-kool-aid" rel="nofollow">as stated in the official guide</a> umbrella has drawbacks in that department.</p>
<p>What umbrella does that could be perceived as similar to <code>boundaries</code> is that it allows to split app code into higher level buckets compared to modules i.e. OTP apps and that it draws dependencies between those apps via deps with <code>in_umbrella</code> BUT it’s a very unreliable tool for guarding these dependencies because if app A always declares dependency on app B and app B doesn’t declare dependency on app A, it still can call code of app A without warnings because these apps are always present together in the build.</p>
<p>Therefore I rather see umbrella as tool for exactly what you wrote i.e. creating heterogenic releases made of different sets of OTP apps, than a code organization tool.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="139889" data-batch-url="/posts/batch_likers">
                        5
                      </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/boundary-enforcing-boundaries-in-elixir-projects/24623/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-139889" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="139889"
                     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/24623/load_more?page=3">Load more posts (29 remaining)</a>
</div></template></turbo-stream>