Skip to content

Conversation

MarcoPolo
Copy link
Collaborator

@MarcoPolo MarcoPolo commented Sep 19, 2025

This commit introduces a new builder concept to allow users more control in building a go-libp2p node. The builder package itself serves as an example of how to configure and connect all the go-libp2p parts into a host. However, there is nothing special about the builder package, and advanced users will make their own builder Config. It’s built around a small and simple DI library I wrote. The DI library has no dependencies, and could be implemented from scratch in a couple of hours. Refer to the godoc at https://pkg.go.dev/git.sr.ht/~marcopolo/di for more details.

In the future, we may split the builder package further to allow reuse of common components without depending on every component. For example, we may move the swarm+host constructor logic into a separate package from the transport constructor logic. That way a user could reuse the swarm+host constructors without depending on the transport constructors.

Today, users can still minimize their dependencies by creating their own Builder config. They may use the existing one as a template and prune the things they don’t need.

I’d like to get feedback from users on this feature before investing more time into it.

History

package builder was born out of frustration with Fx and the convoluted nature of building a Go libp2p host. Especially when one wants to step away from the default path.

Issues with the correct libp2p.New constructor and Fx:

  • It’s a bad combination of Options functions with a Config struct and Fx options.
  • The reason for that is that Fx, doesn’t provide a good way to have a default value for some setting. For example, there’s no way to provide a default resource manager that gets overwritten if a user provides their own resource manager. There are plenty of hacks to workaround this, but they inevitably introduce strange new concepts to the user (e.g. abusing Fx labels, groups, or weird constructors.)
  • It’s hard to pull out one part if you only need that part. For example, if you want the logic around AutoNAT without pulling in any dependency on WebRTC, it’s currently hard.
  • Fx Options type erase the thing they provide. Take Config.QUICReuse as an example. The type of that field is []fx.Option. Literally any fx option can go in there.
  • Fx is a fairly large dependency.

The builder package takes a different approach focuses on the following goals:

  • Ergonomic defaults.
  • Clear layout of required objects.
  • Let users to select only the services and components they need.
  • Let users get references to instantiated services. Don’t hide everything in the basic host.

For reviewers

Commits are meaningful, so it may be helpful to review this commit by commit.

closes #3294 and probably #3251 as well.

@MarcoPolo
Copy link
Collaborator Author

tagging @marten-seemann, as he was curious about these changes

# Overview

This commit introduces a new builder concept to allow users more control in
building a go-libp2p node. The builder package itself serves as an example of
how to configure and connect all the go-libp2p parts into a host. However, there
is nothing special about the builder package, and advanced users will make their
own builder Config. It's build around a small and simple DI library I wrote. The
DI library has no dependencies, and could be implemented from scratch in a
couple of hours. Refer to the godoc at
https://pkg.go.dev/git.sr.ht/~marcopolo/di for more details.

In the future, we may split the builder package further to allow reuse of common
components without depending on every component. For example, we may move the
swarm+host constructor logic into a separate package from the transport
constructor logic. That way a user could reuse the swarm+host constructors
without depending on the transport constructors.

Today, users can still minimize their dependencies by creating their own Builder
config. They may use the existing one as a template and prune the things they
don't need.

I'd like to get feedback from users on this feature before investing more time
into it.

# History

package builder was born out of frustration with Fx and the convoluted nature of
building a Go libp2p host. Especially when one wants to step away from the
default path.

Issues with the correct libp2p.New constructor and Fx:

- It's a bad combination of Options functions with a Config struct and Fx
  options.
- The reason for that is that Fx, doesn't provide a good way to have a default
  value for some setting. For example, there's no way to provide a default
  resource manager that gets overwritten if a user provides their own resource
  manager. There are plenty of hacks to workaround this, but they inevitably
  introduce strange new concepts to the user (e.g. abusing Fx labels, groups, or
  weird constructors.)
- It's hard to pull out one part if you only need that part. For example, if you
  want the logic around AutoNAT without pulling in any dependency on WebRTC,
  it's currently hard.
- Fx Options type erase the thing they provide. Take `Config.QUICReuse` as an
  example. The type of that field is `[]fx.Option`. Literally any fx option can
  go in there.
- Fx is a fairly large dependency.

The builder package takes a different approach focuses on the following goals:

- Ergonomic defaults.
- Clear layout of required objects.
- Let users to select only the services and components they need.
- Let users get references to instantiated services. Don't hide everything in
  the basic host.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Modular go-libp2p
1 participant