Repository navigation
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.
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.jsonremains 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.
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-
-ostops 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. -
-fdoes 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. -
-sis 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. |
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 MSB8040To 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.shis for. -
transpile-clientdoes not type-check. Type control happens when building the product (or separately, withnpm 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.
Packing asks for more than 6 GB of heap. On a machine with 8 GB:
NODE_OPTIONS="--max-old-space-size=5632" ./dev/build.shWith 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).
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.)
- Restore the local history bundle (
.scratch/picode-source-history.bundle) into a working clone outside the repository (git clone <bundle> .merge-work), thengit -C .merge-work fetch --unshallow origin— the merge needs both branches and their common ancestor. - Merge there:
git -C .merge-work merge <new-commit>. Conflicts surface one by one, with context. - Bring the result home: copy the merged tree over
picode-source/(leavingnode_modulesand theout*folders alone) and commit here — the merge commit is the new provenance.git statusin the parent is the control: if only what the merge changed moved, it entered clean. - Update
tagandcommitinupstream/stable.json. - Verify the tree is still what the build expects:
./dev/build.sh -o. - Build, and confirm the editor starts.
RELEASE_VERSION comes from distribution/product-delta.json (set.version), which is
the only home of the version.
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.
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.
-
MSB8040→ the Spectre libraries are missing (check above). -
npm cifailing 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.exereading 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