<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arg Software</title>
    <description>The latest articles on DEV Community by Arg Software (@argsoftware).</description>
    <link>https://dev.to/argsoftware</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4129735%2Ff37c28a1-2870-4d2c-8105-f148315f0e8c.jpg</url>
      <title>DEV Community: Arg Software</title>
      <link>https://dev.to/argsoftware</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/argsoftware"/>
    <language>en</language>
    <item>
      <title>Your Website Looks Fine, But What's Really Going On Behind the Scenes?</title>
      <dc:creator>Arg Software</dc:creator>
      <pubDate>Mon, 19 Oct 2026 19:14:43 +0000</pubDate>
      <link>https://dev.to/argsoftware/your-website-looks-fine-but-whats-really-going-on-behind-the-scenes-48pm</link>
      <guid>https://dev.to/argsoftware/your-website-looks-fine-but-whats-really-going-on-behind-the-scenes-48pm</guid>
      <description>&lt;p&gt;Your website looks great.&lt;/p&gt;

&lt;p&gt;The design is clean. The images load. The buttons work. Everything seems fine.&lt;/p&gt;

&lt;p&gt;But what if your visitors are waiting longer than they should? What if something is making your website less secure? Or what if it's quietly loading things nobody actually needs?&lt;/p&gt;

&lt;p&gt;Here's the thing about websites: some of their biggest problems are the ones you can't see.&lt;/p&gt;

&lt;p&gt;And you shouldn't need to be a developer to find them.&lt;/p&gt;

&lt;p&gt;That's why we built Arg Architect.&lt;/p&gt;

&lt;h2&gt;
  
  
  It started with a question we kept asking ourselves
&lt;/h2&gt;

&lt;p&gt;At ARG, we spend a lot of time looking at websites. And we kept noticing the same thing.&lt;/p&gt;

&lt;p&gt;A website could look perfectly fine on the outside, but behind the scenes, it is a different story.&lt;/p&gt;

&lt;p&gt;Huge images slowing everything down. Security settings that had been overlooked. Third-party tools adding unnecessary weight. Things that had been there for months, sometimes years, without anyone noticing.&lt;/p&gt;

&lt;p&gt;Finding these problems meant jumping between different tools, interpreting complicated reports, and sometimes sending information to external services.&lt;/p&gt;

&lt;p&gt;We kept thinking: "Why is it so difficult to get a clear picture of what's happening on a website?"&lt;/p&gt;

&lt;p&gt;So we built something for ourselves.&lt;/p&gt;

&lt;p&gt;Something simple, practical, and private.&lt;/p&gt;

&lt;p&gt;Then we thought, why not let everyone use it?&lt;/p&gt;

&lt;h2&gt;
  
  
  Meet Arg Architect
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4ejf396gn0stjexpfx16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4ejf396gn0stjexpfx16.png" alt="Arg Architect" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Arg Architect is a free browser extension that gives your website a health check.&lt;/p&gt;

&lt;p&gt;You enter a website address, run an audit, and get a report showing what's working well, what could be improved, and why it matters.&lt;/p&gt;

&lt;p&gt;Think of it like taking your car for an inspection. Everything might feel fine while you're driving, but it's reassuring to know someone has checked what's happening under the hood.&lt;/p&gt;

&lt;p&gt;Except this inspection is free, and it takes about two minutes to run a quick check.&lt;/p&gt;

&lt;p&gt;It looks at eight areas of your website, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Are there weaknesses that could put your website or visitors at risk?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; Is your website making people wait unnecessarily?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency:&lt;/strong&gt; Is it downloading more than it needs?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility:&lt;/strong&gt; Can people with different needs use it comfortably?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI readiness:&lt;/strong&gt; Can AI tools understand your website and find useful information?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also examines page structure, file sizes, and how much your website depends on external services.&lt;/p&gt;

&lt;p&gt;And here's our favorite part: it explains problems in language people can understand.&lt;/p&gt;

&lt;p&gt;Instead of throwing mysterious error codes at you, it tells you what's wrong, why you should care, and what can be done about it.&lt;/p&gt;

&lt;p&gt;You can even copy a finding and send it straight to your developer as a task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things we weren't willing to compromise on
&lt;/h2&gt;

&lt;p&gt;While building Arg Architect, we made three decisions that mattered to us.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Your data stays yours.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your audit results stay in your browser, on your device. Even the small inference model used for part of the analysis runs locally. Two optional external lookups are disabled unless you give permission.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. It respects your privacy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You know those annoying cookie banners?&lt;/p&gt;

&lt;p&gt;When Arg Architect encounters one, it doesn't automatically click "Accept All." It chooses to reject optional cookies or accept only what's essential.&lt;/p&gt;

&lt;p&gt;We thought it would be pretty ironic to build a tool that checks websites for problems while casually accepting every tracking cookie along the way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. It doesn't pretend to know what it doesn't know.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A website might load quickly one moment and slowly the next.&lt;/p&gt;

&lt;p&gt;That's why Arg Architect can run multiple controlled tests and use the middle result, rather than trusting one lucky attempt.&lt;/p&gt;

&lt;p&gt;And if something can't be measured properly, it says so. No invented results. No false reassurance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3dm2qiwpug8f9dx343qz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3dm2qiwpug8f9dx343qz.png" alt="Arg Architect running" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Your website has a new kind of visitor: AI
&lt;/h2&gt;

&lt;p&gt;Here's something that wasn't on most people's minds a few years ago.&lt;/p&gt;

&lt;p&gt;Today, it's not just humans visiting websites. AI assistants and automated tools are reading them too.&lt;/p&gt;

&lt;p&gt;People are increasingly using AI to discover businesses, research products, and compare services.&lt;/p&gt;

&lt;p&gt;But can these tools actually understand your website?&lt;/p&gt;

&lt;p&gt;Arg Architect checks whether your site's information is accessible and understandable to AI systems and whether important details match what your pages really say.&lt;/p&gt;

&lt;p&gt;It won't guarantee that AI will recommend your business. But it can help you understand whether your website is making things unnecessarily difficult.&lt;/p&gt;

&lt;p&gt;And that feels like something worth knowing.&lt;/p&gt;

&lt;h2&gt;
  
  
  See what actually improves
&lt;/h2&gt;

&lt;p&gt;Finding a problem is useful. Knowing you've fixed it is even better.&lt;/p&gt;

&lt;p&gt;Arg Architect saves reports locally and lets you compare audits over time.&lt;/p&gt;

&lt;p&gt;Maybe you optimized your images, removed an unnecessary tool, or launched a redesign.&lt;/p&gt;

&lt;p&gt;Did it help?&lt;/p&gt;

&lt;p&gt;Now you can see what changed, compare the results, and share reports with your team.&lt;/p&gt;

&lt;p&gt;Less guessing. More evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why are we giving it away?
&lt;/h2&gt;

&lt;p&gt;Because we built it for ourselves first.&lt;/p&gt;

&lt;p&gt;At ARG, we believe good engineering starts with understanding what's really happening, not just what things look like on the surface.&lt;/p&gt;

&lt;p&gt;Arg Architect is a small reflection of how we work.&lt;/p&gt;

&lt;p&gt;And yes, it's also a way to introduce people to ARG.&lt;/p&gt;

&lt;p&gt;But we'd rather do that by sharing something genuinely useful than by writing another advertisement about how great we are.&lt;/p&gt;

&lt;p&gt;You don't need to become a client. You don't need to sign up for anything.&lt;/p&gt;

&lt;p&gt;Just use it.&lt;/p&gt;

&lt;p&gt;If it helps make your website a little faster, safer, or easier to use, we're happy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now we're curious about your website
&lt;/h2&gt;

&lt;p&gt;Here's a little challenge.&lt;/p&gt;

&lt;p&gt;Think of a website you care about. Maybe it's your business, your online shop, or something you've spent months building.&lt;/p&gt;

&lt;p&gt;Now ask yourself:&lt;/p&gt;

&lt;p&gt;Do you really know what's happening behind the scenes?&lt;/p&gt;

&lt;p&gt;There's a simple way to find out.&lt;/p&gt;

&lt;p&gt;Install Arg Architect, enter your website address, and run a quick audit.&lt;/p&gt;

&lt;p&gt;Start with security. You might find everything looks good. You might discover something worth fixing.&lt;/p&gt;

&lt;p&gt;Either way, you'll know something you didn't know before.&lt;/p&gt;

&lt;p&gt;And we'd love to hear what you find.&lt;/p&gt;

&lt;p&gt;Try Arg Architect for free:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://chromewebstore.google.com/detail/arg-architect/bijelgdokpgmffnddemjblgdocnbogid" rel="noopener noreferrer"&gt;&lt;strong&gt;Chrome, Edge, Brave &amp;amp; Opera&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://addons.mozilla.org/addon/arg-architect/" rel="noopener noreferrer"&gt;&lt;strong&gt;Firefox&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://arg.software/audit" rel="noopener noreferrer"&gt;&lt;strong&gt;Arg Architect site&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>performance</category>
      <category>security</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Actually Enforce Clean Architecture in TypeScript</title>
      <dc:creator>Arg Software</dc:creator>
      <pubDate>Thu, 17 Sep 2026 11:28:47 +0000</pubDate>
      <link>https://dev.to/argsoftware/how-to-actually-enforce-clean-architecture-in-typescript-1o4a</link>
      <guid>https://dev.to/argsoftware/how-to-actually-enforce-clean-architecture-in-typescript-1o4a</guid>
      <description>&lt;p&gt;You wrote the docs. You did the PR reviews. You explained it during onboarding. And yet, six months later, a bunch of controllers are directly importing a repository, and nobody noticed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Problem With Architecture
&lt;/h2&gt;

&lt;p&gt;Clean Architecture, Hexagonal Architecture, layered architecture, or whatever approach you follow: the rules often exist in only two places: your head and a README nobody reads.&lt;/p&gt;

&lt;p&gt;The moment a deadline hits, someone takes a shortcut. A controller calls a repository directly. A domain model imports a NestJS decorator. An infrastructure class leaks into the application layer.&lt;/p&gt;

&lt;p&gt;It is not malicious. It is invisible.&lt;/p&gt;

&lt;p&gt;Nobody gets a red light. The tests still pass. The application still ships.&lt;/p&gt;

&lt;p&gt;Six months later, you have a codebase that looks structured but behaves like a mess.&lt;/p&gt;

&lt;p&gt;The fix is not more pull request comments or awareness. It is making the rules enforceable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Tests: Rules That Enforce Themselves
&lt;/h2&gt;

&lt;p&gt;Architecture tests are automated tests that do not test your business logic. They test the structure of your application.&lt;/p&gt;

&lt;p&gt;They answer questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does anything in the domain layer import from infrastructure?&lt;/li&gt;
&lt;li&gt;Is any controller talking directly to a repository?&lt;/li&gt;
&lt;li&gt;Do all use cases follow the naming convention we agreed on?&lt;/li&gt;
&lt;li&gt;Does the project contain circular dependencies?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the answer is ever yes, the build fails. No human intervention is required.&lt;/p&gt;

&lt;p&gt;We are going to use &lt;a href="https://www.npmjs.com/package/archunit" rel="noopener noreferrer"&gt;ArchUnitTS&lt;/a&gt;, an actively maintained architecture-testing library for TypeScript inspired by ArchUnit from the Java ecosystem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;archunit &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting the Rules
&lt;/h2&gt;

&lt;p&gt;Imagine you are running a NestJS application with this layered structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
  domain/         # Entities, value objects, domain errors
  application/    # Use cases, service interfaces
  infrastructure/ # Repositories, ORM, external services
  http/           # Controllers, DTOs, HTTP concerns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are the architectural rules you might want to enforce.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Domain Must Not Depend on Application or Infrastructure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;projectFiles&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;archunit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;domain should not depend on application or infrastructure&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;projectFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/domain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldNot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dependOnFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/application&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;or&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/infrastructure&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toPassAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Controllers Must Not Import Repositories Directly
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;controllers should not import repositories directly&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;projectFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldNot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dependOnFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/infrastructure/repositories&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toPassAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Application Must Not Depend on Infrastructure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application should not depend on infrastructure&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;projectFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/application&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldNot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dependOnFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/infrastructure&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toPassAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Enforcing Naming Conventions
&lt;/h2&gt;

&lt;p&gt;Beyond dependency direction, you can enforce the conventions your team agreed on: the ones currently living in a Notion document nobody opens.&lt;/p&gt;

&lt;h3&gt;
  
  
  All Use Cases Must End With &lt;code&gt;UseCase&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use cases must follow the naming convention&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;projectFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/application/use-cases&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchPattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;*UseCase.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toPassAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Domain Interfaces Must Be Prefixed With &lt;code&gt;I&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;domain interfaces should be prefixed with I&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;projectFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/domain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;that&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;areInterfaces&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;haveNameMatching&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^I&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;A-Z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toPassAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Infrastructure Interfaces Must Be Prefixed With &lt;code&gt;I&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;infrastructure interfaces should be prefixed with I&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;projectFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/infrastructure&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;that&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;areInterfaces&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;haveNameMatching&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^I&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;A-Z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toPassAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Project Must Not Contain Circular Dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should have no circular dependencies&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;projectFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/**&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;haveNoCycles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toPassAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Silent Killer Other Libraries Miss
&lt;/h2&gt;

&lt;p&gt;Here is something worth knowing before selecting an architecture-testing library: a passing test that inspected zero files is worse than no test at all.&lt;/p&gt;

&lt;p&gt;Imagine you write this rule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;projectFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/doamin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Typo: this should be "domain"&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shouldNot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dependOnFiles&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inFolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/infrastructure&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many libraries will match zero files, perform zero checks, and report that the test passed.&lt;/p&gt;

&lt;p&gt;Your architectural rule silently does nothing forever.&lt;/p&gt;

&lt;p&gt;ArchUnitTS fails empty tests by default. The test will not pass until the pattern matches actual files.&lt;/p&gt;

&lt;p&gt;It seems like a small detail, but this is exactly the kind of false confidence that causes real incidents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Changes Everything
&lt;/h2&gt;

&lt;p&gt;The usual ways of enforcing architecture are expensive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pair programming is valuable, but it does not scale to every change.&lt;/li&gt;
&lt;li&gt;Pull request reviews catch violations late and introduce friction.&lt;/li&gt;
&lt;li&gt;Documentation gets ignored when deadlines approach.&lt;/li&gt;
&lt;li&gt;Verbal agreements are forgotten by the next sprint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Architecture tests reverse the model.&lt;/p&gt;

&lt;p&gt;You write the rule once, and it runs on every push. A developer cannot accidentally violate a dependency rule without the CI pipeline immediately identifying the offending file.&lt;/p&gt;

&lt;p&gt;This also makes onboarding easier.&lt;/p&gt;

&lt;p&gt;Instead of explaining, “We do not import repositories in controllers here,” you can let the test demonstrate the rule. The tests become living documentation that remains synchronized with the codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;Your architecture is only as strong as your ability to enforce it.&lt;/p&gt;

&lt;p&gt;Documentation decays, memory fades, and deadline pressure is real. Architecture tests turn structural rules into executable constraints that run on every push.&lt;/p&gt;

&lt;p&gt;Write these tests when you establish an architectural rule, include them in your CI pipeline, and stop discovering structural violations during pull request reviews months later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgzkg0hz9xgdu8g4ykl0e.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgzkg0hz9xgdu8g4ykl0e.webp" alt="Two builders constructing a visibly misaligned brick wall with the caption: “Just keep coding. We can always fix it later.”" width="576" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How does your team enforce architectural boundaries: automated tests, lint rules, or code reviews?&lt;/p&gt;




&lt;p&gt;Originally published on &lt;a href="https://arg.software/blog/enforce-clean-architecture-typescript/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_campaign=devto_crosspost" rel="noopener noreferrer"&gt;ARG Software&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>architecture</category>
      <category>testing</category>
      <category>cleancode</category>
    </item>
  </channel>
</rss>
