Runtime and languages
Pear runs JavaScript on the Bare runtime; here's why, what other languages can plug in via native addons, and how to structure code so one app runs everywhere.
Pear applications are JavaScript programs. The runtime under them is Bare, a small embeddable JavaScript runtime that strips the assumptions Node.js carries about being a server. This page explains why the language story looks the way it does, how non-JavaScript code joins in, and what the recommended app shape is when you want one codebase to run on desktop, mobile, and terminal.
Why JavaScript
Two pragmatic reasons:
-
Web heritage. The peer-to-peer libraries Pear is built on (Hypercore, Hyperdrive, Hyperswarm) are mature JavaScript modules with millions of downloads. Reusing them on the desktop and on mobile through a single language eliminates a translation layer.
-
Bare keeps it small. Bare ships without Node's standard library opinions — no
fs.readon a URL, no built-inhttpmodule, no Worker baggage. That makes it cheap to embed in mobile apps, desktop shells, and constrained terminal environments alike. The Pear runtime adds the bits applications actually need on top.
If you're coming from Node.js, the surface looks similar but isn't identical — see Bare modules for the exact set of standard libraries available.
Other languages: native addons
For code that JavaScript can't naturally express — tight cryptography loops, codec work, hardware access — Bare loads native addons. The bare-addon template is the starting point: write the addon in C, C++, Rust, or any language with a C-compatible ABI, expose it through Bare's addon API, and call it from JavaScript like any module.
For languages that compile to JavaScript (TypeScript being the obvious one) the path is unchanged: compile to JS, then point the application's main field or HTML <script> entrypoint at the compiled output.
One codebase, many platforms: the Pear-end pattern
The recommendation for cross-platform Pear apps is to split the code into two halves:
- Pear-end — the peer-to-peer logic, business rules, and storage. Runs in a worker or worklet thread.
- UI — the platform-specific presentation. Talks to the Pear-end over an inter-process communication (IPC) stream.
Because the Pear-end never imports DOM APIs and never assumes a particular UI framework, it's portable across desktop (Electron), mobile (React Native via Bare iOS / Bare Android), and terminal. Only the UI half changes per platform — it gets a fresh implementation each time, but it's also the cheap half: layout, not logic.
This split is what powers Keet's identical experience across phones, laptops, and terminals: one Pear-end, three UIs.
The Pear JavaScript API — documented in the pear-runtime reference — is the surface a UI talks to, and at the time of writing that surface is not yet supported on mobile. Pear v2 lands the same Pear-end / UI separation as a built-in default, at which point the API parity follows.
See also
pear-runtimereference — the JavaScript API exposed inside a running Pear app.- Bare modules — the standard library available to both halves of a Pear app.
- Storage and distribution — what's running underneath both halves.