Radicle 1.9.0 – Hawthorn

11 min read Original article ↗

Radicle is a peer-to-peer, local-first code collaboration stack built on Git.


19.05.2026

The Radicle team would like to announce the release of Radicle 1.9.0, code name Hawthorn. The Hawthorn tree, or Mayflower, signifies the coming of summer, and has significance for many cultures. In particular, the Hawthorn tree represents the door to the “other side” and is the home of the fairies in Irish culture. It is forbidden to cut down the Hawthorn tree, unless you want to be cursed by the fairies. So, this release represents being on the other side of the fixed security vulnerability in 1.8.0, and readying ourselves to ensure stronger foundations for the future.

This release contains 165 commits by 9 contributors, with a big thanks to:

  • Daniel Norman
  • Josh Soref
  • Richard Levitte
  • stefan
  • Wiktor Kwapisiewicz

Installation

curl -sSLf https://radicle.dev/install | sh -s -- --no-modify-path --version=1.9.0

In this Release

Domain Name Migration

Following a domain move of the project, the names of the bootstrap nodes have changed to: {iris,rosa}.radicle.{xyz → network}. If you are still using the old names in the Radicle configuration, this will be detected and you will see warnings printed. Similarly, if you are using systemd credentials, then you should migrate from xyz.radicle.node.* to dev.radicle.node.*. The COB type names and payload IDs remain unchanged for backwards compatibility.

Revision Ranges in rad patch show

Each revision in the output of rad patch show now shows the base and head of the revision in the format: <base>..<head>. The shortened form is used, but the full commit OID is used when --verbose is passed. This makes comparing two revisions much easier in combination with git range-diff. For example, here is a patch in heartwood:

╭───────────────────────────────────────────────────────────────────────────╮
│ Title    .radicle/ambient: Add pre-plan action for rustup                 │
│ Patch    3bb6f611190fc40207cdee0d22c421b02a6bc717                         │
│ Author   fintohaps (you)                                                  │
│ Head     d9f9d090bde88ba0b6596614579641a15acff871                         │
│ Base     9158df5067429282cbec60292316c13b3d965c5a                         │
│ Commits  ahead 1, behind 3                                                │
│ Status   open                                                             │
│                                                                           │
│ To ensure the correct toolchain is used when building and testing the     │
│ project, a pre-plan action is added for `rustup`.                         │
│ It uses the same `channel` as defined in the `rust-toolchain.toml`.       │
│ A note is left about this duplication, and the possibility of it being    │
│ supported in the future.                                                  │
├───────────────────────────────────────────────────────────────────────────┤
│ d9f9d09 .radicle/ambient: Add pre-plan action for rustup                  │
├───────────────────────────────────────────────────────────────────────────┤
│ ● Revision 3bb6f61 @ 9158df5..d9f9d09 by fintohaps (you) 5 days ago       │
│ ↑ Revision 183d186 @ 9158df5..040ab10 by lars z6MkgEM…1b2w2FV 2 hours ago │
╰───────────────────────────────────────────────────────────────────────────╯

As long as the commits are fetched from fintohaps and lars, then you can run:

$ git range-diff 9158df5..d9f9d09 9158df5..040ab10
1:  d9f9d090b = 1:  d9f9d090b .radicle/ambient: Add pre-plan action for rustup
-:  --------- > 2:  040ab1045 work around problems with Ambient Rust toolchain downloading

Showing that a new commit was added, and no other changes were made.

Nodes Advertise Radicle Version

Nodes will now advertise the version of Radicle they are running in the node announcement as part of the “user agent”, which is shared among the network. For example, the value that will be shared by Radicle 1.9.0 will be /radicle:1.9.0/. This value is also customizable by node operators via the configuration value node.userAgent. Refer to rad config schema for more information on the possible values. Operators that choose to set a custom value are asked to keep the substring /radicle:{YOUR_VERSION}/ which allows for better telemetry regarding version distribution on the network. To opt-out of sending any meaningful user agent, set node.userAgent = null.

Introducing I2P Support

In addition to connections via SOCKS proxy and Tor for *.onion hostnames, I2P hostnames are now supported. These names are of the form *.i2p{,.alt}. To enable making connections via I2P, configure node.i2p, for example:

{
  "node": {
    "i2p": {
      "mode": "proxy",
      "address": "127.0.0.1:4447"
    }
  }
}

Symbolic Canonical References

It is now possible to define symbolic canonical references for a repository. The payload xyz.radicle.crefs was extended to accept an object with key “symbolic” next to “rules”. Consider the following example:

{
  "payload": {
    "xyz.radicle.crefs": {
      "rules": {
        "refs/heads/qa": {
          "allow": [
            "did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk"
          ],
          "threshold": 1
        },
        "refs/tags/*": {
          "allow": "delegates",
          "threshold": 1
        },
      },
      "symbolic": {
        "refs/heads/staging": "refs/heads/qa"
      }
    }
  }
}

Delegates are allowed to create tags, and one particular user is allowed to control the branch named “qa”. The team working on this repository used to call the “qa” branch “staging”, so they decided to keep a symbolic reference from “staging” to “qa” around for a while.

For further information about symbolic references also refer to the documentation of git symbolic-ref.

Deprecating rad config Subcommands

The commands to read and modify particular values in Radicle configuration via the CLI were marked as obsolete, i.e.,

  • rad config get
  • rad config push
  • rad config remove
  • rad config set
  • rad config unset

In the future, please modify Radicle configuration with your favorite text editor (e.g. via rad config edit), or specialized tools like jq.

Fixed Bugs

Gracefully Handle Malformed Addresses

Skip node address entries that cannot be parsed from an SQLite row into a valid address entry. This improves the node service, when it checks available peers. Previously, if it found a row it could not parse, then it would fail the whole process. Now, it will continue, providing valid entries to connect to.

To ensure that invalid IPv6 addresses no longer exist in your SQLite database, invalid addresses are removed. Entries deleted include ones that have an address of the form []:port, or that have an invalid address within the []. This removal happens automatically through a database migration, that runs at node startup.

Handling of * in Canonical References

Correctly handle the canonical reference rules that have a glob star suffix, e.g., refs/heads/main*, refs/heads/main-*, etc. Previously, these would be expanded into sub-component searches. For example, in the previous examples, the search would be expanded to refs/heads/main**/* and refs/heads/main-**/*. Now, the rule will match by prefix, e.g. refs/heads/main-* will match refs/heads/main-a, refs/heads/main-b, refs/heads/main-deadbeef, etc.

Changelog

Checksums

42c90f273cf20c4ee1614dc7601c7595b900bf796ef97ba408dc262d48b7e514  radicle-1.9.0-x86_64-apple-darwin.tar.xz
bf5b7d6437eb1a378502d2e7ffbb192381f82a4d093018021585e1fd2e639530  radicle-1.9.0-aarch64-unknown-linux-musl.tar.xz
7adee42d3c3db6e9ba234040b1d9e37f4c2ea152ba7251e80b61a1afef3362a1  radicle-1.9.0-x86_64-unknown-linux-musl.tar.xz
768ef26013df96ea3506e6cf917726550e2d4bb94be3361dd2d7d6522be2ccf6  radicle-1.9.0-aarch64-apple-darwin.tar.xz