<?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: Vanni Daghini</title>
    <description>The latest articles on DEV Community by Vanni Daghini (@vanni7544).</description>
    <link>https://dev.to/vanni7544</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%2F3692340%2F43cbe168-d30c-4307-95a8-0dbaf1b5a5e2.jpeg</url>
      <title>DEV Community: Vanni Daghini</title>
      <link>https://dev.to/vanni7544</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vanni7544"/>
    <language>en</language>
    <item>
      <title>Declarative and observable monitor management with Python</title>
      <dc:creator>Vanni Daghini</dc:creator>
      <pubDate>Fri, 06 Feb 2026 07:24:38 +0000</pubDate>
      <link>https://dev.to/vanni7544/declarative-and-observable-monitor-management-with-python-32oc</link>
      <guid>https://dev.to/vanni7544/declarative-and-observable-monitor-management-with-python-32oc</guid>
      <description>&lt;h1&gt;
  
  
  tool-clean: a declarative and observable approach to monitor management
&lt;/h1&gt;

&lt;p&gt;When dealing with system configuration, I tend to prefer &lt;strong&gt;explicit control&lt;/strong&gt; over automation.&lt;/p&gt;

&lt;p&gt;This is especially true in IT environments, where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;predictability matters more than convenience&lt;/li&gt;
&lt;li&gt;implicit behavior becomes technical debt&lt;/li&gt;
&lt;li&gt;“magic” often hides responsibility rather than reducing it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that mindset, I built &lt;strong&gt;tool-clean&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What tool-clean is (and is not)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;tool-clean&lt;/strong&gt; is a &lt;strong&gt;CLI tool written in Python&lt;/strong&gt; for &lt;strong&gt;observable and declarative monitor management&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;observe connected monitors&lt;/li&gt;
&lt;li&gt;identify them in a stable way&lt;/li&gt;
&lt;li&gt;assign human-readable labels&lt;/li&gt;
&lt;li&gt;declare usage profiles&lt;/li&gt;
&lt;li&gt;associate profiles to monitors&lt;/li&gt;
&lt;li&gt;persist everything locally&lt;/li&gt;
&lt;li&gt;audit all mutating actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What it &lt;strong&gt;does not&lt;/strong&gt; do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it does not apply system configurations&lt;/li&gt;
&lt;li&gt;it does not change brightness or resolution&lt;/li&gt;
&lt;li&gt;it does not interact with drivers or OS APIs&lt;/li&gt;
&lt;li&gt;it does not make autonomous decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is intentional.&lt;/p&gt;




&lt;h2&gt;
  
  
  The design philosophy
&lt;/h2&gt;

&lt;p&gt;tool-clean is built around a few non-negotiable principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Human control is explicit&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Observation is separate from intention&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Declaration is separate from execution&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nothing happens implicitly&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Everything relevant is audit-visible&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, this means the tool never “reacts” to state.&lt;br&gt;&lt;br&gt;
It only &lt;strong&gt;records and exposes it&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why not automate?
&lt;/h2&gt;

&lt;p&gt;Automation is powerful, but it comes with costs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hidden assumptions&lt;/li&gt;
&lt;li&gt;unclear responsibility&lt;/li&gt;
&lt;li&gt;difficult audits&lt;/li&gt;
&lt;li&gt;fragile edge cases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In many IT contexts, the real need is not automation, but clarity.&lt;/p&gt;

&lt;p&gt;tool-clean is meant to be a &lt;strong&gt;foundation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;something an IT operator can reason about&lt;/li&gt;
&lt;li&gt;something you can inspect and revoke&lt;/li&gt;
&lt;li&gt;something that does not surprise you six months later&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How it works (conceptually)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The system observes the real state (connected monitors)&lt;/li&gt;
&lt;li&gt;The user declares a profile (an intention, not an action)&lt;/li&gt;
&lt;li&gt;The user associates that profile to a monitor&lt;/li&gt;
&lt;li&gt;The state is persisted and audited&lt;/li&gt;
&lt;li&gt;Any real application happens &lt;strong&gt;outside&lt;/strong&gt; the tool&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The tool remains read-only with respect to the operating system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical overview
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10+&lt;/li&gt;
&lt;li&gt;CLI-first (not a library)&lt;/li&gt;
&lt;li&gt;Local-only execution&lt;/li&gt;
&lt;li&gt;SQLite for persistence&lt;/li&gt;
&lt;li&gt;Append-only audit log (INFO / WARN / SECURITY)&lt;/li&gt;
&lt;li&gt;No network dependencies&lt;/li&gt;
&lt;li&gt;No background services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project uses a clean &lt;code&gt;src/&lt;/code&gt; layout and a strict separation between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CLI parsing&lt;/li&gt;
&lt;li&gt;domain commands&lt;/li&gt;
&lt;li&gt;observed state&lt;/li&gt;
&lt;li&gt;persistence&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Current scope: Base v2
&lt;/h2&gt;

&lt;p&gt;The current public release is &lt;strong&gt;Base v2&lt;/strong&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;no centralized management&lt;/li&gt;
&lt;li&gt;no federation&lt;/li&gt;
&lt;li&gt;no policy enforcement&lt;/li&gt;
&lt;li&gt;no automatic configuration application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those ideas may belong to future versions, but &lt;strong&gt;not to the base&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Base v2 is meant to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stable&lt;/li&gt;
&lt;li&gt;inspectable&lt;/li&gt;
&lt;li&gt;defensible&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Repository
&lt;/h2&gt;

&lt;p&gt;The project is open source (MIT licensed):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Vanni7544/tool-clean" rel="noopener noreferrer"&gt;https://github.com/Vanni7544/tool-clean&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repository includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;full documentation&lt;/li&gt;
&lt;li&gt;a canonical source snapshot&lt;/li&gt;
&lt;li&gt;clear contribution guidelines&lt;/li&gt;
&lt;li&gt;a defined security policy&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Closing thoughts
&lt;/h2&gt;

&lt;p&gt;tool-clean is not meant to be flashy.&lt;/p&gt;

&lt;p&gt;It is meant to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;boring in the right way&lt;/li&gt;
&lt;li&gt;predictable&lt;/li&gt;
&lt;li&gt;explicit&lt;/li&gt;
&lt;li&gt;safe to reason about&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re interested in tools that favor &lt;strong&gt;clarity over automation&lt;/strong&gt;,&lt;br&gt;&lt;br&gt;
this project might resonate with you.&lt;/p&gt;

&lt;p&gt;Technical feedback is welcome.&lt;/p&gt;

</description>
      <category>python</category>
      <category>cli</category>
      <category>tooling</category>
      <category>devops</category>
    </item>
    <item>
      <title># The `Person` class is lying to you (and that’s okay)</title>
      <dc:creator>Vanni Daghini</dc:creator>
      <pubDate>Mon, 19 Jan 2026 15:25:52 +0000</pubDate>
      <link>https://dev.to/vanni7544/-the-person-class-is-lying-to-you-and-thats-okay-36c7</link>
      <guid>https://dev.to/vanni7544/-the-person-class-is-lying-to-you-and-thats-okay-36c7</guid>
      <description>&lt;p&gt;When you start learning Object-Oriented Programming, sooner or later it happens.&lt;/p&gt;

&lt;p&gt;Someone says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Let’s make a simple example.”&lt;br&gt;
And the example is almost always the same:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nv"&gt;$age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;think&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;decide&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The legendary &lt;strong&gt;&lt;code&gt;Person&lt;/code&gt; class&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It looks harmless.&lt;br&gt;&lt;br&gt;
It even looks &lt;em&gt;natural&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;But there’s a small problem.&lt;/p&gt;

&lt;p&gt;This class is lying to you.&lt;/p&gt;

&lt;p&gt;And it’s doing it with good intentions.&lt;/p&gt;
&lt;h2&gt;
  
  
  The first (necessary) lie of OOP
&lt;/h2&gt;

&lt;p&gt;The lie is not technical.&lt;br&gt;&lt;br&gt;
It’s conceptual.&lt;/p&gt;

&lt;p&gt;That &lt;code&gt;Person&lt;/code&gt; class silently suggests that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a person can be fully described
&lt;/li&gt;
&lt;li&gt;their state is knowable
&lt;/li&gt;
&lt;li&gt;their decisions are modellable
&lt;/li&gt;
&lt;li&gt;their values are consistent
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of course, we know this isn’t true.&lt;/p&gt;

&lt;p&gt;And yet, we keep using this example.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because &lt;strong&gt;programming is not about describing reality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s about &lt;strong&gt;reducing chaos into something we can manage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Person&lt;/code&gt; class is not reality.&lt;/p&gt;

&lt;p&gt;It’s a map.&lt;/p&gt;

&lt;p&gt;And maps always lie a little.&lt;/p&gt;
&lt;h2&gt;
  
  
  The problem is not simplification
&lt;/h2&gt;
&lt;h2&gt;
  
  
  The problem is forgetting it
&lt;/h2&gt;

&lt;p&gt;Simplification is not a mistake.&lt;/p&gt;

&lt;p&gt;It’s unavoidable.&lt;/p&gt;

&lt;p&gt;The problem starts when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we confuse the map with the territory
&lt;/li&gt;
&lt;li&gt;we assume the model &lt;em&gt;is&lt;/em&gt; reality
&lt;/li&gt;
&lt;li&gt;we blindly trust what the software “decides”
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where serious problems begin, especially in complex systems.&lt;/p&gt;
&lt;h2&gt;
  
  
  A small thought experiment
&lt;/h2&gt;

&lt;p&gt;Let’s try a game.&lt;br&gt;
What if we wrote a &lt;code&gt;Person&lt;/code&gt; class that &lt;strong&gt;explicitly admits its limits&lt;/strong&gt;?&lt;br&gt;
Not a simulation of a human being.&lt;br&gt;&lt;br&gt;
Not an artificial mind.&lt;/p&gt;

&lt;p&gt;Just an honest object.&lt;br&gt;
Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Observed state (never complete)&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$states&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

    &lt;span class="c1"&gt;// Declared values (not always respected)&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

    &lt;span class="c1"&gt;// Action history (not the truth)&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Observe a piece of reality&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;mixed&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;states&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;history&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="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'observation'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'key'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'time'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;time&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="c1"&gt;// Declare a value&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;declareValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Decide under uncertainty&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;decide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$options&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Not optimal, just plausible&lt;/span&gt;
        &lt;span class="nv"&gt;$choice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;array_rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$options&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;history&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="s1"&gt;'type'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'decision'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'choice'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$choice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'time'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;time&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="nv"&gt;$choice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Expose history, not truth&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;history&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What actually changes?
&lt;/h2&gt;

&lt;p&gt;This &lt;code&gt;Person&lt;/code&gt; class openly states that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;state is partial
&lt;/li&gt;
&lt;li&gt;values are not hard rules
&lt;/li&gt;
&lt;li&gt;decisions are not optimal
&lt;/li&gt;
&lt;li&gt;history is not truth, just a trace
In other words:&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;the software does not pretend to understand everything&lt;/strong&gt;&lt;br&gt;
Paradoxically, this makes it safer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why this matters (outside toy examples)
&lt;/h2&gt;

&lt;p&gt;In real systems — business software, enterprise platforms, infrastructure —&lt;br&gt;&lt;br&gt;
problems rarely happen because software is “stupid”.&lt;/p&gt;

&lt;p&gt;They happen because software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;makes silent decisions
&lt;/li&gt;
&lt;li&gt;auto-corrects without saying so
&lt;/li&gt;
&lt;li&gt;acts without leaving traces
&lt;/li&gt;
&lt;li&gt;closes in on itself
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A system becomes dangerous &lt;strong&gt;when it stops admitting its own limits&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple idea to take with you
&lt;/h2&gt;

&lt;p&gt;OOP is not meant to simulate human beings.&lt;/p&gt;

&lt;p&gt;It’s meant to make explicit &lt;strong&gt;what we can model&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
and, more importantly, &lt;strong&gt;what we cannot&lt;/strong&gt;.&lt;br&gt;
The classic &lt;code&gt;Person&lt;/code&gt; class is not wrong.&lt;/p&gt;

&lt;p&gt;It’s incomplete.&lt;br&gt;
The mistake is not writing it.&lt;/p&gt;

&lt;p&gt;The mistake is forgetting that it lies a little.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The best software is not the one that “decides better”.&lt;/p&gt;

&lt;p&gt;It’s the one that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;exposes its rules
&lt;/li&gt;
&lt;li&gt;leaves traces
&lt;/li&gt;
&lt;li&gt;asks for confirmation
&lt;/li&gt;
&lt;li&gt;admits uncertainty
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Maybe the first thing we should teach&lt;br&gt;&lt;br&gt;
when we introduce the &lt;code&gt;Person&lt;/code&gt; class&lt;br&gt;&lt;br&gt;
is not &lt;em&gt;how it works&lt;/em&gt;…&lt;/p&gt;

&lt;p&gt;but &lt;strong&gt;where it stops&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>oop</category>
      <category>programming</category>
      <category>design</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title># Laravel Pure Alert: a Blade-native alert system for backend interfaces</title>
      <dc:creator>Vanni Daghini</dc:creator>
      <pubDate>Sun, 18 Jan 2026 17:47:31 +0000</pubDate>
      <link>https://dev.to/vanni7544/-laravel-pure-alert-a-blade-native-alert-system-for-backend-interfaces-2laf</link>
      <guid>https://dev.to/vanni7544/-laravel-pure-alert-a-blade-native-alert-system-for-backend-interfaces-2laf</guid>
      <description>&lt;p&gt;Most Laravel projects eventually need alerts.&lt;/p&gt;

&lt;p&gt;Not fancy notifications.&lt;br&gt;
Just clear feedback: something was saved, something failed, something needs confirmation.&lt;/p&gt;

&lt;p&gt;In backend interfaces and admin panels, this often turns into JavaScript helpers, inline scripts, or UI libraries that do much more than required.&lt;/p&gt;

&lt;p&gt;Laravel Pure Alert was born from the need to keep this part of the application simple and predictable.&lt;/p&gt;

&lt;p&gt;In CRUD-heavy applications, alerts are not really a UI feature.&lt;/p&gt;

&lt;p&gt;They belong to the request lifecycle.&lt;/p&gt;

&lt;p&gt;A controller handles a request, performs an action, redirects, and the user expects feedback:&lt;br&gt;
success, error, or confirmation before a destructive action.&lt;/p&gt;

&lt;p&gt;This flow is already server-side, yet many solutions introduce extra layers and indirection in places that should remain straightforward.&lt;/p&gt;

&lt;p&gt;Laravel Pure Alert is a Blade-native alert and confirmation system designed for backend applications.&lt;/p&gt;

&lt;p&gt;Alerts are triggered server-side and rendered through Blade components.&lt;br&gt;
There is no frontend state to manage and no JavaScript framework involved.&lt;/p&gt;

&lt;p&gt;Everything follows Laravel’s natural request–response flow.&lt;/p&gt;

&lt;p&gt;This package is intentionally minimal.&lt;/p&gt;

&lt;p&gt;It does not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;support SPA workflows&lt;/li&gt;
&lt;li&gt;manage frontend state&lt;/li&gt;
&lt;li&gt;replace JavaScript UI frameworks&lt;/li&gt;
&lt;li&gt;add visual effects or animations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Laravel Pure Alert is built for admin panels, internal tools, and backend-first interfaces.&lt;/p&gt;

&lt;p&gt;Backend interfaces benefit from predictable behavior.&lt;/p&gt;

&lt;p&gt;When alerts live in Blade:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;permissions are respected automatically&lt;/li&gt;
&lt;li&gt;redirects behave exactly as expected&lt;/li&gt;
&lt;li&gt;debugging is straightforward&lt;/li&gt;
&lt;li&gt;the execution flow is easy to follow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You read the controller, follow the redirect, and see the alert in the layout.&lt;br&gt;
No additional layers to reason about.&lt;/p&gt;

&lt;p&gt;A typical usage starts in the controller, during a redirect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\Request&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ... store logic&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'User created'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'The user has been created successfully.'&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;redirectRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users.index'&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;The alert component is rendered once in your main layout.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;x-alert /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For destructive actions, a confirmation component can be used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;x-confirm-delete
    action="{{ route('users.destroy', $user) }}"
    method="DELETE"
    message="Are you sure you want to delete this user?"
&amp;gt;
    Delete
&amp;lt;/x-confirm-delete&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Laravel Pure Alert follows a few simple principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;small, readable Blade components&lt;/li&gt;
&lt;li&gt;no implicit side effects&lt;/li&gt;
&lt;li&gt;easy to remove if requirements change&lt;/li&gt;
&lt;li&gt;no lock-in to a specific frontend stack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is clarity rather than abstraction.&lt;/p&gt;

&lt;p&gt;The source code is public and can be inspected on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Vanni7544/laravel-pure-alert" rel="noopener noreferrer"&gt;https://github.com/Vanni7544/laravel-pure-alert&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The complete documentation and usage notes are provided separately as a commercial product.&lt;/p&gt;

&lt;p&gt;This is a conscious choice to keep the project sustainable while keeping the implementation transparent.&lt;/p&gt;

&lt;p&gt;Full documentation is available here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://daghini.gumroad.com/l/hnziix" rel="noopener noreferrer"&gt;https://daghini.gumroad.com/l/hnziix&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Laravel Pure Alert is a good fit if you are building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;admin panels&lt;/li&gt;
&lt;li&gt;internal tools&lt;/li&gt;
&lt;li&gt;CRUD-heavy applications&lt;/li&gt;
&lt;li&gt;backend-driven interfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is not designed for frontend-first or animation-heavy projects.&lt;/p&gt;

&lt;p&gt;Not every Laravel project needs more JavaScript or more abstraction.&lt;/p&gt;

&lt;p&gt;Sometimes a small, predictable solution is enough.&lt;/p&gt;

&lt;p&gt;If this approach matches how you build backend applications, you can explore the code on GitHub and the documentation on Gumroad.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>backend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Config Manager for Laravel: transitioning the Base to MIT and introducing the Pro edition</title>
      <dc:creator>Vanni Daghini</dc:creator>
      <pubDate>Thu, 15 Jan 2026 11:52:47 +0000</pubDate>
      <link>https://dev.to/vanni7544/config-manager-for-laravel-transitioning-the-base-to-mit-and-introducing-the-pro-edition-38n4</link>
      <guid>https://dev.to/vanni7544/config-manager-for-laravel-transitioning-the-base-to-mit-and-introducing-the-pro-edition-38n4</guid>
      <description>&lt;h1&gt;
  
  
  Config Manager for Laravel: transitioning the Base to MIT and introducing the Pro edition
&lt;/h1&gt;

&lt;p&gt;Over the past months I’ve been working on &lt;strong&gt;Config Manager&lt;/strong&gt;, a Laravel package focused on one very specific and often underestimated problem:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;managing &lt;code&gt;.env&lt;/code&gt; files safely in real production environments&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While building this package, I realized how many assumptions we usually make about configuration safety — until something goes wrong in production.&lt;/p&gt;

&lt;p&gt;Today I want to clearly explain two important things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;why the &lt;strong&gt;Base edition has transitioned to MIT&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;why a &lt;strong&gt;Pro edition exists and is commercial&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a marketing post.&lt;br&gt;&lt;br&gt;
It’s about design choices, transparency, and sustainability.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem I wanted to solve
&lt;/h2&gt;

&lt;p&gt;In many Laravel projects, configuration management is still handled manually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;copying &lt;code&gt;.env&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;editing values directly on servers&lt;/li&gt;
&lt;li&gt;applying changes without a clear audit trail&lt;/li&gt;
&lt;li&gt;rolling back by guesswork&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This works… until it doesn’t.&lt;/p&gt;

&lt;p&gt;Production environments require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;predictability&lt;/li&gt;
&lt;li&gt;safety&lt;/li&gt;
&lt;li&gt;explicit control&lt;/li&gt;
&lt;li&gt;reversible actions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Config Manager was born to address exactly this.&lt;/p&gt;




&lt;h2&gt;
  
  
  Config Manager Base (MIT)
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Base edition&lt;/strong&gt; of Config Manager is now released as &lt;strong&gt;open-source (MIT)&lt;/strong&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;structured environment configuration storage&lt;/li&gt;
&lt;li&gt;safe export to &lt;code&gt;.env&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;automatic backups&lt;/li&gt;
&lt;li&gt;basic rollback support&lt;/li&gt;
&lt;li&gt;production warnings&lt;/li&gt;
&lt;li&gt;a console-first workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Base is meant to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;understandable&lt;/li&gt;
&lt;li&gt;hackable&lt;/li&gt;
&lt;li&gt;educational&lt;/li&gt;
&lt;li&gt;useful for many projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Transitioning the Base to MIT was a conscious decision.&lt;/p&gt;

&lt;p&gt;Open source is where this project started, and it remains a core part of it.&lt;/p&gt;

&lt;p&gt;You can explore the Base edition here:&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://github.com/Vanni7544/config-manager" rel="noopener noreferrer"&gt;https://github.com/Vanni7544/config-manager&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why a Pro edition exists
&lt;/h2&gt;

&lt;p&gt;While working on the Base, a clear line emerged.&lt;/p&gt;

&lt;p&gt;Some features are not about convenience, but about &lt;strong&gt;risk management&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;detailed audit logs&lt;/li&gt;
&lt;li&gt;explicit production guards&lt;/li&gt;
&lt;li&gt;guided recovery flows&lt;/li&gt;
&lt;li&gt;diagnostic tools&lt;/li&gt;
&lt;li&gt;human-error prevention&lt;/li&gt;
&lt;li&gt;long-term maintenance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These features require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more design&lt;/li&gt;
&lt;li&gt;more testing&lt;/li&gt;
&lt;li&gt;more responsibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s where &lt;strong&gt;Config Manager Pro&lt;/strong&gt; comes in.&lt;/p&gt;




&lt;h2&gt;
  
  
  Config Manager Pro
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Pro edition&lt;/strong&gt; builds on top of the MIT Base and focuses on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Structured audit logging&lt;/strong&gt; (INFO / WARN / SECURITY)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selective rollback&lt;/strong&gt;, with explicit backup selection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced production guards&lt;/strong&gt; with mandatory confirmation&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;diagnostic &lt;code&gt;config-manager:sync&lt;/code&gt; command&lt;/strong&gt; (read-only)&lt;/li&gt;
&lt;li&gt;A guided CLI UX with explicit exit paths&lt;/li&gt;
&lt;li&gt;Pro-only safety and consistency checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a SaaS.&lt;br&gt;&lt;br&gt;
There is no cloud.&lt;br&gt;&lt;br&gt;
No background automation.&lt;br&gt;&lt;br&gt;
No remote control.&lt;/p&gt;

&lt;p&gt;It’s still a local, explicit, and predictable tool.&lt;/p&gt;

&lt;p&gt;You can inspect the Pro source code here:&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://github.com/Vanni7544/config-manager-pro" rel="noopener noreferrer"&gt;https://github.com/Vanni7544/config-manager-pro&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The commercial license is available here:&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://daghini.gumroad.com/l/urbzs" rel="noopener noreferrer"&gt;https://daghini.gumroad.com/l/urbzs&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  A note for early supporters of the Base edition
&lt;/h2&gt;

&lt;p&gt;Before the Base transitioned to MIT, it was distributed under a proprietary license.&lt;/p&gt;

&lt;p&gt;If you purchased the Base edition during that period, I want to be very clear and fair about it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;you will receive a 100% refund&lt;/strong&gt;, no questions asked&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;you will also receive a 50% discount on Config Manager Pro&lt;/strong&gt;, if you choose to upgrade&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not an upsell tactic.&lt;br&gt;&lt;br&gt;
It’s about respecting early supporters and making sure no one feels penalized by the transition.&lt;/p&gt;

&lt;p&gt;If this applies to you, just get in touch and it will be handled transparently.&lt;/p&gt;




&lt;h2&gt;
  
  
  Open source and sustainability
&lt;/h2&gt;

&lt;p&gt;Making the Base MIT does not mean the Pro is “closed”.&lt;/p&gt;

&lt;p&gt;Config Manager Pro is &lt;strong&gt;source-available&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the code is readable&lt;/li&gt;
&lt;li&gt;the design is inspectable&lt;/li&gt;
&lt;li&gt;behavior is explicit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What you pay for is &lt;strong&gt;the license to use it in production&lt;/strong&gt;, along with continued development.&lt;/p&gt;

&lt;p&gt;This balance allows the project to grow without compromising its principles.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final notes
&lt;/h2&gt;

&lt;p&gt;If the Base edition is enough for your needs, that’s perfectly fine.&lt;br&gt;
That’s exactly why it’s MIT.&lt;/p&gt;

&lt;p&gt;If you manage real production environments and value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;safety&lt;/li&gt;
&lt;li&gt;predictability&lt;/li&gt;
&lt;li&gt;accountability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;then the Pro edition exists for you.&lt;/p&gt;

&lt;p&gt;Thanks for reading,&lt;br&gt;&lt;br&gt;
and thanks to everyone who supports sustainable open-source development.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>devtools</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Building a safer way to manage .env in Laravel — and I’ve just released the public roadmap</title>
      <dc:creator>Vanni Daghini</dc:creator>
      <pubDate>Tue, 06 Jan 2026 11:00:28 +0000</pubDate>
      <link>https://dev.to/vanni7544/building-a-safer-way-to-manage-env-in-laravel-and-ive-just-released-the-public-roadmap-2hha</link>
      <guid>https://dev.to/vanni7544/building-a-safer-way-to-manage-env-in-laravel-and-ive-just-released-the-public-roadmap-2hha</guid>
      <description>&lt;p&gt;Hi everyone 👋&lt;/p&gt;

&lt;p&gt;A few days ago I shared here a tool I’ve been building for Laravel to make working with &lt;code&gt;.env&lt;/code&gt; files a bit safer and less stressful.&lt;/p&gt;

&lt;p&gt;Over the past weeks I realised how easy it is to break an application just by:&lt;br&gt;
• missing an environment variable&lt;br&gt;&lt;br&gt;
• overwriting the wrong &lt;code&gt;.env&lt;/code&gt;&lt;br&gt;&lt;br&gt;
• changing something in production too quickly  &lt;/p&gt;

&lt;p&gt;So I decided to build a small tool whose only job is to make &lt;code&gt;.env&lt;/code&gt; management more &lt;strong&gt;safe, predictable and reversible&lt;/strong&gt; — without turning Laravel into something it’s not.&lt;/p&gt;

&lt;p&gt;I’ve now published a &lt;strong&gt;public product roadmap&lt;/strong&gt; so that everything is clear and transparent:&lt;br&gt;
👉 &lt;a href="https://github.com/Vanni7544/config-manager/blob/main/ROADMAP.md" rel="noopener noreferrer"&gt;https://github.com/Vanni7544/config-manager/blob/main/ROADMAP.md&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the tool currently does
&lt;/h2&gt;

&lt;p&gt;Right now Config Manager allows you to:&lt;/p&gt;

&lt;p&gt;✔ export environment configuration&lt;br&gt;&lt;br&gt;
✔ validate required variables before export&lt;br&gt;&lt;br&gt;
✔ generate a &lt;code&gt;.env.config-manager&lt;/code&gt; file&lt;br&gt;&lt;br&gt;
✔ optionally apply it using &lt;code&gt;--apply&lt;/code&gt;&lt;br&gt;&lt;br&gt;
✔ automatically back up the previous &lt;code&gt;.env&lt;/code&gt;&lt;br&gt;&lt;br&gt;
✔ rollback safely when needed&lt;br&gt;&lt;br&gt;
✔ show clear warnings when dealing with production  &lt;/p&gt;

&lt;p&gt;So instead of editing &lt;code&gt;.env&lt;/code&gt; manually and hoping for the best,&lt;br&gt;
the workflow becomes much more controlled and calm.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s coming next (Pro Edition)
&lt;/h2&gt;

&lt;p&gt;In the roadmap I describe the next major goals, including:&lt;/p&gt;

&lt;p&gt;🔹 local audit logs (no SaaS, no external services)&lt;br&gt;&lt;br&gt;
🔹 the ability to choose which backup to restore&lt;br&gt;&lt;br&gt;
🔹 a simple terminal CLI so nobody needs Tinker&lt;br&gt;&lt;br&gt;
🔹 better onboarding and safety UX  &lt;/p&gt;

&lt;p&gt;All development will stay focused on:&lt;/p&gt;

&lt;p&gt;✔ safety&lt;br&gt;&lt;br&gt;
✔ reversibility&lt;br&gt;&lt;br&gt;
✔ predictability&lt;br&gt;&lt;br&gt;
✔ keeping things local  &lt;/p&gt;

&lt;h2&gt;
  
  
  Long-term vision
&lt;/h2&gt;

&lt;p&gt;There will eventually be a &lt;strong&gt;Security / Enterprise Edition&lt;/strong&gt; with things like:&lt;/p&gt;

&lt;p&gt;🔸 declarative environment rules&lt;br&gt;&lt;br&gt;
🔸 dry-run mode with human-readable output&lt;br&gt;&lt;br&gt;
🔸 structured audit logging&lt;br&gt;&lt;br&gt;
🔸 CI/CD validation support&lt;br&gt;&lt;br&gt;
🔸 diff between environment versions  &lt;/p&gt;

&lt;p&gt;But the core philosophy will never change:&lt;br&gt;
🚫 no remote config storage&lt;br&gt;&lt;br&gt;
🚫 no silent updates&lt;br&gt;&lt;br&gt;
🚫 no hidden magic  &lt;/p&gt;

&lt;h2&gt;
  
  
  If you want to have a look
&lt;/h2&gt;

&lt;p&gt;GitHub (details, docs, roadmap):&lt;br&gt;
👉 &lt;a href="https://github.com/Vanni7544/config-manager" rel="noopener noreferrer"&gt;https://github.com/Vanni7544/config-manager&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AMA — happy to chat 🙂
&lt;/h2&gt;

&lt;p&gt;If you’re curious about:&lt;/p&gt;

&lt;p&gt;• why I built it&lt;br&gt;&lt;br&gt;
• how it works internally&lt;br&gt;&lt;br&gt;
• real problems it solved for me&lt;br&gt;&lt;br&gt;
• what you would improve&lt;br&gt;&lt;br&gt;
• whether this is useful in your workflow  &lt;/p&gt;

&lt;p&gt;…feel free to ask anything.&lt;br&gt;&lt;br&gt;
I’m not trying to spam — I genuinely enjoy talking about safe configuration practices in Laravel and learning from how others do it.&lt;/p&gt;

&lt;p&gt;Thanks for reading 🙏&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I built a safer way to manage .env files in Laravel (export, validate, backup, rollback)</title>
      <dc:creator>Vanni Daghini</dc:creator>
      <pubDate>Sun, 04 Jan 2026 09:26:07 +0000</pubDate>
      <link>https://dev.to/vanni7544/i-built-a-safer-way-to-manage-env-files-in-laravel-export-validate-backup-rollback-1cdg</link>
      <guid>https://dev.to/vanni7544/i-built-a-safer-way-to-manage-env-files-in-laravel-export-validate-backup-rollback-1cdg</guid>
      <description>&lt;p&gt;Over the last few weeks, I’ve been working on a small tool for Laravel that was born from a real-world problem I kept running into: safely managing &lt;code&gt;.env&lt;/code&gt; files across multiple environments (local, staging, production).&lt;/p&gt;

&lt;p&gt;I noticed how little it takes — a missing value, a wrong variable, a rushed copy-paste — to break an application. And when this happens in production, it’s stressful and risky.&lt;/p&gt;

&lt;p&gt;So I decided to build something that would make &lt;code&gt;.env&lt;/code&gt; management a bit safer and more controlled — without changing how Laravel works.&lt;/p&gt;

&lt;p&gt;This is not meant as spam 🙂 — I’m sharing it because it might be useful to others, and also because I’d love to hear how you all manage this topic in your own workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔐 What the tool does (in simple terms)
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;.env&lt;/code&gt; file usually contains things like:&lt;/p&gt;

&lt;p&gt;• database credentials&lt;br&gt;&lt;br&gt;
• API keys&lt;br&gt;&lt;br&gt;
• environment mode&lt;br&gt;&lt;br&gt;
• other critical configuration values  &lt;/p&gt;

&lt;p&gt;It’s a fragile file — one wrong line and the app stops working.&lt;/p&gt;

&lt;p&gt;So the tool acts like a &lt;strong&gt;“safety layer”&lt;/strong&gt; for &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It lets you:&lt;/p&gt;

&lt;p&gt;✔ manage configuration per-environment&lt;br&gt;&lt;br&gt;
✔ export a generated &lt;code&gt;.env&lt;/code&gt; when you choose&lt;br&gt;&lt;br&gt;
✔ automatically back up your old &lt;code&gt;.env&lt;/code&gt;&lt;br&gt;&lt;br&gt;
✔ rollback instantly if needed  &lt;/p&gt;

&lt;p&gt;And most importantly:&lt;/p&gt;

&lt;p&gt;➡ your real &lt;code&gt;.env&lt;/code&gt; is &lt;strong&gt;NOT touched unless you explicitly apply it&lt;/strong&gt;  &lt;/p&gt;
&lt;h2&gt;
  
  
  🧪 Examples
&lt;/h2&gt;

&lt;p&gt;Export a configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan config-manager:export &amp;lt;project-id&amp;gt; &amp;lt;environment-id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.env.config-manager
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your &lt;code&gt;.env&lt;/code&gt; is &lt;strong&gt;not modified yet&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Apply the configuration (with automatic backup):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan config-manager:export &amp;lt;project-id&amp;gt; &amp;lt;environment-id&amp;gt; &lt;span class="nt"&gt;--apply&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will:&lt;/p&gt;

&lt;p&gt;✔ back up your current &lt;code&gt;.env&lt;/code&gt; into &lt;code&gt;.env.backups/&lt;/code&gt;&lt;br&gt;&lt;br&gt;
✔ replace it with the generated one  &lt;/p&gt;

&lt;p&gt;Rollback to the previous &lt;code&gt;.env&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan config-manager:export &lt;span class="nt"&gt;--rollback&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instant restore — no drama 🙂&lt;/p&gt;

&lt;p&gt;If the environment is marked as &lt;strong&gt;production&lt;/strong&gt;, the tool also shows a clear confirmation prompt before doing anything — so you don’t accidentally overwrite live configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 If you want to check it out
&lt;/h2&gt;

&lt;p&gt;GitHub:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/Vanni7544/config-manager" rel="noopener noreferrer"&gt;https://github.com/Vanni7544/config-manager&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Gumroad (commercial ready-to-install package):&lt;br&gt;&lt;br&gt;
&lt;a href="https://daghini.gumroad.com/l/ifyzw" rel="noopener noreferrer"&gt;https://daghini.gumroad.com/l/ifyzw&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;It’s &lt;strong&gt;not a SaaS&lt;/strong&gt; — nothing leaves your server.&lt;br&gt;&lt;br&gt;
Everything runs locally inside your Laravel project.  &lt;/p&gt;

&lt;h2&gt;
  
  
  💬 Feedback welcome
&lt;/h2&gt;

&lt;p&gt;If you try it and have feedback, criticism, improvement ideas, or thoughts about safer ways to manage &lt;code&gt;.env&lt;/code&gt;, I’d honestly love to hear them.&lt;/p&gt;

&lt;p&gt;And if you’re curious — AMA-style — about:&lt;/p&gt;

&lt;p&gt;• why I built it&lt;br&gt;&lt;br&gt;
• how it works internally&lt;br&gt;&lt;br&gt;
• what real-world problems it solved&lt;br&gt;&lt;br&gt;
• what I’d like to improve next  &lt;/p&gt;

&lt;p&gt;I’m happy to chat 🙂&lt;/p&gt;

&lt;p&gt;This isn’t meant as a promotional post — more a way to share something I built and hopefully learn from the community as well.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

&lt;p&gt;❤️ PS&lt;/p&gt;

&lt;p&gt;If English isn’t perfect everywhere, forgive me — I’m Italian 🇮🇹 and doing my best 😄 Happy to clarify anything!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>laravel</category>
      <category>php</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
