Guides
Choose a build
Every platform has two builds. Pi itself is compiled ahead of time in both. They differ in what happens to code that is loaded while Pi runs, such as extensions.
The two builds#
| Default (JIT off) | JIT build (JIT on) | |
|---|---|---|
| Pi's own code | Compiled machine code | Compiled machine code |
| Extensions loaded at run time | Interpreted | Interpreted, then JIT-compiled as they warm up |
bun:ffi, heavy eval / new Function | bun:ffi does not work | Works |
| Memory | Lowest | Higher once the JIT has compiled something |
pi-bolt --version ends in | JIT off | JIT on |
A JIT (just-in-time compiler) turns code into machine code while the program runs. Pi-Bolt's default build has none: Pi was compiled before you ran it, so it does not need one, and it saves the JIT's compiler threads, warm-up and memory.
Which one to use#
- No extensions, or light ones (a todo list, UI panels, small hooks, most extensions): the default build. These spend their time waiting on the model, files or processes, so how their code runs does not show.
- Extensions that do heavy work in JavaScript (search, parsing, analysis over many files): the JIT build. On the default build their code is interpreted.
- Extensions that use
bun:ffi, such as pi-fff: the JIT build. On the default build they fail withbun:ffi requires the JIT, because native calls throughbun:ffiare generated by the JIT. - Extensions you use every day and can build yourself: compile them into the default build, where they run as machine code. See Compile extensions in.
If you are unsure, the JIT build is the safe choice: it costs within about 5% of the default build in CPU and memory.
What it costs#
The same Pi session on both builds, Pi-Bolt 0.7.3, against Pi 1.1.0 on stock Bun. Lower is better.
| Benchmark | Default | JIT build | Pi on Bun |
|---|---|---|---|
| Linux: CPU, interactive session (5 prompts) | 309 ms | 324 ms | 913 ms |
| Linux: ready to type | 47 ms | 52 ms | 143 ms |
| macOS: CPU, interactive session (5 prompts) | 175 ms | 175 ms | 555 ms |
| macOS: memory, interactive session | 100 MB | 104 MB | 208 MB |
And what it changes for an extension. An example extension command scans a 16.8 MB file character by character (Linux, Pi-Bolt 0.7.3):
| How the extension runs | Launch to ready | The command |
|---|---|---|
| Compiled in, default build | 52 ms | 55 ms |
| Loaded at run time, default build | 91 ms | 1,315 ms |
| Loaded at run time, JIT build | 83 ms | 48 ms |
| Loaded at run time, Pi on Bun | 244 ms | 45 ms |
Most real extensions are not like this command. Measured on Windows with nine popular extensions from npm, run-time extensions on the default build started fastest, used the least memory, and took the same time for their usual actions as with the JIT on. The exception was an extension doing heavy JavaScript work itself: one report took 838 ms with the JIT off and 154 ms with it on.
Switch builds#
$ curl -fsSL https://pi-bolt.opensec.in/install.sh | PIBOLT_VARIANT=arm64-jit sh
Back to the default: PIBOLT_VARIANT=arm64.
$ curl -fsSL https://pi-bolt.opensec.in/install.sh | PIBOLT_VARIANT=x64-jit sh
Back to the default: PIBOLT_VARIANT=x64 (or x64-baseline on a CPU without AVX2).
$env:PIBOLT_VARIANT = "x64-jit" powershell -c "irm https://pi-bolt.opensec.in/install.ps1 | iex"
Back to the default: $env:PIBOLT_VARIANT = "x64".
export PIBOLT_VARIANT=arm64-jit # x64-jit on Linux
On macOS and Linux, the npm package reads PIBOLT_VARIANT on every run and downloads that build on first use.
Remove it to go back to the default.
On Windows, the npm package picks the build when it is installed or updated: set
$env:PIBOLT_VARIANT = "x64-jit", then run npm install -g --allow-scripts=pi-bolt pi-bolt again. Clear
the variable and install again to go back.
Then check with pi-bolt --version. pi-bolt update keeps the build you chose.