Pear Evolution

Pear is evolving. What began as a peer to peer application runtime inside the Pear CLI is now becoming something far more flexible: an embeddable runtime library that can integrate into any JavaScript environment. This shift marks a major step forward for the Pear ecosystem, making peer to peer over the air updates, distributed deployment, and Bare workers available beyond the CLI itself. In this article, we explore the history behind Pear, why the runtime architecture is changing, and what developers need to know as Pear moves toward a more modular and production ready future.

Pear is evolving, the CLI now has a companion runtime library for peer-to-peer over-the-air updates – now any JS runtime can be a Pear application.

Pear CLI has undergone many iterations in parallel from the beginning of the development journeys of both Bare and Keet. Pear CLI is part of the Pears Ecosystem, which is for creating and deploying peer-to-peer applications. As a bridgehead of the ecosystem the CLI’s focus has been deployment and application runtime. Over time the community has grown as more projects flourish with Pear, this has been a pleasure to observe. We’ve also been able to observe pain and that has driven us to pivot our approach.
The Pear CLI runtime capability (pear run) is deprecated and will be removed. In its place comes an embeddable runtime library that can be integrated into any JavaScript runtime.

This is the story of Pear, from inception to the pear run command to the pear-runtime library.

The History

We initially began using the term “peer-to-peer microkernel” by way of analogy for our abstract conceptualization of what we needed to build. That evolved into “peer-to-peer platform”. Running an application platform on user machines seemed a good fit for a P2P architecture. We wanted to encourage system availability by incentivizing usage. The more Pear applications, the more likely the platform is running, the more theoretical availability.

From the outset we understood that building application UI and implementing peer-to-peer mechanisms are separate concerns, we needed a way to augment the UI development with peer-to-peer capabilities without getting in the way of UI development.

The first iteration wasn’t called pear, we didn’t have that name yet. So we named it after our secret sauce: holepunch dev was the first command. This wrapped Electron, all it did was spawn Electron at a given path. From here the idea was to evolve the command so that it could open Electron not just from disk, but from a Hyperdrive running in the platform sidecar.


We will spare the gory details of the many iterations wrangling between Electron and the Operating Systems but eventually the holepunch dev command became the pear run command with deployment commands like pear stage and pear seed emerging alongside to support it.
Now any Pear application could be run from a pear link, pear run pear://<key>. For developers this meant getting a Pear application to production was trivial because all Pear apps used the same vendor signed build. It meant no OS signing keys needed, no native compiling required, just write HTML, CSS and JS and take an application live.

However the blessing turned out to be a curse. Operating Systems, virus scanners, process managers and more do not expect this non-standard approach. An OS update could occur at any moment and something about the runtime could regress. Notification and Dock/Tray icons were difficult to replace with application branded icons, and even when we could it was glitchy. For example a restarted app could end up with the Pear icon in the Dock. Updating the Electron build became higher and higher risk, many apps using the same build and we can’t test the build update on them.

We also needed to support the runtime with architectural conventions for peer-to-peer applications and this could cause friction with industry conventions –  converting a conventional Electron app to a Pear app wasn’t a very linear path so was a drag on adoption.


We wanted to focus on the future, but these runtime associated issues were eating our time up.

The Pivot

We realised that if we dropped the runtime from Pear CLI and instead created a library for peer-to-peer over-the-air updates and for running Bare workers then that would expose the core value to any JavaScript project, leaving the Pear CLI to focus on application deployment.

The Pear CLI runtime capability replacement library is pear-runtime. It expects package.json with an upgrade field set to the application pear:// link and a specific build directory structure that can be created with the new (since Pear v2.5.0) pear build command. Instead of deploying (eg pear stage) the application contents, the folder built by pear build is the deployment folder.

Where pear run had a Pear global with a run method for spawning workers (global.Pear.run) pear-runtime has an equivalent run method which uses bare-sidecar, a module which comes with the native Bare runtime included.

With renewed focus on application deployment and productionization this allowed us to move forward on codifying our learnings and processes that evolved from undertaking production Keet releases. From Pear v2.6.5 we’ve also introduced the pear provision and pear multisig commands. The pear provision command reduces the disk space needed for an application, effectively stripping interim operations by block-syncing from a source drive. Use this to create a prerelease. The pear multisig command has several subcommands for managing cryptographic cosigning. Define the signers, define the quorum and then sign against the prerelease. Using pear multisig is not just essential to a serious production signoff flow, it also derisks the application drive because unlike all other Pear application drives, Pear multisig’d drives are not machine-bound.

Migrating

IMPORTANT: The  pear run command will be removed around the end of June 2026. It’s critical to migrate any apps before pear run is removed, otherwise this will be an end-of-life point for the application.  To migrate, use the hello-pear-electron boilerplate to create an Electron application with pear-runtime already integrated. Then move across the HTML, JS, and CSS, assets, dependencies and so on over.

Any code using the Pear global must be removed and replaced. For Electron this means:

  • Replace global.Pear.run() with the pear-runtime run() method
  • Replace global.Pear.updates() with pear-runtime updated and updating events
  • Replace global.Pear.exit() with process.exit()
  • Replace global.Pear.exitCode with process.exitCode
  • Replace global.Pear.restart() with app.relaunch()
  • Replace global.Pear.teardown() with graceful-goodbye or similar
  • Replace global.Pear.config.args with process.argv.slice(2)
  • Replace global.Pear.config.applink with require(‘./package.json’).upgrade


The rest of the state on global.Pear.config is either self-referential so no longer relevant, or it’s to do with link parsing, which should be replaced with direct deep link protocol handling.

The hello-pear-electron boilerplate Readme describes how to deploy. We strongly recommend moving to this approach for releasing peer-to-peer applications. Use pear stage for internal previews, staging environment, for sharing ephemeral variations – but not for production. Use pear stage, pear provision and pear multisig in sequence for production rigour and safety. Bear in mind that until this deployment approach is migrated to there is a risk of losing write access if something happens to the machine it’s on. If that happens, there is no way to recover because there’s no way to write an update to use a new application pear link. So use pear multisig.

For help migrating or any other questions about peer-to-peer development with Pear join the Pear Development group on Keet with the following invite:

keet://chat/yfo6dbyb4iz9bhhdq6nzq888dto4b4mxttz94i8ttaidrppwnmtehgn4so6u5jy9cfg41x7aoht5egf8354wjaz7eip5am37ie9ffy3gpq4bngkz35fx4f9zxpeo53qt679q4e8bjazbxoo356pz96c9munhaye

Office hour runs Thursdays at 15:00-16:00 UTC for dedicated Pear team response, but ask a question any time and help generally arrives. 

The Future

The pear install command is round the corner for both applications and binaries. Use pear install pear://<key> to install any application created with pear build. For a sneak peak see the independent pear-install module/CLI. For a demo of the upcoming command, try installing Keet peer-to-peer with npx pear-install pear://17pwkcszz18deaccarhrrixhzf1f5ko1b1dz6j3pxhexebutjwzy. In the near future this will ship with Pear CLI, so the equivalent will be pear install pear://keet.

An equivalent of pear-runtime for iOS and Android is in the works, named pear-mobile. Exactly the same API, built for peer-to-peer over-the-air mobile updates. We’re excited to bring this public but we’re focused on making sure it’s stable and battletested beforehand.

The Pear CLI itself is transforming into a standalone binary that’s deployed with Pear CLI, using the pear-runtime library for P2P OTA updates, so npx pear-install will install pear.
The npx pear command will execute npx pear-install which eliminates all dependency needs for the pear namespace, freeing it up to become the single library entrypoint for both pear-runtime and pear-mobile.

We’re also working on and dogfooding the pear-ci tool, a minimal counterpart to Pear CLI that can be used in CI flows for releasing applications.

Overall our focus is stability, facilitating release flows and production process. As we move forward there are so many unstoppable libraries, tools and applications emerging from the Pears Ecosystem and we’re dedicated to supporting the peer-to-peer revolution. To  join the Pear Development group on Keet, use the following invite:

keet://chat/yfo6dbyb4iz9bhhdq6nzq888dto4b4mxttz94i8ttaidrppwnmtehgn4so6u5jy9cfg41x7aoht5egf8354wjaz7eip5am37ie9ffy3gpq4bngkz35fx4f9zxpeo53qt679q4e8bjazbxoo356pz96c9munhaye