<?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: Hossam Hamdy</title>
    <description>The latest articles on DEV Community by Hossam Hamdy (@hossam_hamdy_a981027811d6).</description>
    <link>https://dev.to/hossam_hamdy_a981027811d6</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%2F3753227%2Fe7a6da4d-ddf9-489e-a5e6-ad2281740edf.jpg</url>
      <title>DEV Community: Hossam Hamdy</title>
      <link>https://dev.to/hossam_hamdy_a981027811d6</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hossam_hamdy_a981027811d6"/>
    <language>en</language>
    <item>
      <title>I built Injectus, a decorator-free DI container for Node, looking for early users/feedback</title>
      <dc:creator>Hossam Hamdy</dc:creator>
      <pubDate>Thu, 02 Jul 2026 12:01:51 +0000</pubDate>
      <link>https://dev.to/hossam_hamdy_a981027811d6/i-built-injectus-a-decorator-free-di-container-for-node-looking-for-early-usersfeedback-1foc</link>
      <guid>https://dev.to/hossam_hamdy_a981027811d6/i-built-injectus-a-decorator-free-di-container-for-node-looking-for-early-usersfeedback-1foc</guid>
      <description>&lt;p&gt;I've been building a dependency injection container for Node/TypeScript called &lt;strong&gt;Injectus&lt;/strong&gt;, and I'm at the point where I'd rather have a handful of people actually try it and poke holes in it than keep polishing alone. It's &lt;code&gt;0.2.x&lt;/code&gt; not "adopt this in prod tomorrow" young, but the core is solid and I want real usage before I push it further.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; zero-dependency, decorator-free IoC container. No &lt;code&gt;reflect-metadata&lt;/code&gt;, no &lt;code&gt;emitDecoratorMetadata&lt;/code&gt;, no build config wrestling.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;InjectionToken&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="s2"&gt;injectus&lt;/span&gt;&lt;span class="dl"&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;DB_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;InjectionToken&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;DB_URL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DB_URL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;findAll&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;injector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Injector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;providers&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="na"&gt;provide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DB_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;useValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;postgres://localhost/app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;UserService&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="nx"&gt;injector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;injector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispose&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 I built it:&lt;/strong&gt; I kept hitting the same friction with existing containers - decorators requiring specific tsconfig/build setups, string or symbol tokens silently colliding, and singleton/scoped lifetime mismatches only surfacing as bugs in production. Injectus's actual differentiators:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Decorator-free&lt;/strong&gt; - &lt;code&gt;inject()&lt;/code&gt; works in field initializers and factory bodies, no metadata reflection required.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity-based tokens&lt;/strong&gt; - classes and &lt;code&gt;InjectionToken&lt;/code&gt; instances are the key, not their string description. Two tokens named &lt;code&gt;"Logger"&lt;/code&gt; can't collide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Captive dependency detection&lt;/strong&gt; - resolving a &lt;code&gt;Singleton&lt;/code&gt; that depends on a &lt;code&gt;Scoped&lt;/code&gt; binding throws &lt;code&gt;CaptiveDependencyError&lt;/code&gt; at resolve time, not silently in prod.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic disposal&lt;/strong&gt; - LIFO teardown via &lt;code&gt;Symbol.asyncDispose&lt;/code&gt;, multiple failing disposers collected into one &lt;code&gt;AggregateError&lt;/code&gt;, full dependency path exposed root-to-leaf on &lt;code&gt;CircularDependencyError&lt;/code&gt;/&lt;code&gt;CaptiveDependencyError&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also benchmarks well against the two closest points of comparison - &lt;code&gt;awilix&lt;/code&gt; (decorator-free) and &lt;code&gt;tsyringe&lt;/code&gt; (decorator-based) - resolving the same dependency-graph shape in each case:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's honestly not done yet&lt;/strong&gt;, so you know what you're getting into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No module system yet - (flat provider arrays only, for now)&lt;/li&gt;
&lt;li&gt;No multi-injection - registering the same token twice currently shadows (last-write-wins)&lt;/li&gt;
&lt;li&gt;No async init hooks / lifecycle ordering yet&lt;/li&gt;
&lt;li&gt;No framework adapters (Express example exists, others don't)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ioc</category>
      <category>node</category>
      <category>typescript</category>
      <category>dependencyinversion</category>
    </item>
  </channel>
</rss>
