Pi-Bolt Docs

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 codeCompiled machine codeCompiled machine code
Extensions loaded at run timeInterpretedInterpreted, then JIT-compiled as they warm up
bun:ffi, heavy eval / new Functionbun:ffi does not workWorks
MemoryLowestHigher once the JIT has compiled something
pi-bolt --version ends inJIT offJIT 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 with bun:ffi requires the JIT, because native calls through bun:ffi are 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.

BenchmarkDefaultJIT buildPi on Bun
Linux: CPU, interactive session (5 prompts)309 ms324 ms913 ms
Linux: ready to type47 ms52 ms143 ms
macOS: CPU, interactive session (5 prompts)175 ms175 ms555 ms
macOS: memory, interactive session100 MB104 MB208 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 runsLaunch to readyThe command
Compiled in, default build52 ms55 ms
Loaded at run time, default build91 ms1,315 ms
Loaded at run time, JIT build83 ms48 ms
Loaded at run time, Pi on Bun244 ms45 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.