Skip to content

Building PiCode

TomΓ‘s Platero edited this page Oct 9, 2026 · 3 revisions

Building PiCode

PiCode's source lives in picode-source/, inside this repository: the VS Code-derived editor with every PiCode change committed as code. There is nothing to download and nothing to apply β€” the tree already is PiCode. Releases are built from it, CI builds it, and it is the only way to change editor behaviour: a behaviour change is written in TypeScript, in the tree itself, and compiled.

This document is for contributors. If you only want to use PiCode, take a prebuilt release β€” see Getting PiCode.

Since 2026-09-27 (owner's decision) the retired build machinery β€” the download step, the patch application, the jq dependency β€” is gone. Anything it once produced is now code in the tree, committed like any other change.

What ./picode-source is

The editor tree with the PiCode changes already inside. It descends from Microsoft VS Code 1.135.0 (commit 08d4889f, recorded in upstream/stable.json); the de-branding work and PiCode's own source changes were applied once, and from that day the tree is versioned in this repository:

  • nothing is downloaded: the tree is already here;
  • no patch is ever applied: the changes are the code;
  • upstream/stable.json remains as the record of provenance.

Because Microsoft's source now lives inside this repository, the rule of CONTRIBUTING.md moved up a level: this repository must not be pushed to a public origin. Publishing it is exclusively the owner's decision.

The build, five phases

dev/build.sh runs five phases. The order is not negotiable.

Phase What happens
1 Β· Prepare Checks the source and the identity; installs dependencies only when the recorded state stops matching (dev/deps-current.mjs decides); applies the product delta to picode-source/product.json via distribution/apply-product-delta.mjs; brings in the connector extensions/picode
2 Β· Connector Compiles the connector extension
3 Β· Compile Compiles the editor (the fast esbuild route, with a type-check gate)
4 Β· Pack Produces PiCode-Win32-x64/ (or PiCode-linux-x64/)
5 Β· Stage dev/stage-distribution.sh: portable data/ profile, first-run settings, icons and names, the pi runtime install
./dev/build.sh          # whole chain (β‰ˆ3–4 min warm, more the first time)
./dev/build.sh -o       # check mode only β€” seconds, installs and compiles nothing
./dev/build.sh -i       # force a dependency install even if the recorded state matches
  • -o stops inside phase 1, after checking the source and the identity and before installing anything; it exits with code 0 and compiles nothing. In practice it takes seconds, and it is the way to know the tree is the right one before paying for a long build.
  • -f does not exist, on purpose: it used to delete ./picode-source. That tree is the source and the only copy that exists; the flag errors and explains why.
  • -s is accepted with a notice: it used to mean "reuse the tree instead of downloading it", and since 2026-09-27 that is the only thing that can happen.

OS_NAME is derived from OSTYPE (Git Bash β†’ windows) and is mandatory: an OSTYPE from which windows, osx or linux cannot be derived is a hard error.

Where everything lands:

Path What it is
./picode-source PiCode's source. Edited, committed, and living in this repository.
./PiCode-Win32-x64 The pack output (phases 4 and 5), gitignored.
./PiCode-Win32-x64/PiCode.exe The executable built from source.

Dependencies (Windows)

The scripts are Bash: run them from Git Bash (included in Git for Windows); PowerShell cannot execute them. jq is no longer needed for anything β€” the build reads and writes the JSON it touches with node.

Tool Why Install
Git for Windows Git and Git Bash: without it there is no shell for the scripts. winget install --id Git.Git -e
Node.js 24.18.0 (see .nvmrc) npm ci and the gulp tasks. nvm-windows: nvm install 24.18.0 && nvm use 24.18.0
Python 3.11 Asked by VS Code's build system for the native modules (node-gyp). winget install --id Python.Python.3.11 -e
Rustup Compiles some native modules. It rewrites PATH when it finishes: restart the shell. rustup.rs
7-Zip Produces the release .zip. winget install --id 7zip.7zip -e
Visual Studio 2022 (Community or Build Tools) with Desktop development with C++ and the Spectre libraries node-gyp compiles the native modules with MSBuild. Without the Spectre libraries the build stops with error MSB8040. VS Installer β†’ Modify β†’ Individual components

Check Spectre without installing anything:

VSW="/c/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe"
"$VSW" -latest -products '*' \
  -requires Microsoft.VisualStudio.Component.VC.Runtimes.x86.x64.Spectre \
  -property installationPath
# no output = the component is missing, and the build will stop with MSB8040

The development loop (see a change in seconds)

To touch code and see it in the editor you do not need the five phases:

cd picode-source
npm run transpile-client      # src/ β†’ out/ : ~7,500 files in ~7 seconds
npm run watch                 # from then on, re-transpiles on save
scripts\code.bat              # launches the editor FROM out/ (first run downloads Electron)

Things worth knowing about this mode:

  • The UI comes up in English: development mode deliberately skips the translation step. The packaging step brings the shipped copy β€” that is what ./dev/build.sh is for.
  • transpile-client does not type-check. Type control happens when building the product (or separately, with npm run gulp watch-client).
  • The development out/ is never packaged: the product build writes its own outputs (out-build, out-vscode-min) and does not collide with it.

Memory (heap) requirements

Packing asks for more than 6 GB of heap. On a machine with 8 GB:

NODE_OPTIONS="--max-old-space-size=5632" ./dev/build.sh

With 16 GB, 12288 is more than enough. On Linux, note that Ubuntu 24.04 ships systemd-oomd, which kills the whole cgroup under memory pressure without printing "Killed" β€” stop it before building (sudo systemctl stop systemd-oomd).

Bringing a newer VS Code

upstream/stable.json is the provenance pin: the tag, commit and repository of the VS Code the tree descends from. The day a newer version is wanted, the work is not to re-apply anything: it is to merge the two versions. The repository received the tree as a squashed import (without VS Code's history inside), so the merge happens in a disposable clone that does have that history, and the result enters here as a normal commit. (This plan is written but not yet exercised end to end.)

  1. Restore the local history bundle (.scratch/picode-source-history.bundle) into a working clone outside the repository (git clone <bundle> .merge-work), then git -C .merge-work fetch --unshallow origin β€” the merge needs both branches and their common ancestor.
  2. Merge there: git -C .merge-work merge <new-commit>. Conflicts surface one by one, with context.
  3. Bring the result home: copy the merged tree over picode-source/ (leaving node_modules and the out* folders alone) and commit here β€” the merge commit is the new provenance. git status in the parent is the control: if only what the merge changed moved, it entered clean.
  4. Update tag and commit in upstream/stable.json.
  5. Verify the tree is still what the build expects: ./dev/build.sh -o.
  6. Build, and confirm the editor starts.

RELEASE_VERSION comes from distribution/product-delta.json (set.version), which is the only home of the version.

The graphical front-end

builder/ (C# / WinUI 3) drives the same pipeline with one button: it needs only the .NET SDK, drives Windows natively and Linux through WSL. cd builder && ./build.cmd. All entry points (terminal, GUI, CI) run the same engine; the engine in dev/ stays executable on its own.

Linux, and Windows with WSL

The chain understands Windows and Linux; macOS is not wired yet. The OS is deduced from the environment and decides the output folder name (PiCode-linux-x64 on Linux).

  • A Linux build must be made on Linux. Native modules (the terminal, the file watcher) compile for the machine you compile on: you cannot cross-compile from Windows.
  • With WSL (install as administrator, then reboot): put the repository on the Linux disk (~/PiCode), not on /mnt/d/... β€” building across the Windows disk with thousands of small files is several times slower. With WSL 2 on Windows 11 (WSLg) you can even open the resulting editor on the desktop to test it.

If it fails

  • MSB8040 β†’ the Spectre libraries are missing (check above).
  • npm ci failing once and then continuing β†’ normal, the pipeline retries.
  • The editor built but behaves oddly β†’ see the verification checklist in Distribution and Licensing; note that a PiCode.exe reading ARM64 binaries on x64 passes every file-level check: verify the PE machine type of any archive you build on.

Related: Architecture Β· CI and Releases Β· Distribution and Licensing

Clone this wiki locally