All Versions
Latest Version
Avg Release Cycle
36 days
Latest Release

Changelog History
Page 1

  • v1.0.0 Changes

    • πŸ”¨ go-libp2p 0.19 removed support for undocumented ls command (PR). If you are still using it for internal testing, it is time to refactor (example)
  • v0.13.0 Changes

    May 04, 2022

    We're happy to announce go-ipfs 0.13.0, packed full of changes and improvements!

    As usual, this release includes important fixes, some of which may be critical for security. Unless the fix addresses a bug being exploited in the wild, the fix will not be called out in the release notes. Please make sure to update ASAP. See our release process for details.


    πŸš€ Below is an outline of all that is in this release, so you get a sense of all that's included.

    • [πŸ›  BREAKING CHANGES](#---breaking-changes)
      • [ipfs block put command](#-ipfs-block-put--command)
      • [ipfs cid codecs command](#-ipfs-cid-codecs--command)
      • [Swarm configuration](#-swarm--configuration)
      • Circuit Relay V1 is deprecated
      • [ls requests for /multistream/1.0.0 are removed](#-ls--requests-for---multistream-100--are-removed)
      • Gateway Items
    • [πŸ”¦ Highlights](#---highlights)
      • [πŸ§‘β€πŸ’Ό libp2p Network Resource Manager (Swarm.ResourceMgr)](#------libp2p-network-resource-manager---swarmresourcemgr--)
      • [πŸ”ƒ Relay V2 client with auto discovery (Swarm.RelayClient)](#---relay-v2-client-with-auto-discovery---swarmrelayclient--)
      • [πŸŒ‰ HTTP Gateway improvements](#---http-gateway-improvements)
      • [🍱 Support for Block and CAR response formats](#---support-for-block-and-car-response-formats)
      • [🐎 Fast listing generation for huge directories](#---fast-listing-generation-for-huge--directories)
      • [🎫 Improved Etag and If-None-Match for bandwidth savings](#---improved--etag--and--if-none-match--for-bandwidth-savings)
      • [⛓️ Added X-Ipfs-Roots for smarter HTTP caches](#---added-x-ipfs-roots-for-smarter-http-caches)
      • [🌑️ Added metrics per response type](#----added-metrics-per-response-type)
      • [πŸ•΅οΈ OpenTelemetry tracing](#----opentelemetry-tracing)
      • How to use Jaeger UI for visual tracing?
      • [🩺 Built-in ipfs diag profile to ease debugging](#---built-in--ipfs-diag-profile--to-ease-debugging)
      • [πŸ”‘ Support for PEM/PKCS8 for key import/export](#---support-for-pem-pkcs8-for-key-import-export)
      • [🧹 Using standard IPLD codec names across the CLI/HTTP API](#---using-standard-ipld-codec-names-across-the-cli-http-api)
      • [🐳 Custom initialization for Docker](#---custom-initialization-for-docker)
      • RPC API docs for experimental and deprecated commands
      • Yamux over Mplex


    ipfs block put command

    0️⃣ ipfs block put command returns a CIDv1 with raw codec by default now.

    • ipfs block put --cid-codec makes block put return CID with alternative codec
      • This impacts only the returned CID; it does not trigger any validation or data transformation.
      • Retrieving a block with a different codec or CID version than it was put with is valid.
      • Codec names are validated against tables from go-multicodec library.
    • πŸš€ ipfs block put --format is deprecated. It used incorrect codec names and should be avoided for new deployments. Use it only if you need the old, invalid behavior, namely:
      • ipfs block put --format=v0 will produce CIDv0 (implicit dag-pb)
      • ipfs block put --format=cbor will produce CIDv1 with dag-cbor (!)
      • ipfs block put --format=protobuf will produce CIDv1 with dag-pb (!)

    ipfs cid codecs command

    • Now lists codecs from go-multicodec library.
    • πŸ‘ ipfs cid codecs --supported can be passed to only show codecs supported in various go-ipfs commands.

    ipfs cid format command

    • 🚚 --codec was removed and replaced with --mc to ensure existing users are aware of the following changes:
      • --mc protobuf now correctly points to code 0x50 (was 0x70, which is dab-pg)
      • --mc cbor now correctly points to code 0x51 (was 0x71, which is dag-cbor)

    πŸ”§ Swarm configuration

    • πŸ—„ Daemon will refuse to start if long-deprecated RelayV1 config key Swarm.EnableAutoRelay or Swarm.DisableRelay is set to true.
    • If Swarm.Transports.Network.Relay is disabled, then Swarm.RelayService and Swarm.RelayClient are also disabled (unless they have been explicitly enabled).

    πŸ—„ Circuit Relay V1 is deprecated

    • 0️⃣ By default, Swarm.RelayClient does not use Circuit Relay V1. Circuit V1 support is only enabled when Swarm.RelayClient.StaticRelays are specified.
  • v0.12.2 Changes

    April 08, 2022

    πŸš€ This patch release fixes a security issue wherein traversing some malformed DAGs can cause the node to panic.

    πŸ”’ See also the security advisory:

    πŸš€ Note: the v0.11.1 patch release contains the Docker compose fix from v0.12.1 as well

    πŸ”„ Changelog

    Full Changelog

    • (v1.3.0 -> v1.3.2):
      • fix: use protowire for Links bytes decoding

    ❀ Contributors

    Contributor Commits Lines Β± Files Changed
    Rod Vagg 1 +34/-19 2
  • v0.12.1 Changes

    March 17, 2022

    πŸš€ This patch release fixes a security issue with the docker-compose.yaml file in which the IPFS daemon API listens on all interfaces instead of only the loopback interface, which could allow remote callers to control your IPFS daemon. If you use the included docker-compose.yaml file, it is recommended to upgrade.

    πŸ”’ See also the security advisory:

    Thanks to @LynHyper for finding and disclosing this.

    πŸ”„ Changelog

    Full Changelog

      • fix: listen on loopback for API and gateway ports in docker-compose.yaml

    ❀ Contributors

    Contributor Commits Lines Β± Files Changed
    guseggert 1 +10/-3 1
  • v0.12.0 Changes

    February 17, 2022

    πŸš€ We're happy to announce go-ipfs 0.12.0. This release switches the storage of IPLD blocks to be keyed by multihash instead of CID.

    As usual, this release includes important fixes, some of which may be critical for security. Unless the fix addresses a bug being exploited in the wild, the fix will not be called out in the release notes. Please make sure to update ASAP. See our release process for details.


    • ipfs refs local will now list all blocks as if they were raw CIDv1 instead of with whatever CID version and IPLD codecs they were stored with. All other functionality should remain the same.

    ⚑️ Note: This change also effects ipfs-update so if you use that tool to mange your go-ipfs installation then grab ipfs-update v1.8.0 from dist.

    Keep reading to learn more details.

    πŸ”¦ Highlights

    There is only one change since 0.11:

    Blockstore migration from full CID to Multihash keys

    0️⃣ We are switching the default low level datastore to be keyed only by the Multihash part of the CID, and deduplicate some blocks in the process. The blockstore will become codec-agnostic.


    πŸ›  The blockstore/datastore layers are not concerned with data interpretation, only with storage of binary blocks and verification that the Multihash they are addressed with (which comes from the CID), matches the block. In fact, different CIDs, with different codecs prefixes, may be carrying the same multihash, and referencing the same block. Carrying the CID abstraction so low on the stack means potentially fetching and storing the same blocks multiple times just because they are referenced by different CIDs. Prior to this change, a CIDv1 with a dag-cbor codec and a CIDv1 with a raw codec, both containing the same multihash, would result in two identical blocks stored. A CIDv0 and CIDv1 both being the same dag-pb block would also result in two copies.

    How migration works

    ⚑️ In order to perform the switch, and start referencing all blocks by their multihash, a migration will occur on update. This migration will take the repository version from 11 (current) to 12.

    0️⃣ One thing to note is that any content addressed CIDv0 (all the hashes that start with Qm..., the current default in go-ipfs), does not need any migration, as CIDv0 are raw multihashes already. This means the migration will be very lightweight for the majority of users.

    The migration process will take care of re-keying any CIDv1 block so that it is only addressed by its multihash. Large nodes with lots of CIDv1-addressed content will need to go through a heavier process as the migration happens. This is how the migration works:

    πŸ”§ 1. Phase 1: The migration script will perform a pass for every block in the datastore and will add all CIDv1s found to a file named 11-to-12-cids.txt, in the go-ipfs configuration folder. Nothing is written in this first phase and it only serves to identify keys that will be migrated in phase 2. πŸ”§ 2. Phase 2: The migration script will perform a second pass where every CIDv1 block will be read and re-written with its raw-multihash as key. There is 1 worker performing this task, although more can be configured. Every 100MiB-worth of blocks (this is configurable), each worker will trigger a datastore "sync" (to ensure all written data is flushed to disk) and delete the CIDv1-addressed blocks that were just renamed. This provides a good compromise between speed and resources needed to run the migration.

    πŸ”€ At every sync, the migration emits a log message showing how many blocks need to be rewritten and how far the process is.

    # FlatFS specific migration

    🐎 For those using a single FlatFS datastore as their backing blockstore (i.e. the default behavior), the migration (but not reversion) will take advantage of the ability to easily move/rename the blocks to improve migration performance.

    πŸ‘ Unfortunately, other common datastores do not support renames which is what makes this FlatFS specific. If you are running a large custom datastore that supports renames you may want to consider running a fork of fs-repo-11-to-12 specific to your datastore.

    If you want to disable this behavior, set the environment variable IPFS_FS_MIGRATION_11_TO_12_ENABLE_FLATFS_FASTPATH to false.

    πŸ”§ ####### Migration configuration

    πŸ”§ For those who want to tune the migration more precisely for their setups, there are two environment variables to configure:

    • IPFS_FS_MIGRATION_11_TO_12_NWORKERS : an integer describing the number of migration workers - defaults to 1
    • IPFS_FS_MIGRATION_11_TO_12_SYNC_SIZE_BYTES : an integer describing the number of bytes after which migration workers will sync - defaults to 104857600 (i.e. 100MiB)
    Migration caveats

    Large repositories with very large numbers of CIDv1s should be mindful of the migration process:

    • πŸ‘€ We recommend ensuring that IPFS runs with an appropriate (high) file-descriptor limit, particularly when Badger is use as datastore backend. Badger is known to open many tables when experiencing a high number of writes, which may trigger "too many files open" type of errors during the migrations. If this happens, the migration can be retried with a higher FD limit (see below).
    • Migrations using the Badger datastore may not immediately reclaim the space freed by the deletion of migrated blocks, thus space requirements may grow considerably. A periodic Badger-GC is run every 2 minutes, which will reclaim space used by deleted and de-duplicated blocks. The last portion of the space will only be reclaimed after go-ipfs starts (the Badger-GC cycle will trigger after 15 minutes).
    • βͺ While there is a revert process detailed below, we recommend keeping a backup of the repository, particularly for very large ones, in case an issue happens, so that the revert can happen immediately and cases of repository corruption due to crashes or unexpected circumstances are not catastrophic.
    Migration interruptions and retries

    If a problem occurs during the migration, it is be possible to simply re-start and retry it:

    πŸ‘€ 1. Phase 1 will never overwrite the 11-to-12-cids.txt file, but only append to it (so that a list of things we were supposed to have migrated during our first attempt is not lost - this is important for reverts, see below).

    1. Phase 2 will proceed to continue re-keying blocks that were not re-keyed during previous attempts.

    βͺ ###### Migration reverts

    πŸš€ It is also possible to revert the migration after it has succeeded, for example to go to a previous go-ipfs version (<=0.11), even after starting and using go-ipfs in the new version (>=0.12). The revert process works as follows:

    1. The 11-to-12-cids.txt file is read, which has the list of all the CIDv1s that had to be rewritten for the migration. πŸ”§ 2. A CIDv1-addressed block is written for every item on the list. This work is performed by 1 worker (configurable), syncing every 100MiB (configurable). πŸ“Œ 3. It is ensured that every CIDv1 pin, and every CIDv1 reference in MFS, are also written as CIDV1-addressed blocks, regardless of whether they were part of the original migration or were added later.

    ⬇️ The revert process does not delete any blocks--it only makes sure that blocks that were accessible with CIDv1s before the migration are again keyed with CIDv1s. This may result in a datastore becoming twice as large (i.e. if all the blocks were CIDv1-addressed before the migration). This is however done this way to cover corner cases: user can add CIDv1s after migration, which may reference blocks that existed as CIDv0 before migration. The revert aims to ensure that no data becomes unavailable on downgrade.

    ⚑️ While go-ipfs will auto-run the migration for you, it will not run the reversion. To do so you can download the latest migration binary or use ipfs-update.

    Custom datastores

    πŸ— As with previous migrations if you work with custom datastores and want to leverage the migration you can run a fork of fs-repo-11-to-12 specific to your datastore. The repo includes instructions on building for different datastores.

    For this migration, if your datastore has fast renames you may want to consider writing some code to leverage the particular efficiencies of your datastore similar to what was done for FlatFS.

    πŸ”„ Changelog

    ❀️ Contributors

    Contributor Commits Lines Β± Files Changed
    Gus Eggert 10 +333/-321 24
    Steven Allen 7 +289/-190 13
    Hector Sanjuan 9 +134/-109 18
    Adin Schmahmann 11 +179/-55 21
    RaΓΊl Kripalani 2 +152/-42 5
    Daniel MartΓ­ 1 +120/-1 1
    frrist 1 +95/-13 2
    Alex Trottier 2 +22/-11 4
    Andrey Petrov 1 +32/-0 1
    Lucas Molas 1 +18/-7 2
    πŸ‘€ Marten Seemann 2 +11/-7
    whyrusleeping 1 +10/-0 1
    web3-bot 3 +9/-0 3
    postables 1 +5/-3 1
    Dr Ian Preston 1 +4/-0 1
  • v0.11.0 Changes

    December 08, 2021

    πŸš€ We're happy to announce go-ipfs 0.11.0. This release comes with improvements to the UnixFS Sharding and PubSub experiments as well as support for Circuit-Relay v2 which sets the network up for decentralized hole punching support.

    As usual, this release includes important fixes, some of which may be critical for security. Unless the fix addresses a bug being exploited in the wild, the fix will not be called out in the release notes. Please make sure to update ASAP. See our release process for details.


    • 0️⃣ UnixFS sharding is now automatic and enabled by default
      • HAMT-based sharding is applied to large directories (i.e. those that would serialize into block larger than ~256KiB)s. This means importing data via commands like ipfs add -r <directory> may result in different CIDs due to the different DAG representations.
      • Support for Experimental.ShardingEnabled is removed.
    • πŸ“„ go-ipfs can no longer act as a Circuit Relay v1
      • Node will refuse to start if Swarm.EnableRelayHop is set to true
      • If you depend on v1 relay service provider, see "Removal of v1 relay service" section for available migration options.
    • HTTP RPC wire format for experimental commands at /api/v0/pubsub changed.

    Keep reading to learn more details.

    πŸ”¦ Highlights

    πŸ—ƒ Automatic UnixFS sharding

    πŸ“„ Truly big directories can have so many items, that the root block with all of their names is too big to be exchanged with other peers. This was partially solved by HAMT-sharding, which was introduced a while ago as opt-in. The main downside of the implementation was that it was a global flag that sharded all imported directories (big and small).

    πŸš€ This release solves that inconvenience by making UnixFS sharding smarter and applies it only to larger directories (i.e. directories that would be at least ~256KiB). This is now the default behavior in ipfs add and ipfs files commands, where UnixFS sharding works out-of-the-box.

    πŸ” Circuit Relay v2

    πŸš€ This release adds support for the circuit relay v2 protocol based on the reference implementation from go-libp2p 0.16.

    🚦 This is the cornerstone for maximizing p2p connections between IPFS peers. Every publicly dialable peer can now act as a limited relay v2, which can be used for hole punching and other decentralized signaling protocols.

    πŸ”§ Limited relay v2 configuration options

    πŸ”§ go-ipfs can now be configured to act as a RelayClient that uses other peers for autorelay functionality when behind a NAT, or provide a limited RelayService to other peers on the network.

    ⚑️ Starting with go-ipfs v0.11 every publicly dialable go-ipfs (based on AutoNAT determination) will start a limited RelayService. RelayClient remains disabled by default for now, as we want the network to update and get enough v2 service providers first.

    πŸš€ Note: the limited Circuit Relay v2 provided with this release only allows low-bandwidth protocols (identify, ping, holepunch) over transient connections. If you want to relay things like bitswap sessions, you need to set up a v1 relay by some other means. See details below.

    Removal of unlimited v1 relay service provider

    πŸ”§ Switching to v2 of the relay spec means removal or deprecation of configuration keys that were specific to v1.

    • πŸ‘ Relay transport and client support circuit-relay v2:
      • Swarm.EnableAutoRelay was replaced by Swarm.RelayClient.Enabled.
      • Swarm.DisableRelay is deprecated, relay transport can be now disabled globally (both client and service) by setting Swarm.Transports.Network.Relay to false
    • Relay v1 service provider was replaced by v2:
      • Swarm.EnableRelayHop no longer starts an unlimited v1 relay. If you have it set to true the node will refuse to start and display an error message.
      • Existing users who choose to continue running a v1 relay should migrate their setups to relay v1 based on js-ipfs running in node, or the standalone libp2p-relay-daemon configured with RelayV1.Enabled set to true. Be mindful that v1 relays are unlimited, and one may want to set up some ACL based either on PeerIDs or Subnets.

    πŸ•³ Decentralized Hole Punching (DCUtR protocol client)

    We are working towards enabling hole punching for NAT traversal when port forwarding is not possible.

    πŸš€ go-libp2p 0.16 provides an implementation of the DCUtR (decentralized hole punching) protocol. It is hidden behind the Swarm.EnableHolePunching configuration flag.

    ⬆️ When enabled, go-ipfs will coordinate with the counterparty using a relayed v2 connection, to upgrade to a direct connection through a NAT/firewall whenever possible.

    πŸš€ This feature is disabled by default in this release, but we hope to enable it by default as soon the network updates to go-ipfs v0.11 and gains a healthy set of limited v2 relays.

    πŸ’¬ Multibase in PubSub HTTP RPC API

    πŸš€ This release fixed some edge cases that were reported by users of the PubSub experiment, getting it closer to becoming a stable feature of go-ipfs. Some PubSub users will notice that the plaintext limitation is lifted: one can now use line breaks in messages published to non-ascii topic names, or even publish arbitrary bytes to arbitrary topics. It required a change to the wire format used when pubsub commands are executed over the HTTP RPC API at /api/v0/pubsub/*, and also modified the behavior of the ipfs pubsub pub command, which now is publishing only a single pubsub message with data read from a file or stdin.

    PubSub client migration tips

    ⚑️ If you use the HTTP RPC API with the go-ipfs-http-client library, make sure to update to the latest version. The next version of js-ipfs-http-client will use the new wire format as well, so you don't need to do anything.

    πŸ“„ If you use /api/v0/pubsub/* directly or maintain your own client library, you must adjust your HTTP client code. Byte fields and URL args are now encoded in base64url Multibase. Encode/decode bytes using the ipfs multibase --help commands, or use the multiformats libraries (js-multiformats, go-multibase).

    Low level changes:

    • topic passed as URL arg in requests to /api/v0/pubsub/* must be encoded in URL-safe multibase (base64url)
    • data, from, seqno and topicIDs returned in JSON responses are now encoded in multibase
    • 0️⃣ Peer IDs returned in from now use the same default text representation from go-libp2p and peerid encoder/decoder from libp2p. This means the same text representation as in as in swarm peers, which makes it possible to compare them without decoding multibase.
    • 🚚 /api/v0/pubsub/pub no longer accepts data to be passed as URL, it has to be sent as multipart/form-data. This removes size limitations based on URL length, and enables regular HTTP clients to publish data to PubSub topics. For example, to publish some-file to topic named test-topic using vanilla curl, one would execute: curl -X POST -v -F "[email protected]" '$(echo -n test-topic | ipfs multibase encode -b base64url)'
    • πŸ’» ipfs pubsub pub on the command line no longer accepts variadic data arguments. Instead, it expects a single file input or stream of bytes from stdin. This ensures arbitrary stream of bytes can be published, removing limitation around messages that include \n or \r\n.

    πŸ”§ βš™ New configuration flags

    • πŸ“„ Addresses.AppendAnnounce is an array of multiaddrs, similar to Addresses.Announce, except it does not override inferred swarm addresses, but appends custom ones to the list.
    • Pubsub experiments can now be enabled via config, removing the need for CLI flag to be passed every time daemon starts:

    πŸ‘ πŸ” Support for DAG-JOSE IPLD codec

    JOSE is a standard for signing and encrypting JSON objects. DAG-JOSE is an IPLD codec based on JOSE and represented in CBOR. Upon encountering the dag-jose multicodec indicator, implementations can expect that the block contains dag-cbor encoded data which matches the IPLD schema from the DAG-JOSE spec.

    This work was contributed by Ceramic and acts as a template for future IPFS improvements driven by the real world needs of the IPFS community.

    πŸ”„ Changelog

    ❀️ Contributors

    Contributor Commits Lines Β± Files Changed
    Will 13 +73226/-130481 43
    Masih H. Derkani 99 +10549/-5799 489
    hannahhoward 43 +5515/-3293 233
    Daniel MartΓ­ 60 +5312/-2883 208
    πŸ‘€ Marten Seemann 175 +4839/-3254
    Eric Myhre 73 +3924/-3328 175
    Jessica Schilling 52 +2709/-2386 75
    Rod Vagg 30 +2719/-1703 79
    vyzo 10 +3516/-177 87
    Gus Eggert 64 +1677/-1416 147
    Adin Schmahmann 23 +1708/-381 95
    Lucas Molas 14 +1557/-365 48
    Will Scott 7 +1846/-15 34
    Steven Allen 32 +537/-897 56
    Cory Schwartz 3 +614/-109 12
    rht 3 +576/-4 7
    Simon Zhu 9 +352/-51 16
    Petar Maymounkov 7 +173/-167 23
    RubenKelevra 1 +107/-188 1
    jwh 2 +212/-80 7
    longfeiW 1 +4/-249 10
    guseggert 5 +230/-21 11
    Kevin Neaton 8 +137/-80 13
    Takashi Matsuda 1 +199/-0 5
    Andrey Kostakov 1 +107/-49 2
    Jesse Bouwman 1 +151/-0 7
    web3-bot 39 +136/-3 52
    Marcin Rataj 16 +62/-57 25
    Marco Munizaga 1 +118/-0 2
    Aaron Riekenberg 4 +64/-52 6
    Ian Davis 4 +81/-32 7
    Jorropo 2 +79/-19 6
    Mohsin Zaidi 1 +89/-1 20
    Andey Robins 1 +70/-3 3
    gammazero 3 +40/-25 4
    Steve Loeppky 2 +26/-27 3
    Dimitris Apostolou 1 +25/-25 15
    Sudarshan Reddy 1 +9/-40 1
    Richard Littauer 2 +42/-1 3
    pymq 1 +32/-8 2
    Dirk McCormick 2 +23/-1 2
    Nicholas Bollweg 1 +21/-0 1
    anorth 1 +14/-6 2
    Jack Loughran 1 +16/-0 2
    whyrusleeping 2 +11/-2 2
    bt90 1 +13/-0 1
    Yi Cao 1 +10/-0 1
    Max 1 +7/-3 1
    Juan Batiz-Benet 2 +8/-2 2
    Keenan Nemetz 1 +8/-0 1
    muXxer 1 +3/-3 1
    galargh 2 +3/-3 3
    Didrik NordstrΓΆm 1 +2/-4 1
    Ben Lubar 1 +3/-3 1
    arjunraghurama 1 +5/-0 1
    Whyrusleeping 1 +3/-2 1
    TUSF 1 +3/-2 3
    mathew-cf 1 +3/-1 2
    Stephen Whitmore 1 +2/-2 1
    Song Zhu 1 +2/-2 1
    Michael MurΓ© 1 +4/-0 1
    Alex Good 1 +4/-0 2
    aarshkshah1992 1 +2/-1 1
    susarlanikhilesh 1 +1/-1 1
    falstack 1 +1/-1 1
    Michael Vorburger ⛑️ 1 +1/-1 1
    Ismail Khoffi 1 +1/-1 1
    George Xie 1 +1/-1 1
    Bryan Stenson 1 +1/-1 1
    Lars Gierth 1 +1/-0 1
  • v0.10.0 Changes

    September 30, 2021

    πŸš€ We're happy to announce go-ipfs 0.10.0. This release brings some big changes to the IPLD internals of go-ipfs that make working with non-UnixFS DAGs easier than ever. There are also a variety of new commands and configuration options available.

    As usual, this release includes important fixes, some of which may be critical for security. Unless the fix addresses a bug being exploited in the wild, the fix will not be called out in the release notes. Please make sure to update ASAP. See our release process for details.


    • ipfs dag get
      • default output changed to dag-json
      • dag-pb (e.g. unixfs) field names changed - impacts userland code that works with dag-pb objects returned by dag get
      • no longer emits an additional new-line character at the end of the data output
    • ipfs dag put
      • defaults changed to reduce ambiguity and surprises: input is now assumed to be dag-json, and data is serialized to dag-cbor at rest.
      • --format and --input-enc were removed and replaced with --store-codec and --input-codec
      • codec names now match the ones defined in the multicodec table
      • dag-pb (e.g. unixfs) field names changed - impacts userland code that works with dag-pb objects stored via dag put

    Keep reading to learn more details.

    πŸ”¦ Highlights

    🌲 IPLD Levels Up

    The handling of data serialization as well as many aspects of DAG traversal and pathing have been migrated from older libraries, including go-merkledag and go-ipld-format to the new go-ipld-prime library and its components. This allows us to use many of the newer tools afforded by go-ipld-prime, stricter and more uniform codec implementations, support for additional (pluggable) codecs, and some minor performance improvements.

    πŸ’₯ This is significant refactor of a core component that touches many parts of IPFS, and does come with some breaking changes:

    • πŸ”Œ IPLD plugins:
      • The PluginIPLD interface has been changed to utilize go-ipld-prime. There is a demonstration of the change in the [bundled git plugin](./plugin/plugins/git/).
    • The semantics of dag put and dag get change:
      • dag get now takes the output-codec option which accepts a multicodec name used to encode the output. By default this is dag-json, which is a strict and deterministic subset of JSON created by the IPLD team. Users may notice differences from the previously plain Go JSON output, particularly where bytes are concerned which are now encoded using a form similar to CIDs: {"/":{"bytes":"unpadded-base64-bytes"}} rather than the previously Go-specific plain padded base64 string. See the dag-json specification for an explanation of these forms.
      • dag get no longer prints an additional new-line character at the end of the encoded block output. This means that the output as presented by dag get are the exact bytes of the requested node. A round-trip of such bytes back in through dag put using the same codec should result in the same CID.
      • dag put uses the input-codec option to specify the multicodec name of the format data is being provided in, and the store-codec option to specify the multicodec name of the format the data should be stored in at rest. These formerly defaulted to json and cbor respectively. They now default to dag-json and dag-cbor respectively but may be changed to any supported codec (bundled or loaded via plugin) by its multicodec name.
      • The json and cbor multicodec names (as used by input-enc and format options) are now no longer aliases for dag-json and dag-cbor respectively. Instead, they now refer to their proper multicodec types. cbor refers to a plain CBOR format, which will not encode CIDs and does not have strict deterministic encoding rules. json is a plain JSON format, which also won't encode CIDs and will encode bytes in the Go-specific padded base64 string format rather than the dag-json method of byte encoding. See for more information on IPLD codecs.
      • protobuf is no longer used as the codec name for dag-pb
      • The codec name raw is used to mean Bytes in the IPLD Data Model
    • πŸ”¨ UnixFS refactor. The dag-pb codec, which is used to encode UnixFS data for IPFS, is now represented through the dag API in a form that mirrors the protobuf schema used to define the binary format. This unifies the implementations and specification of dag-pb across the IPLD and IPFS stacks. Previously, additional layers of code for file and directory handling within IPFS between protobuf serialization and UnixFS obscured the protobuf representation. Much of this code has now been replaced and there are fewer layers of transformation. This means that interacting with dag-pb data via the dag API will use different forms:
      • Previously, using dag get on a dag-pb block would present the block serialized as JSON as {"data":"padded-base64-bytes","links":[{"Name":"foo","Size":100,"Cid":{"/":"Qm..."}},...]}.
      • Now, the dag-pb data with dag-json codec for output will be serialized using the data model from the dag-pb specification: {"Data":{"/":{"bytes":"unpadded-base64-bytes"}},"Links":[{"Name":"foo","Tsize":100,"Hash":{"/":"Qm..."}},...]}. Aside from the change in byte formatting, most field names have changed: data β†’ Data, links β†’ Links, Size β†’ Tsize, Cid β†’ Hash. Note that this output can be changed now using the output-codec option to specify an alternative codec.
      • Similarly, using dag put and a store-codec option of dag-pb now requires that the input conform to this dag-pb specified form. Previously, input using {"data":"...","links":[...]} was accepted, now it must be {"Data":"...","Links":[...]}.
      • Previously it was not possible to use paths to navigate to any of these properties of a dag-pb node, the only possible paths were named links, e.g. dag get QmFoo/NamedLink where NamedLink was one of the links whose name was NamedLink. This functionality remains the same, but by prefixing the path with /ipld/ we enter data model pathing semantics and can dag get /ipld/QmFoo/Links/0/Hash to navigate to links or /ipld/QmFoo/Data to simply retrieve the data section of the node, for example.
      • β„Ή See the dag-pb specification for details on the codec and its data model representation.
      • β„Ή See this detailed write-up for further background on these changes.

    β“‚ Multibase Command

    πŸ“„ go-ipfs now provides utility commands for working with multibase:

    $ echo -n hello | ipfs multibase encode -b base16 > file-mbase16
    $ cat file-mbase16
    $ ipfs multibase decode file-mbase16
    $ cat file-mbase16 | ipfs multibase decode
    $ ipfs multibase transcode -b base2 file-mbase16

    πŸ‘€ See ipfs multibase --help for more examples.

    πŸ”§ πŸ”¨ Bitswap now supports greater configurability

    πŸ“š This release adds an Internal section to the configuration file that is designed to help advanced users optimize their setups without needing a custom binary. The Internal section is not guaranteed to be the same from release to release and may not be covered by migrations. If you use the Internal section you should be making sure to check the config documentation between releases for any changes.

    🐚 Programmatic shell completions command

    ipfs commands completion bash will generate a bash completion script for go-ipfs commands

    πŸ“œ Profile collection command

    🐎 Performance profiles can now be collected using ipfs diag profile. If you need to do some debugging or have an issue to submit the collected profiles are very useful to have around.

    🍎 Mac OS notarized binaries

    The go-ipfs and related migration binaries (for both Intel and Apple Sillicon) are now signed and notarized to make Mac OS installation easier.

    πŸ‘¨β€πŸ‘©β€πŸ‘¦ Improved MDNS

    πŸ‘ There is a completed implementation of the revised libp2p MDNS spec. This should result in better MDNS discovery and better local/offline operation as a result.

    πŸš— CAR import statistics

    πŸ‘ dag import command now supports --stats option which will include the number of imported blocks and their total size in the output.

    πŸ•Έ Peering command

    πŸš€ This release adds swarm peering command for easy management of the peering subsystem. Peer in the peering subsystem is maintained to be connected at all times, and gets reconnected on disconnect with a back-off.

    πŸ‘€ See ipfs swarm peering --help for more details.

    πŸ”„ Changelog


    Contributor Commits Lines Β± Files Changed
    Daniel MartΓ­ 42 +8549/-6587 170
    Eric Myhre 55 +5883/-6715 395
    πŸ‘€ Marten Seemann 100 +1814/-2028
    Steven Allen 80 +1573/-1998 127
    hannahhoward 18 +1721/-671 53
    Will 2 +1114/-1217 18
    Andrew Gillis 2 +1220/-720 14
    gammazero 3 +43/-1856 10
    Masih H. Derkani 3 +960/-896 8
    Adin Schmahmann 25 +1458/-313 44
    vyzo 27 +986/-353 60
    Will Scott 6 +852/-424 16
    Rod Vagg 19 +983/-255 66
    Petar Maymounkov 6 +463/-179 22
    web3-bot 10 +211/-195 24
    adlrocha 1 +330/-75 15
    RubenKelevra 2 +128/-210 2
    Ian Davis 3 +200/-109 17
    Cory Schwartz 3 +231/-33 7
    Keenan Nemetz 1 +184/-71 2
    Randy Reddig 2 +187/-53 8
    Takashi Matsuda 3 +201/-2 7
    guseggert 4 +161/-20 9
    Lucas Molas 5 +114/-47 27
    nisdas 4 +115/-45 7
    Michael MurΓ© 6 +107/-33 24
    Richard Ramos 2 +113/-9 3
    Marcin Rataj 12 +88/-24 13
    Ondrej Prazak 2 +104/-6 4
    Michal Dobaczewski 2 +77/-28 3
    Jorropo 3 +9/-75 4
    Andey Robins 1 +70/-3 3
    Gus Eggert 10 +34/-31 12
    noot 1 +54/-9 5
    Maxim Merzhanov 1 +29/-24 1
    Adrian Lanzafame 1 +30/-13 2
    Bogdan Stirbat 1 +22/-16 2
    Shad Sterling 1 +28/-3 1
    Jesse Bouwman 5 +30/-0 5
    Pavel Karpy 1 +19/-7 2
    lasiar 5 +14/-10 5
    Dennis Trautwein 1 +20/-4 2
    Louis Thibault 1 +22/-1 2
    whyrusleeping 2 +21/-1 2
    aarshkshah1992 3 +12/-8 3
    Peter Rabbitson 2 +20/-0 2
    bt90 2 +17/-2 2
    Dominic Della Valle 1 +13/-1 2
    Audrius Butkevicius 1 +12/-1 1
    Brian Strauch 1 +9/-3 1
    Aarsh Shah 2 +1/-11 2
    Whyrusleeping 1 +11/-0 1
    Max 1 +7/-3 1
    vallder 1 +3/-5 1
    Michael Burns 3 +2/-6 3
    Lasse Johnsen 1 +4/-4 2
    snyh 1 +5/-2 1
    Hector Sanjuan 2 +3/-2 2
    市川恭佑 (ebi) 1 +1/-3 1
    godcong 2 +2/-1 2
    Mathis Engelbart 1 +1/-2 1
    folbrich 1 +1/-1 1
    Med Mouine 1 +1/-1 1
  • v0.9.1 Changes

    July 20, 2021

    πŸš€ This is a small bug fix release resolving the following issues:

    1. A regression where the empty CID bafkqaaa could not resolve on gateways #8230
    2. A panic on OpenBSD #8211
    3. High CPU usage with QUIC #8256
    4. High memory usage with TCP #8219
    5. Some pubsub issues (libp2p/go-libp2p-pubsub#427, libp2p/go-libp2p-pubsub#430) πŸš€ 6. Updated WebUI to v2.12.4 πŸš€ 7. Fixed the snap deployment #8212

    πŸ”„ Changelog

      • chore: update deps
      • feat: webui v2.12.4
      • test: gateway response for bafkqaaa
      • fix: downgrade mimetype dependency
      • update go-libp2p to v0.14.3
      • bump snap to build with Go 1.16
    • (v0.14.2 -> v0.14.3):
    • (v0.4.1 -> v0.4.2):
      • release priority locks early when handling batches
      • don't respawn writer if we fail to open a stream; declare it a peer error
      • batch process dead peer notifications
      • use a priority lock instead of a semaphore
      • do the notification in a goroutine
      • emit new peer notification without holding the semaphore
      • use a semaphore for new peer notifications so that we don't block the event loop
      • don't accumulate pending goroutines from new connections
      • Make close concurrent safe
      • Fix close of closed channel
    • (v0.11.1 -> v0.11.2):
      • update quic-go to v0.21.2
    • (v0.2.2 -> v0.2.4):
    • (v0.21.1 -> v0.21.2):
      • update qtls to include the crypto/tls fix of Go 1.16.6 / 1.15.14
      • cancel the PTO timer when all Handshake packets are acknowledged
      • update to Go 1.17rc1
      • update Ginkgo to v1.16.4 and Gomega to v1.13.0 (lucas-clemente/quic-go#3139)
    • (v0.3.2 -> v0.3.3):


    Contributor Commits Lines Β± Files Changed
    vyzo 8 +205/-141 12
    πŸ‘€ Marten Seemann 7 +127/-74
    gammazero 2 +43/-5 3
    Steven Allen 1 +13/-2 1
    Adin Schmahmann 3 +13/-2 3
    Marcin Rataj 2 +9/-1 2
    Aaron Bieber 1 +6/-2 1
  • v0.9.0 Changes

    June 22, 2021

    πŸš€ We're happy to announce go-ipfs 0.9.0. This release makes go-ipfs even more configurable with some fun experiments to boot. We're also deprecating or removing some uncommonly used features to make it easier for users to discover the easy ways to use go-ipfs safely and efficiently.

    As usual, this release includes important fixes, some of which may be critical for security. Unless the fix addresses a bug being exploited in the wild, the fix will not be called out in the release notes. Please make sure to update ASAP. See our release process for details.

    πŸ”¦ Highlights

    πŸ“¦ Exporting of DAGs via Gateways

    πŸ‘ Gateways now support downloading arbitrary IPLD graphs via the /api/v0/dag/export endpoint. This endpoint works in the same way as the ipfs dag export command.

    One major thing this enables is ability to verify data downloaded from public gateways. If you go to you are using the old school HTTP transport, and trusting that the gateway is being well behaved. However, if you download the graph as a DAG archive then it is possible to verify that the data you downloaded does in fact match bafyexample.

    βž• Additionally, it was previously quite painful to download things other than UnixFS (files + directories) using gateways. It is now possible to download arbitrary IPLD graphs from gateways, making them useful as a general-purpose alternative to p2p transports.

    πŸ’» This opens exciting opportunities in areas like thin clients, mobile browsers and IoT devices, which now can delegate IPFS resolution to any public gateway, and have ability to verify that the data received matches the requested hash.

    ☁ Custom DNS Resolvers

    Resolution of DNS records for DNSLink and DNSAddrs means that names are sent in cleartext between the operating system and the DNS server provided by an ISP. In the past, the only way to customize DNS resolution in IPFS stack was to set up own DNS proxy server.

    There is now the ability to customize DNS resolution and override the default resolver from the OS with DNS over HTTPS (DoH) one. We made it really flexible: override can be applied globally, or per specific TLD/FQDN. Examples can be found in the documentation.

    πŸ‘ πŸ‘ͺ Support for non-ICANN DNSLink names

    πŸ— Building off of the support for custom DNS resolvers it is now possible to create DNSLink names not handled by ICANN and choose how that domain name will be resolved. An example of this is how ENS is supported, despite .eth not being an ICANN TLD you can point .eth to any ENS resolver you want (including a local one).

    0️⃣ While go-ipfs may have some DoH defaults for a few popular non-ICANN DNSLink names (e.g. ENS), you are free to use any protocol for a naming system and as long as it exposes a DNSLink record via a DNS endpoint you can make it work.

    ⚑️ πŸ–₯️ Updated to the latest WebUI

    Our web interface now includes experimental support for pinning services, and various updates to Files and Peers screens.

    Remote pinning services added via the ipfs pin remote service add command are already detected, one can also add one from Settings screen, and it will appear in Set pinning interface on the Files screen.

    Data presented on the Peers screen can now be copied by simply clicking on a specific cell, and a list of open streams gives better insight into how a local node interacts with a specific peer.

    πŸš€ See release notes for ipfs-webui v2.12 for screenshots and more details.

    πŸ”‘ IPNS keys can now be exported via the CLI without stopping the daemon

    ipfs key export no longer requires interrupting ipfs daemon ✨

    πŸ•Έ Experimental DHT Client and Provider System

    An area of go-ipfs that has been historically tricky is how go-ipfs finds who has the data they are looking for. While the IPFS Public DHT is only one of the ways go-ipfs can find data it tends to be an important one. While since go-ipfs v0.5.0 the time to find content in the network has dropped significantly the time to put/get IPNS records or for a node to advertise the content it has still has much room for improvement.

    We have been doing some experimenting and have an alternative DHT client that essentially trades off some resources and in return is much more performant. We have also included with the experimental DHT client a bulk provider system that takes advantage of the new client to more efficiently do many advertisements at a time

    This work is quite new and still under development, however, the results so far have been promising especially for users with lots of data who have otherwise been having difficulty advertising their data into the IPFS Public DHT

    πŸ“š As described in the experimental features documentation the experimental client can be enabled using the command below (or modifying the config file).

    ipfs config --json Experimental.AcceleratedDHTClient true

    A few things to take note of when AcceleratedDHTClient is enabled:

    • go-ipfs will likely use more resources then previously
    • DHT queries will not be usable (i.e. finding which peers have some data, finding where a particular peer is, etc.) for the first 5-10 minutes of operation depending on your network conditions
    • πŸ“„ There is an ipfs stats provide command that will help you track your provide/reprovide usage, if you are providing lots of data you may want to consider how to reduce the amount you are providing (e.g. Reprovider Strategies and/or Strategic Providing)

    πŸ“š See the documentation for more details.

    πŸšΆβ€β™€οΈ Migrations

    πŸ“¦ Migrations are now individually packaged

    ⬆️ While previously the go-ipfs repo migration binary was monolithic and contained all migrations from previous go-ipfs versions the binaries are now packaged individually. However, the fs-repo-migrations binary is still there to help those who manually upgrade their repos to download all the individual migrations.

    ⬆️ This means faster download times for upgrades, a much easier time building migrations for those who make use of custom plugins, and an easier time developing new migrations going forward.

    πŸ”§ Configurable migration downloads enable downloading over IPFS

    ⚑️ Previously the migration downloader built into go-ipfs downloaded the migrations from While users could use tools like ipfs-update to download the migrations over IPFS or manually download the migrations (over IPFS or otherwise) themselves, this is now automated and configurable. Users can choose to download the migrations over IPFS or from any specified IPFS Gateway.

    πŸ“š The configurable migration options are described in the config file documentation, although most users should not need to change the default settings.

    πŸš€ The main benefit here is that users behind restrictive firewalls, or in offline/private deployments, won't have to run migrations manually, which is especially important for desktop use cases where go-ipfs is running inside of IPFS Desktop and Brave.

    πŸ— 🍎 Published builds for Apple M1 hardware

    πŸ— Go now supports building for Darwin ARM64, and we are now publishing those builds

    πŸ—„ πŸ‘‹ Deprecations and Feature Removals

    πŸ—„ The ipfs object commands are now deprecated

    In the last couple years most of the Object API's commands have become fulfillable using alternative APIs.

    πŸ‘ The utility of Object API's is limited to data in UnixFS-v1 (dag-pb) format. If you are still using it, it is highly recommended that you switch to the DAG ipfs dag (supports modern data types like dag-cbor) or Files ipfs files (more intuitive for working with dag-pb) APIs.

    ⚑️ While the Object API and commands are still usable they are now marked as deprecated and hidden from users on the command line to discourage further use. We also updated their --help text to point at the modern replacements.

    πŸ—„ X-Ipfs-Gateway-Prefix is now deprecated

    🚚 IPFS community moved towards dedicated Origins (DNSLink and subdomain gateways) which are much easier to isolate and reason about.

    🚚 Setting up Gateway.PathPrefixes and X-Ipfs-Gateway-Prefix is no longer necessary and support will be removed in near future.

    🚚 Proquints support removed

    🚚 A little known feature that was not well used or documented and was more well known for the error message Error: not a valid proquint string users received when trying to download invalid IPNS or DNSLink names (e.g. We have removed support for proquints as they were out of place and largely unused, however proquints are valid multibases so if there is renewed interest in them there is a way forward.

    🚚 SECIO support removed

    🚚 SECIO was deprecated and turned off by default given the prevalence of TLS and Noise support, SECIO support is now removed entirely.

    πŸ”„ Changelog

    ❀️ Contributors

    Contributor Commits Lines Β± Files Changed
    πŸ‘€ Marten Seemann 358 +17444/-12000
    Eric Myhre 82 +9672/-2459 328
    Ian Davis 7 +8421/-737 116
    Daniel MartΓ­ 18 +2733/-4377 313
    Adin Schmahmann 46 +5387/-1289 125
    Steven Allen 95 +3278/-1861 200
    hannahhoward 14 +1380/-3667 84
    gammazero 29 +2520/-1161 88
    Hector Sanjuan 12 +511/-3129 52
    vyzo 77 +2198/-940 117
    Will Scott 12 +912/-593 37
    Dirk McCormick 3 +1384/-63 14
    Andrew Gillis 3 +1231/-39 19
    Marcin Rataj 37 +549/-308 72
    Aarsh Shah 13 +668/-86 30
    Olivier Poitrey 1 +469/-182 15
    Rod Vagg 9 +364/-184 14
    whyrusleeping 5 +253/-32 11
    Cory Schwartz 10 +162/-115 37
    Adrian Lanzafame 8 +212/-60 11
    aarshkshah1992 7 +102/-110 9
    Jakub Sztandera 7 +126/-75 16
    huoju 4 +127/-41 6
    acruikshank 6 +32/-24 7
    Toby 1 +41/-1 2
    Naveen 1 +40/-0 1
    Bogdan Stirbat 1 +22/-16 2
    KΓ©vin Dunglas 1 +32/-2 2
    Nicholas Bollweg 1 +22/-0 1
    q191201771 2 +4/-11 2
    Mathis Engelbart 1 +12/-2 1
    requilence 1 +13/-0 1
    divingpetrel 1 +7/-4 2
    Oli Evans 2 +9/-2 3
    Lucas Molas 3 +7/-3 3
    RubenKelevra 3 +2/-6 3
    Will 1 +1/-5 1
    Jorropo 1 +4/-2 1
    Ju Huo 1 +2/-2 1
    zhoujiajie 1 +1/-1 1
    Luflosi 1 +1/-1 1
    Jonathan Rudenberg 1 +1/-1 1
    David Pflug 1 +1/-1 1
    Ari Mattila 1 +1/-1 1
    Yingrong Zhao 1 +0/-1 1
  • v0.8.0 Changes

    February 18, 2021

    πŸš€ We're happy to announce go-ipfs 0.8.0! This is planned to be a fairly small release focused on integrating in the new pinning service/remote pinning API that makes the experience of managing pins across pinning services easier and more uniform.

    πŸ”¦ Highlights

    πŸ“Œ 🧷 Remote pinning services

    πŸ“Œ There is now support for asking remote services to pin data for you. This means anyone can implement the spec (developed in this repo) and allow for pin management.

    πŸ“Œ All of the CLI (and corresponding HTTP API) commands are available under ipfs pin remote.

    πŸ“Œ This remote pinning service comes with a redesign of how we're thinking about pinning and includes some commonly requested features such as:

    • πŸ“‡ Pins can have names (and coming soon metadata)
    • πŸ“Œ The same content can be pinned multiple times, but of course stored only once
      • This allows applications using the same pinning service to manage their own pins without worrying about removing content important to another application
    • πŸ“Œ Data can be pinned in either the foreground or background

    Examples include:

    ipfs pin remote service add myservice https://myservice.tld:1234/api/path myaccess key
    ipfs pin remote add /ipfs/bafymydata --service=myservice --name=myfile 
    ipfs pin remote ls --service=myservice --name=myfile
    ipfs pin remote ls --service=myservice --cid=bafymydata
    ipfs pin remote rm --serivce=myservice --name=myfile

    A few notes:

    πŸ“Œ Remote pinning services work with recursive pins. This means commands like ipfs pin remote ls will not list indirectly pinned CIDs.

    πŸ”§ While pinning service data is stored in the configuration file it cannot be edited directly via the ipfs config commands due to the sensitive nature of pinning service API keys. The ipfs pin remote service commands can be used for interacting with remote service settings.

    πŸ“Œ πŸ“Œ Faster local pinning and unpinning

    πŸ“Œ The pinning subsystem has been redesigned to be much faster and more flexible in how it tracks pins. For users who are working with many pins this will lead to a big speed increase in listing and modifying the set of pinned items as well as decreased memory usage.

    πŸ“Œ Part of the redesign was setup to account for being able to interact with local pins the same way we can now interact with remote pins (e.g. names, being allowed to pin the same CID multiple times, etc.). Keep posted for more improvements to pinning.

    DNSLink names on https:// subdomains

    πŸ‘ Previously DNSLink names would have trouble loading over subdomain gateways with HTTPS support since there is no way to get multilevel wildcard certificates (e.g. cannot be covered by * Therefore, when trying to load DNSLink names over https:// subdomains go-ipfs we now forward to an encoded DNS name. Since DNS names cannot contain . in them they are escaped using -.

    /ipns/ β†’ ipns:// β†’ :point_left: a single DNS label, no TLS error

    ⚑️ QUIC update

    🐎 QUIC support has received a number of upgrades, including the ability to take advantage of larger UDP receive buffers for increased performance.

    🐧 Linux users may notice a logged error on daemon startup if your system needs extra configuration to allow IPFS increase the buffer size. A helpful link for resolving this is in the log message as well as here.

    πŸ— πŸ‘‹ No more Darwin 386 builds

    βœ… Go 1.15 (the latest version of Go) no longer supports Darwin 386 and so we are dropping support as well.

    πŸ”„ Changelog


    Contributor Commits Lines Β± Files Changed
    Eric Myhre 180 +26453/-11032 883
    πŸ‘€ Marten Seemann 212 +14876/-9352
    hannahhoward 41 +9195/-3113 186
    Alex Cruikshank 5 +3323/-1895 58
    Andrew Gillis 3 +3792/-581 21
    vyzo 49 +2675/-949 95
    Adin Schmahmann 57 +1473/-837 90
    Steven Allen 43 +1252/-780 99
    Petar Maymounkov 3 +1755/-113 17
    Marcin Rataj 35 +979/-210 61
    Paul Wolneykien 2 +670/-338 9
    Jeromy Johnson 9 +525/-221 21
    gammazero 11 +366/-101 26
    Hector Sanjuan 7 +312/-0 11
    Dirk McCormick 4 +190/-90 15
    Will Scott 1 +252/-0 1
    Oli Evans 1 +201/-0 1
    Tomasz ZdybaΕ‚ 2 +182/-3 6
    Daniel MartΓ­ 6 +104/-66 35
    Sam 3 +76/-59 5
    Łukasz Magiera 2 +92/-3 5
    whyrusleeping 3 +77/-15 3
    nisdas 3 +76/-15 4
    RaΓΊl Kripalani 3 +59/-31 5
    Lucas Molas 1 +66/-3 2
    Alex Towle 1 +52/-8 2
    Dennis Trautwein 1 +58/-0 2
    Adrian Lanzafame 2 +49/-7 4
    klzgrad 1 +49/-5 2
    Fazlul Shahriar 1 +35/-14 17
    Yingrong Zhao 1 +45/-2 2
    Jakub Sztandera 2 +22/-13 2
    Chaitanya 8 +16/-16 8
    Aarsh Shah 1 +27/-1 3
    Rod Vagg 1 +23/-4 2
    M. Hawn 4 +11/-11 8
    Will 1 +12/-2 1
    frrist 1 +7/-0 1
    Rafael Ramalho 2 +5/-2 2
    dependabot[bot] 1 +3/-3 1
    Zaurbek Zhakupov 1 +3/-3 1
    Tom Worrall 1 +4/-2 1
    Jorropo 2 +5/-1 2
    Chaitanya Raju 1 +3/-3 2
    Egon Elbre 1 +0/-5 1
    incognitomode 1 +2/-2 1
    achingbrain 1 +2/-2 1
    Michael Burns 1 +2/-2 1
    David Florness 2 +2/-2 2
    RubenKelevra 1 +2/-1 1
    Andrew Nesbitt 2 +2/-1 2
    Tarun Bansal 1 +1/-1 1
    Max Inden 1 +1/-1 1
    K 1 +2/-0 1
    Jacob Heun 1 +1/-1 1
    Henrique Dias 1 +1/-1 1
    Bryan White 1 +1/-1 1
    Bryan Stenson 1 +1/-1 1