<?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: Habeeb Abdullahi</title>
    <description>The latest articles on DEV Community by Habeeb Abdullahi (@engrwithhabeeb).</description>
    <link>https://dev.to/engrwithhabeeb</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2501179%2F9a977a7b-5b55-4010-afc5-7e66019cc7ca.png</url>
      <title>DEV Community: Habeeb Abdullahi</title>
      <link>https://dev.to/engrwithhabeeb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/engrwithhabeeb"/>
    <language>en</language>
    <item>
      <title>The Trap of "Perfect" Architecture: What Building a Shopping Cart Taught Me</title>
      <dc:creator>Habeeb Abdullahi</dc:creator>
      <pubDate>Sat, 30 May 2026 22:06:27 +0000</pubDate>
      <link>https://dev.to/engrwithhabeeb/the-trap-of-perfect-architecture-what-building-a-shopping-cart-taught-me-3ice</link>
      <guid>https://dev.to/engrwithhabeeb/the-trap-of-perfect-architecture-what-building-a-shopping-cart-taught-me-3ice</guid>
      <description>&lt;p&gt;Early in my journey as a software engineer, I became fascinated with software architecture.&lt;/p&gt;

&lt;p&gt;I spent hours learning about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SOLID Principles&lt;/li&gt;
&lt;li&gt;Clean Architecture&lt;/li&gt;
&lt;li&gt;Hexagonal Architecture&lt;/li&gt;
&lt;li&gt;Ports and Adapters&lt;/li&gt;
&lt;li&gt;Dependency Inversion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The more I learned, the more I became convinced that every project should be highly decoupled, framework-agnostic, and future-proof.&lt;/p&gt;

&lt;p&gt;Then I built a shopping cart application.&lt;/p&gt;

&lt;p&gt;And that's when reality taught me a lesson that no book could.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building It "The Right Way"
&lt;/h2&gt;

&lt;p&gt;Instead of creating a straightforward React application, I decided to apply a strict layered architecture.&lt;/p&gt;

&lt;p&gt;My project was structured like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UI
│
Controllers
│
Application
│
Domain
│
Adapters
│
Infrastructure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every responsibility had its own layer.&lt;/p&gt;

&lt;p&gt;Every dependency pointed inward.&lt;/p&gt;

&lt;p&gt;Every interaction crossed carefully designed boundaries.&lt;/p&gt;

&lt;p&gt;At first, I loved it.&lt;/p&gt;

&lt;p&gt;The folder structure looked professional.&lt;/p&gt;

&lt;p&gt;The separation of concerns looked clean.&lt;/p&gt;

&lt;p&gt;The architecture looked impressive.&lt;/p&gt;

&lt;p&gt;Then I started building features.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architectural Tax
&lt;/h2&gt;

&lt;p&gt;A simple feature change often required updates across multiple layers.&lt;/p&gt;

&lt;p&gt;Something that should have taken minutes turned into a journey through several directories and files.&lt;/p&gt;

&lt;p&gt;I found myself spending more time maintaining architectural boundaries than solving actual problems.&lt;/p&gt;

&lt;p&gt;That's when I realized something important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Architecture isn't free.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every layer comes with a cost.&lt;/p&gt;

&lt;p&gt;Every abstraction comes with a cost.&lt;/p&gt;

&lt;p&gt;Every boundary comes with a cost.&lt;/p&gt;

&lt;p&gt;You pay for it with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More files&lt;/li&gt;
&lt;li&gt;More indirection&lt;/li&gt;
&lt;li&gt;More cognitive load&lt;/li&gt;
&lt;li&gt;More debugging effort&lt;/li&gt;
&lt;li&gt;Slower development velocity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The architecture wasn't wrong.&lt;/p&gt;

&lt;p&gt;The problem was that the complexity of the architecture was greater than the complexity of the application itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture Is a Budget, Not a Rulebook
&lt;/h2&gt;

&lt;p&gt;This realization completely changed how I think about software design.&lt;/p&gt;

&lt;p&gt;The question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is this architecture clean?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The better question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What problem is this architecture solving, and is that problem large enough to justify its cost?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A shopping cart application with a handful of features does not face the same challenges as a large enterprise system.&lt;/p&gt;

&lt;p&gt;Treating both projects the same way can actually make the smaller project harder to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Framework-Agnostic Illusion
&lt;/h2&gt;

&lt;p&gt;One of my goals was to make the application completely independent of React.&lt;/p&gt;

&lt;p&gt;I wanted to be able to swap React for another framework in the future.&lt;/p&gt;

&lt;p&gt;In theory, that sounded like great engineering.&lt;/p&gt;

&lt;p&gt;In practice, I realized I was optimizing for a scenario that might never happen.&lt;/p&gt;

&lt;p&gt;The changes that are almost guaranteed to happen are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New features&lt;/li&gt;
&lt;li&gt;Requirement changes&lt;/li&gt;
&lt;li&gt;UI updates&lt;/li&gt;
&lt;li&gt;Bug fixes&lt;/li&gt;
&lt;li&gt;Refactoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A complete framework migration is usually much less likely.&lt;/p&gt;

&lt;p&gt;Today, I still keep business logic isolated, but I no longer try to abstract every single framework detail away.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Prefer Now
&lt;/h2&gt;

&lt;p&gt;My current frontend architecture is much simpler:&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain
&lt;/h3&gt;

&lt;p&gt;Pure business logic.&lt;/p&gt;

&lt;p&gt;No React.&lt;/p&gt;

&lt;p&gt;No API calls.&lt;/p&gt;

&lt;p&gt;No UI concerns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure
&lt;/h3&gt;

&lt;p&gt;External systems such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API clients&lt;/li&gt;
&lt;li&gt;Storage&lt;/li&gt;
&lt;li&gt;Third-party services&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hooks
&lt;/h3&gt;

&lt;p&gt;State management and orchestration.&lt;/p&gt;

&lt;p&gt;The bridge between the domain and the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  UI
&lt;/h3&gt;

&lt;p&gt;Presentation components.&lt;/p&gt;

&lt;p&gt;Focused on rendering and user interaction.&lt;/p&gt;

&lt;p&gt;Nothing more.&lt;/p&gt;

&lt;p&gt;This gives me most of the benefits I care about without introducing unnecessary complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Biggest Lesson
&lt;/h2&gt;

&lt;p&gt;The lesson wasn't that Hexagonal Architecture is bad.&lt;/p&gt;

&lt;p&gt;The lesson wasn't that Clean Architecture is wrong.&lt;/p&gt;

&lt;p&gt;The lesson was this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Architecture should solve real problems, not hypothetical ones.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes adding a boundary is the right decision.&lt;/p&gt;

&lt;p&gt;Sometimes removing a boundary is the right decision.&lt;/p&gt;

&lt;p&gt;The difficult part is knowing the difference.&lt;/p&gt;

&lt;p&gt;And that's not something you learn from reading alone.&lt;/p&gt;

&lt;p&gt;You learn it by building software, experiencing the friction, and understanding the trade-offs firsthand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Engineering maturity isn't about applying every design pattern you've learned.&lt;/p&gt;

&lt;p&gt;It's about understanding the cost and value of each decision.&lt;/p&gt;

&lt;p&gt;The goal isn't perfect architecture.&lt;/p&gt;

&lt;p&gt;The goal is reducing the cost of future change.&lt;/p&gt;

&lt;p&gt;Build.&lt;/p&gt;

&lt;p&gt;Ship.&lt;/p&gt;

&lt;p&gt;Learn.&lt;/p&gt;

&lt;p&gt;Then simplify.&lt;/p&gt;




&lt;p&gt;Have you ever realized you were over-engineering a project? What lesson did it teach you?&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>webdev</category>
      <category>software</category>
      <category>career</category>
    </item>
    <item>
      <title>JavaScript vs TypeScript? Maybe We’ve Been Asking the Wrong Question.</title>
      <dc:creator>Habeeb Abdullahi</dc:creator>
      <pubDate>Thu, 30 Apr 2026 12:23:08 +0000</pubDate>
      <link>https://dev.to/engrwithhabeeb/javascript-vs-typescript-maybe-weve-been-asking-the-wrong-question-3aei</link>
      <guid>https://dev.to/engrwithhabeeb/javascript-vs-typescript-maybe-weve-been-asking-the-wrong-question-3aei</guid>
      <description>&lt;p&gt;A lot of developers frame JavaScript vs TypeScript as a debate about which one is better or more professional.&lt;/p&gt;

&lt;p&gt;But in real-world systems, that question often misses the real issue.&lt;/p&gt;

&lt;p&gt;The difference between good and bad developers is rarely about the language. It is about understanding software design, data flow, and runtime behavior.&lt;/p&gt;

&lt;p&gt;Let’s look at a practical example.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Bad TypeScript (Type Safety Without Real Safety)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a common pattern&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;type&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&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;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/user/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;showUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123&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;&lt;strong&gt;What is wrong here&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On the surface this looks clean and type safe&lt;/p&gt;

&lt;p&gt;But in reality&lt;/p&gt;

&lt;p&gt;• The API response is not validated&lt;br&gt;
• The server could return null or incomplete data&lt;br&gt;
• TypeScript is being trusted blindly&lt;br&gt;
• Runtime errors are still possible&lt;/p&gt;

&lt;p&gt;This is what happens when TypeScript is used as a replacement for validation instead of a supplement&lt;/p&gt;



&lt;p&gt;✅ Better JavaScript (Safer Through Design)&lt;/p&gt;

&lt;p&gt;Now compare this approach&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&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;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/api/user/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid user data received from API&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to load user:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&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;showUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123&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;&lt;strong&gt;Why this JavaScript approach can actually be safer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;• It validates real runtime data instead of assumptions&lt;br&gt;
• It fails explicitly when something is wrong&lt;br&gt;
• It separates concerns between fetching, validation, and usage&lt;br&gt;
• It scales naturally into schema based systems like Zod or Joi&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The real takeaway&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TypeScript improves &lt;strong&gt;developer experience and static safety&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;real world safety comes from architecture, validation, and understanding runtime behavior, not types alone.&lt;/p&gt;
&lt;/blockquote&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.amazonaws.com%2Fuploads%2Farticles%2Fd03mcu9zgt1w7n93ev57.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.amazonaws.com%2Fuploads%2Farticles%2Fd03mcu9zgt1w7n93ev57.png" alt="A comparison of two security models: a cracked blue holographic shield labeled 'Type Safety' next to a solid, reinforced yellow vault door labeled 'Real Safety'" width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
You can write unsafe TypeScript and safe JavaScript.&lt;/p&gt;

&lt;p&gt;The difference is not the language.&lt;/p&gt;

&lt;p&gt;It is the engineering discipline behind it.&lt;/p&gt;




&lt;p&gt;If you are serious about frontend engineering, the real question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JavaScript or TypeScript&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do I understand what actually happens when my code runs?&lt;/p&gt;
&lt;/blockquote&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.amazonaws.com%2Fuploads%2Farticles%2Fm6qik0gpzaxd6qk7ifnb.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.amazonaws.com%2Fuploads%2Farticles%2Fm6qik0gpzaxd6qk7ifnb.png" alt="A glowing vintage scale balancing a yellow JS cube and a blue TS cube, supported by a heavy mechanical base labeled 'Software Design &amp;amp; Fundamentals' and 'Real-World Safety'." width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What’s your take? Does TypeScript make better developers or do fundamentals matter more?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>architecture</category>
      <category>typescript</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
