<?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: Jack Apolo</title>
    <description>The latest articles on DEV Community by Jack Apolo (@jack_apolo_beb30743942cf8).</description>
    <link>https://dev.to/jack_apolo_beb30743942cf8</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%2F3603852%2Fd4ddb5fb-1c3f-43b1-81d8-7feb53643831.png</url>
      <title>DEV Community: Jack Apolo</title>
      <link>https://dev.to/jack_apolo_beb30743942cf8</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jack_apolo_beb30743942cf8"/>
    <language>en</language>
    <item>
      <title>Go DI Libraries Comparison: go-infrastructure vs. Fx</title>
      <dc:creator>Jack Apolo</dc:creator>
      <pubDate>Mon, 10 Nov 2025 08:12:47 +0000</pubDate>
      <link>https://dev.to/jack_apolo_beb30743942cf8/go-di-libraries-comparison-go-infrastructure-vs-fx-4jni</link>
      <guid>https://dev.to/jack_apolo_beb30743942cf8/go-di-libraries-comparison-go-infrastructure-vs-fx-4jni</guid>
      <description>&lt;p&gt;Choosing a DI library in Go replaced how you wire services, manage lifecycle, and keep code testable. In this post, I will compare &lt;strong&gt;go-infrastructure&lt;/strong&gt; and &lt;strong&gt;Uber's Fx&lt;/strong&gt; to make a confident choice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why these two?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fx&lt;/strong&gt; is Uber’s DI framework built on &lt;strong&gt;dig&lt;/strong&gt;. It wires dependencies at runtime via reflection and gives you a powerful &lt;strong&gt;application lifecycle&lt;/strong&gt; (hooks for start/stop, modules, invoke). Great when boot order and shutdown choreography matter. (&lt;a href="https://pkg.go.dev/go.uber.org/fx" rel="noopener noreferrer"&gt;pkg.go.dev&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;go-infrastructure&lt;/strong&gt; is “batteries included”: DI plus &lt;strong&gt;logging, config hot-reload, events, error handling&lt;/strong&gt;, filesystem/server helpers—all designed to work together out of the box. (&lt;a href="https://github.com/janmbaco/go-infrastructure" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Side-by-side snapshot
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;go-infrastructure&lt;/th&gt;
&lt;th&gt;Fx (Uber)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DI style&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Typed API; explicit registration &amp;amp; generic resolution&lt;/td&gt;
&lt;td&gt;Reflection-based (via &lt;strong&gt;dig&lt;/strong&gt;) w/ &lt;code&gt;fx.Provide&lt;/code&gt;/&lt;code&gt;fx.Invoke&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lifecycle&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Minimal; use provided modules/utilities&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;First-class&lt;/strong&gt; &lt;code&gt;fx.Lifecycle&lt;/code&gt; with &lt;code&gt;OnStart&lt;/code&gt;/&lt;code&gt;OnStop&lt;/code&gt; hooks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Out-of-the-box modules&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt;: logs, file config reload, events, errors, disk/server&lt;/td&gt;
&lt;td&gt;No defaults; you compose your own&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Learning curve&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Low—ship something fast&lt;/td&gt;
&lt;td&gt;Medium—concepts (Provide/Invoke/Lifecycle) to learn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Maturity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Actively evolving&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Battle-tested&lt;/strong&gt; across Uber services&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Real pros &amp;amp; cons
&lt;/h3&gt;

&lt;h4&gt;
  
  
  go-infrastructure
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Batteries included&lt;/strong&gt;: plug-and-play &lt;strong&gt;logging&lt;/strong&gt;, &lt;strong&gt;hot-reloading config from JSON&lt;/strong&gt;, &lt;strong&gt;typed events&lt;/strong&gt;, consolidated error handling. Less glue in &lt;code&gt;main.go&lt;/code&gt;. (&lt;a href="https://github.com/janmbaco/go-infrastructure" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Straightforward DI&lt;/strong&gt;: register constructors, resolve with generics—easy to follow and easy to test. See container, resolver, and &lt;code&gt;dependencyinjection&lt;/code&gt; package in the repo. (&lt;a href="https://github.com/janmbaco/go-infrastructure" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No central lifecycle like Fx's; if you need ordered start/stop across many subsystems, you'll do a bit more by hand.&lt;/li&gt;
&lt;li&gt;Smaller ecosystem; you'll write a module yourself when integrations get exotic.&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Fx
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lifecycle done right&lt;/strong&gt;: &lt;code&gt;fx.Lifecycle&lt;/code&gt; w/ &lt;code&gt;OnStart&lt;/code&gt;/&lt;code&gt;OnStop&lt;/code&gt; for clean boot/shutdown ordering—critical in big services. (&lt;a href="https://pkg.go.dev/go.uber.org/fx" rel="noopener noreferrer"&gt;pkg.go.dev&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Composable via &lt;code&gt;fx.Provide&lt;/code&gt;/&lt;code&gt;fx.Invoke&lt;/code&gt;, value groups, and modules—scales with team size and dependency graphs. (&lt;a href="https://pkg.go.dev/go.uber.org/fx" rel="noopener noreferrer"&gt;pkg.go.dev&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Widely used (and maintained) in production at Uber. (&lt;a href="https://go.uber.org/" rel="noopener noreferrer"&gt;go.uber.org&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses &lt;strong&gt;reflection&lt;/strong&gt; (via dig): tremendous flexibility, but a little more indirection during boot, and sometimes “magical” error messages. (&lt;a href="https://github.com/uber-go/dig" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;A bit more boilerplate for simple services.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Code you can skim
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Minimal service injection
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;go-infrastructure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;di&lt;/span&gt; &lt;span class="s"&gt;"github.com/janmbaco/go-infrastructure/dependencyinjection"&lt;/span&gt; &lt;span class="c"&gt;// use /v2 if your module is v2&lt;/span&gt;
    &lt;span class="n"&gt;logsIoc&lt;/span&gt; &lt;span class="s"&gt;"github.com/janmbaco/go-infrastructure/logs/ioc"&lt;/span&gt;       &lt;span class="c"&gt;// ...and /v2 here too&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;UserService&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewUserService&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;AddModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logsIoc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewLogsModule&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Register&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsSingleton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;NewUserService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;MustBuild&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;svc&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolver&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;svc&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repo exhibits this pattern (builder → modules → &lt;code&gt;Resolve&lt;/code&gt;). (&lt;a href="https://github.com/janmbaco/go-infrastructure" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"go.uber.org/fx"&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;UserService&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;NewUserService&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;fx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Provide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NewUserService&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;fx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c"&gt;// use s&lt;/span&gt;
        &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&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;p&gt;Typical &lt;code&gt;Provide&lt;/code&gt;/&lt;code&gt;Invoke&lt;/code&gt;/&lt;code&gt;Run()&lt;/code&gt; flow. (&lt;a href="https://pkg.go.dev/go.uber.org/fx" rel="noopener noreferrer"&gt;pkg.go.dev&lt;/a&gt;)&lt;/p&gt;




&lt;h4&gt;
  
  
  Config that hot-reloads
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;go-infrastructure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;di&lt;/span&gt; &lt;span class="s"&gt;"github.com/janmbaco/go-infrastructure/dependencyinjection"&lt;/span&gt; &lt;span class="c"&gt;// use /v2 if applicable&lt;/span&gt;
    &lt;span class="n"&gt;cfgIoc&lt;/span&gt; &lt;span class="s"&gt;"github.com/janmbaco/go-infrastructure/configuration/fileconfig/ioc"&lt;/span&gt;
    &lt;span class="n"&gt;cfgRes&lt;/span&gt; &lt;span class="s"&gt;"github.com/janmbaco/go-infrastructure/configuration/fileconfig/ioc/resolver"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Port&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="s"&gt;`json:"port"`&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;di&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfgIoc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewConfigurationModule&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MustBuild&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;cfgRes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetFileConfigHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolver&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"config.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Port&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetConfig&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// updates when the file changes&lt;/span&gt;
    &lt;span class="k"&gt;select&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;p&gt;Hot-reload from JSON is part of the provided modules. (&lt;a href="https://github.com/janmbaco/go-infrastructure" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fx&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You’ll bring your own config loader/watcher and wire its start/stop with &lt;code&gt;fx.Lifecycle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;fx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;New&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;fx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Provide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NewConfigWatcher&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;fx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lc&lt;/span&gt; &lt;span class="n"&gt;fx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lifecycle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ConfigWatcher&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;lc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Hook&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;OnStart&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="n"&gt;OnStop&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;  &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stop&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="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fx has first-class lifecycle hooks. (&lt;a href="https://pkg.go.dev/go.uber.org/fx" rel="noopener noreferrer"&gt;pkg.go.dev&lt;/a&gt;)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Import-path note (SemVer v2+)&lt;/strong&gt;: when you ship &lt;strong&gt;v2&lt;/strong&gt; of your module, imports must specify &lt;code&gt;/v2&lt;/code&gt; (example: &lt;code&gt;github.com/janmbaco/go-infrastructure/v2/...&lt;/code&gt;). Otherwise, &lt;code&gt;go get&lt;/code&gt; won’t resolve the right major. (&lt;a href="https://github.com/uber-go/dig" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Verdict: Which one should you pick?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;go-infrastructure&lt;/strong&gt; when you need to &lt;strong&gt;ship fast&lt;/strong&gt; with logging, hot-reloading config, events, and DI already wired. For normal HTTP services or microservices where you don't need intricate boot choreography, it cuts boilerplate and gets you to "working app" quicker. &lt;strong&gt;This is my default to get a service live.&lt;/strong&gt; (&lt;a href="https://github.com/janmbaco/go-infrastructure" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Fx&lt;/strong&gt; when you have &lt;strong&gt;complicated startup/shutdown requirements&lt;/strong&gt;, many subsystems which have to start in order, or a large team that benefits from strict lifecycle semantics and modular composition. &lt;strong&gt;This is my pick for large multi-module systems.&lt;/strong&gt; (&lt;a href="https://pkg.go.dev/go.uber.org/fx" rel="noopener noreferrer"&gt;pkg.go.dev&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're on the fence: prototype a small slice in both. If lifecycle hooks drive your design, Fx will feel natural; if your priority is getting robust plumbing with minimal ceremony, go-infrastructure will feel lighter.&lt;/p&gt;




&lt;h3&gt;
  
  
  Further reading
&lt;/h3&gt;

</description>
      <category>architecture</category>
      <category>go</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
