<?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: Sergej Willmann</title>
    <description>The latest articles on DEV Community by Sergej Willmann (@retlim).</description>
    <link>https://dev.to/retlim</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%2F1154897%2F636c1b31-06d3-4f47-975f-f3dc525ab7a4.png</url>
      <title>DEV Community: Sergej Willmann</title>
      <link>https://dev.to/retlim</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/retlim"/>
    <language>en</language>
    <item>
      <title>Fusion: Everything Is a Modular Package</title>
      <dc:creator>Sergej Willmann</dc:creator>
      <pubDate>Sun, 19 Apr 2026 13:01:44 +0000</pubDate>
      <link>https://dev.to/retlim/fusion-everything-is-a-modular-package-5ggc</link>
      <guid>https://dev.to/retlim/fusion-everything-is-a-modular-package-5ggc</guid>
      <description>&lt;p&gt;What if there were no traditional static root projects and package types, allowing a package manager to build the root project along with its dependencies? To see how this generic approach benefits PHP projects and which problems it solves, let's look at the core implementation of Fusion's modularity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Projects are modular packages.&lt;/li&gt;
&lt;li&gt;Packages can depend on each other and even themselves.&lt;/li&gt;
&lt;li&gt;Packages are built the same way and share a unified state with per-package stateful files.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Recursive Dependency Graph
&lt;/h2&gt;

&lt;p&gt;The ability for a package to depend on itself makes standalone packages manageable and removes the need for static initial distributions. Instead, root and nested packages are built within a single dependency graph:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqov7wiacmyk0ser4rwf.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%2Fkqov7wiacmyk0ser4rwf.png" alt="Pseudograph with nodes A and B. Node A is the root and references &amp;lt;br&amp;gt;
itself and B." width="323" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since Fusion itself is also a package, it works well as a real-world example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A: &lt;a href="https://valvoid.com/registry/packages/1/fusion-php-package-manager" rel="noopener noreferrer"&gt;Fusion - Package Manager&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;B: &lt;a href="https://valvoid.com/registry/packages/104/box-php-dependency-injection-container" rel="noopener noreferrer"&gt;Box - DI Container&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In its own metadata, the package manager depends on a dependency injection container for abstraction, and for user-friendly non-breaking updates (2.x.x), it also depends on itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"structure"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"valvoid.com/valvoid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fusion/2.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"/dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"valvoid.com/valvoid/box/2.0.0"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because these dependencies are defined in the metadata, the maintenance command remains user-friendly without arguments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fusion build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For major upgrades, for example for future release &lt;code&gt;3.0.0&lt;/code&gt;, an explicit reference argument must be passed to override the fallback reference defined in the metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fusion build build.source=valvoid.com/valvoid/fusion/3.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Regardless of how the reference is passed, Fusion connects different versions of the same root package into a recursive graph. The higher version can either trigger a custom migration script or rely on Fusion's default behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Dependency Graph
&lt;/h2&gt;

&lt;p&gt;Without static root projects, graphs can expand upward. The flexible entry point, which shifts with each new reference, lets standalone packages become default dependencies that parent packages can consume and extend:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flrqfe6mwgbjq52s7yep2.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%2Flrqfe6mwgbjq52s7yep2.png" alt="Graph with nodes A, B, C, and a dashed node indicating a possible next root. A references B, B references C, and the dashed node references the current root." width="322" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For example, Fusion itself is such a default package:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A: Customization&lt;/li&gt;
&lt;li&gt;B: &lt;a href="https://valvoid.com/registry/packages/1/fusion-php-package-manager" rel="noopener noreferrer"&gt;Fusion - Package Manager&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;C: &lt;a href="https://valvoid.com/registry/packages/104/box-php-dependency-injection-container" rel="noopener noreferrer"&gt;Box - DI Container&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Determining which parent packages customize a default package, and in what order they are applied, is not trivial. For this reason, Fusion provides built-in extension logic at the metadata layer, which it also uses itself. The package manager exposes the virtual config path in production metadata via the &lt;code&gt;extendable&lt;/code&gt; indicator and expects the generated extender data to be in the &lt;code&gt;stateful&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"structure"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"/config"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"extendable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"/state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stateful"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A custom package manager, as an extender package on top, declares Fusion as a dependency in its production metadata and maps its own configuration directory into the exposed virtual path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"structure"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"/config"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;":valvoid/fusion/config"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"/dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"valvoid.com/valvoid/fusion/2.0.0"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the relation is abstract, the extender does not pass anything directly to Fusion's configuration. Instead, it contributes to the shared state generated during the build process, constrained only by the config schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fusion build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once completed, Fusion, like any other default package, reads the ordered extender directories from the generated &lt;code&gt;extensions.php&lt;/code&gt; file in its own &lt;code&gt;stateful&lt;/code&gt; directory:&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;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;

    &lt;span class="c1"&gt;// exposed virtual path&lt;/span&gt;
    &lt;span class="s2"&gt;"/config"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;

        &lt;span class="c1"&gt;// mapped extender directories&lt;/span&gt;
        &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;absolute extender root dir&amp;gt;/config"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="c1"&gt;#3 =&amp;gt; "&amp;lt;other extender&amp;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;During subsequent executions, the package manager applies all mapped configs in deterministic top-down order without exposing merge logic to extenders, minimizing overhead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Circular Dependency Graph
&lt;/h2&gt;

&lt;p&gt;Due to unrestricted references, packages can depend on each other, resulting in a graph relative to its entry point. This allows the graph to be reused across different builds by constructing it from different nodes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxojd3kd4xeygas39la0.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%2Fhxojd3kd4xeygas39la0.png" alt="Circular dependency graph with nodes A and B referencing each other." width="322" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reflex and Box are example packages that share such a graph:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A: &lt;a href="https://valvoid.com/registry/packages/110/reflex-php-testing-framework" rel="noopener noreferrer"&gt;Reflex - Testing Framework&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;B: &lt;a href="https://valvoid.com/registry/packages/104/box-php-dependency-injection-container" rel="noopener noreferrer"&gt;Box - DI Container&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Testing upcoming releases before your own release, such as breaking changes in the &lt;code&gt;2.0.0&lt;/code&gt; dependency injection container used by Reflex for abstraction, is the most interesting part of such relationships. The default Valvoid &lt;a href="https://valvoid.com/registry" rel="noopener noreferrer"&gt;registry&lt;/a&gt;&lt;br&gt;
is production-only and limited to its own sources (&lt;code&gt;valvoid.com/&amp;lt;path&amp;gt;/&amp;lt;reference&amp;gt;&lt;/code&gt;), so the Reflex production metadata &lt;code&gt;fusion.json&lt;/code&gt; prepends the &lt;code&gt;2.0.0&lt;/code&gt; reference pattern for upcoming versions using the logical &lt;code&gt;||&lt;/code&gt; operator and applies the changes along with the next bugfix release &lt;code&gt;1.0.1&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"structure"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"/dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"valvoid.com/valvoid/box/2.0.0||1.1.0"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the shared development metadata &lt;code&gt;fusion.dev.php&lt;/code&gt;, Reflex drops the production source by setting it to &lt;code&gt;null&lt;/code&gt; and defines the upcoming version &lt;code&gt;2.0.0&lt;/code&gt; using the GitLab repository branch &lt;code&gt;2.0&lt;/code&gt; as the offset:&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;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"structure"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"/dependencies"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"gitlab.com/valvoid/box/'code/==2.0.0:2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"valvoid.com/valvoid/box"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;null&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;Box, in parallel, increases its version in the production metadata &lt;code&gt;fusion.json&lt;/code&gt; to &lt;code&gt;2.0.0&lt;/code&gt;, and in the shared development metadata &lt;code&gt;fusion.dev.php&lt;/code&gt; it also changes the source to the GitLab repository branch &lt;code&gt;1.0&lt;/code&gt; as the offset:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"structure"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s2"&gt;"/dependencies"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s2"&gt;"gitlab.com/valvoid/reflex/'code/==1.0.1:1.0"&lt;/span&gt;

            &lt;span class="c1"&gt;// previous production source&lt;/span&gt;
            &lt;span class="c1"&gt;// "valvoid.com/valvoid/reflex/1.0.0"&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;Using separated metadata files, both packages build each other for testing inside the pipeline with upcoming versions by running the build command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fusion build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;These are the use cases I have found in my projects and implemented in Fusion. There will likely be more as it is used in additional projects and different setups. If you like the approach without traditional static root projects and package types, you can try Fusion in your next project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://valvoid.com/registry/packages/1/fusion-php-package-manager" rel="noopener noreferrer"&gt;Package&lt;/a&gt;: Default Valvoid registry&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gitlab.com/valvoid/fusion/code" rel="noopener noreferrer"&gt;Project&lt;/a&gt;: GitLab repo&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Introducing Fusion – A PHP Package Manager</title>
      <dc:creator>Sergej Willmann</dc:creator>
      <pubDate>Mon, 12 May 2025 13:04:02 +0000</pubDate>
      <link>https://dev.to/retlim/introducing-fusion-a-php-package-manager-3cj2</link>
      <guid>https://dev.to/retlim/introducing-fusion-a-php-package-manager-3cj2</guid>
      <description>&lt;p&gt;Fusion is a PHP package manager that manages dependencies, loadable source code, extensions, and state of PHP projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Everything Is a Modular Package
&lt;/h2&gt;

&lt;p&gt;The root project, its dependencies, and even Fusion itself are modular packages that can be used as standalone software, as dependencies in other projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scoped Metadata and Snapshot Files
&lt;/h2&gt;

&lt;p&gt;A package can be defined using three individual &lt;a href="https://valvoid.com/registry/packages/1/fusion-php-package-manager/docs/package/schema/files" rel="noopener noreferrer"&gt;metadata files&lt;/a&gt;, each serving a different use case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optional local development metadata specific to your personal machine.&lt;/li&gt;
&lt;li&gt;Optional shared development metadata used across all machines in the project.&lt;/li&gt;
&lt;li&gt;Production metadata used for releases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These files intersect in a top-down order, where local metadata overrides shared metadata, and shared metadata overrides production metadata. Fusion also generates a snapshot file for each metadata file, capturing replicable versions of its dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lifecycle Hooks
&lt;/h2&gt;

&lt;p&gt;Packages can define custom scripts in their metadata that run after recycling, downloading, installing, or updating, and before migrating or deleting the package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loadable Code
&lt;/h2&gt;

&lt;p&gt;All object-oriented and procedural code is automatically indexed into granular files for custom loading. The same files also form the basis of a pre-built autoloader, providing default out-of-the-box loading.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flexible Package References
&lt;/h2&gt;

&lt;p&gt;Fusion offers full support for &lt;a href="https://semver.org" rel="noopener noreferrer"&gt;semantic versioning&lt;/a&gt;, as well as commit, branch, and tag offsets, which can be extended by intuitive, well-known logic for &lt;a href="https://valvoid.com/registry/packages/1/fusion-php-package-manager/docs/package/schema/structure#trailing-reference-segment" rel="noopener noreferrer"&gt;complex references&lt;/a&gt;, similar to the syntax used in code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logical &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; and &lt;code&gt;||&lt;/code&gt; operators.&lt;/li&gt;
&lt;li&gt;Comparison signs &lt;code&gt;!=&lt;/code&gt;, &lt;code&gt;==&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Grouping brackets &lt;code&gt;()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resolution process uses a conflict-driven clause learning (CDCL) algorithm to ensure efficient decision-making.&lt;/p&gt;

&lt;h2&gt;
  
  
  Directory Type Indicators
&lt;/h2&gt;

&lt;p&gt;Fusion builds new versions efficiently by recycling existing packages. To instruct the package manager that your package includes a mutable directory built by a callback and should be handled individually as new content, set the &lt;a href="https://valvoid.com/registry/packages/1/fusion-php-package-manager/docs/package/schema/structure#mutable-directory-indicator" rel="noopener noreferrer"&gt;mutable&lt;/a&gt; indicator in your metadata.&lt;/p&gt;

&lt;p&gt;To allow other packages to extend yours at a special directory using the default built-in, out-of-the-box behavior, set the &lt;a href="https://valvoid.com/registry/packages/1/fusion-php-package-manager/docs/package/schema/structure#extendable-directory-indicator" rel="noopener noreferrer"&gt;extendable&lt;/a&gt; indicator in your metadata. Fusion will also generate an extensions file for your package, containing the parent package dirs and the order in which they extend it, in case your package needs to know this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interface-Based Customization
&lt;/h2&gt;

&lt;p&gt;As mentioned above, Fusion is itself a &lt;a href="https://valvoid.com/registry/packages/1/fusion-php-package-manager" rel="noopener noreferrer"&gt;package&lt;/a&gt;, and its architecture supports out-of-the-box customization through built-in directory indicators. You can build your &lt;a href="https://valvoid.com/registry/packages/1/fusion-php-package-manager/docs/extensions/package" rel="noopener noreferrer"&gt;own package manager&lt;/a&gt; on top by extending it with custom implementations, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding a custom package registry.&lt;/li&gt;
&lt;li&gt;Replacing the download, build, or replication logic.&lt;/li&gt;
&lt;li&gt;Setting a custom log serializer.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;For the source code, issues, or contribution, see the &lt;a href="https://gitlab.com/valvoid/fusion/code" rel="noopener noreferrer"&gt;GitLab repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>php</category>
      <category>opensource</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
