Building from source
Prerequisites
Section titled “Prerequisites”Node 20 or newer, pnpm, and a Rust toolchain. On Linux you also need Tauri’s system dependencies:
sudo apt-get install -y libwebkit2gtk-4.1-dev libayatana-appindicator3-dev \ librsvg2-dev libssl-dev libgtk-3-dev patchelf build-essentialRun it
Section titled “Run it”pnpm installpnpm fetch:node-sidecar # fetches the Node runtime the extension host sidecar needspnpm dev # tauri devfetch:node-sidecar asks rustc for your host target, so the Rust toolchain has to be on your
PATH before you run it. Pass a target triple explicitly to fetch a different one:
node scripts/fetch-node-sidecar.mjs aarch64-apple-darwinpnpm dev does more than start Tauri. Before the window opens it builds the extension host,
stages it into the app bundle, and builds every first-party extension, because the app reads
that output off disk to register them. A clean checkout that skips this has no built-in
commands.
pnpm build runs a full tauri build. On a tagged push, CI builds four targets — Linux x64 and
arm64, macOS on Apple Silicon, and Windows x64 — and opens a draft GitHub release with the
installers attached. A manual workflow run builds the same targets and uploads them as workflow
artifacts instead.
Checks
Section titled “Checks”pnpm typecheckpnpm lintpnpm test # every workspace package's own suite
# Build the host and the built-in extensions first, or the Rust tests that# exercise the real sidecar silently skip themselves instead of failing.pnpm --filter @openray/extension-host buildnode scripts/build-builtin-extensions.mjs
cd src-tauricargo test --lib --features custom-protocolcargo clippy --all-targets -- -D warningsCI runs all of the above. It also runs cargo check and cargo clippy for
aarch64-apple-darwin and x86_64-pc-windows-msvc on every push and pull request, which is how
platform-specific code stays compiling without those machines. See
Platform verification.
Regenerating the app icon
Section titled “Regenerating the app icon”The app icon’s source of truth is src-tauri/icons/icon.svg — the same bolt the webview
ships as its favicon, on a filled tile. After editing it, rasterize and regenerate the
whole PNG/ICO/ICNS set:
magick -background none src-tauri/icons/icon.svg -resize 1024x1024 /tmp/openray-icon.pngpnpm tauri icon /tmp/openray-icon.pngrm -rf src-tauri/icons/android src-tauri/icons/ios src-tauri/icons/64x64.pngThe last line drops output for the mobile targets and a size this project doesn’t bundle
— see tauri.conf.json’s bundle.icon.
Regenerating the tray icon
Section titled “Regenerating the tray icon”The tray icon is separate, and monochrome on every platform: the bare bolt, in solid black
(src-tauri/icons/tray.svg) and solid white (tray-inverted.svg).
macOS is handed the black one as a template image and recolours it itself for a light or
dark menu bar. Linux and Windows draw the bitmap as given, so tray::apply_system_theme
picks between the two by the panel’s theme and re-picks when it changes. On Linux that is
the desktop theme; on Windows it is the taskbar’s own SystemUsesLightTheme setting, read
from the registry — the theme Tauri reports there is the apps one
(AppsUseLightTheme), and the two commonly differ.
magick -background none src-tauri/icons/tray.svg -resize 72x72 PNG32:src-tauri/icons/tray@2x.pngmagick -background none src-tauri/icons/tray-inverted.svg -resize 72x72 PNG32:src-tauri/icons/tray-inverted@2x.pngDocumentation site
Section titled “Documentation site”This site lives in apps/website and deploys from .github/workflows/pages.yml, which runs on
pushes that touch apps/website or the workflow itself.
pnpm --filter openray-website dev # local previewpnpm --filter openray-website screenshots # regenerate the SVG screenshotspnpm --filter openray-website buildThe screenshots are drawings, not captures: apps/website/scripts/render-screenshots.mjs
renders declarative scenes to SVG using the app’s own dark palette. Edit a scene there and
re-run the script rather than editing an SVG by hand.