Repository navigation
Browser Version Packages
The browser version runs the whole app in a browser tab, served by a small program on your machine
(nibtree-browser, in src-tauri/browser). People install it from npm with npx nibtree. This page explains the
packages, how CI tests them on every platform, and how each release publishes them. The Docker image is built
from the same packages: see Docker Image.
npm is where developers already get command line tools, and npx runs one without installing anything first.
But nibtree-browser is a native Rust program, a different file for each operating system and processor. npm has
no built-in way to ship one package per platform, so we use the pattern esbuild and others use: one small launcher
package and one optional package per platform.
flowchart LR
U["npx nibtree"] --> L["nibtree: bin/nibtree.mjs"]
L -->|"require.resolve"| P["@nibtree/darwin-arm64 ... win32-arm64"]
P --> B["bin/nibtree-browser"]
B --> G["bin/page: the app's page"]
-
nibtree(npm/nibtree) holds only the launcher,bin/nibtree.mjs. It lists every platform package as an optional dependency, pinned to its own version. -
@nibtree/<os>-<cpu>, six of them:darwin-arm64,darwin-x64,linux-x64,linux-arm64,win32-x64andwin32-arm64. Each one setsosandcpu(andlibc: glibcon Linux), so the package manager installs only the one that fits. It holds the program inbin/and the built page next to it inbin/page.
The launcher finds this machine's package with require.resolve, starts the program with the same arguments and
passes Ctrl+C and other signals on. When the program ends by a signal, the launcher ends by the same signal. If no
package fits, it says so plainly. NIBTREE_BINARY runs another build instead, for development.
The program looks for its page in --assets, then in page next to itself, then in this checkout's build/. So a
platform package works on its own, without the launcher.
.github/workflows/browser.yml runs on every pull request and every push to master, on six runners:
macos-latest (Apple silicon), macos-15-intel, ubuntu-22.04, ubuntu-22.04-arm, windows-latest and
windows-11-arm. Each one:
- builds the page (
bun run build) and runs the browser version's page tests; - runs its Rust tests:
cargo test -p nibtree-browserand the app crate'sbrowser::andcommands::browse::; - builds
nibtree-browserand packs both packages withbun scripts/npm-package.ts pack; - runs
scripts/browser-smoke.tstwice, with Bun and with Node.
The smoke test unpacks the tarballs into a fresh node_modules, as a package manager would, and starts the
launcher on a new repository with a new home folder. It checks --version, that a page without the token gets
401, that the token becomes a cookie, the page, a WebSocket hello, discover_repositories, get_status, an error
from a desktop-only command, and that settings land in ~/.nibtree-browser and never in ~/.nibtree.
release.yml has a browser job that calls browser.yml with publish: true for every beta and stable release. The
programs are then built in release mode, smoke tested, and kept as artifacts. A last job publishes them with
bun scripts/npm-package.ts publish:
- platform packages first, the launcher last, so the launcher never points at a missing package;
- betas under the
nexttag (npx nibtree@next), stable versions underlatest(npx nibtree); - a version that is already on npm is skipped, so rerunning a release is safe;
- without the
NPM_TOKENsecret the release fails, instead of quietly publishing nothing.
Every push to develop rehearses all of this without uploading, and after a release verify-npm installs what
npm serves on Linux, macOS and Windows. See Browser Release Checks.
Setup, once: create the free nibtree organization on npmjs.com (it owns the @nibtree scope), make an npm
granular access token that may publish nibtree and @nibtree/*, and save it as the repository secret NPM_TOKEN.
| File | What it does |
|---|---|
npm/nibtree/bin/nibtree.mjs |
the launcher |
npm/nibtree/lib/platforms.mjs |
the six platforms: Node's names, the Rust target and the package name |
scripts/npmPackages.ts |
package manifests, the dist-tag and the publish order (tested) |
scripts/npm-package.ts |
pack and publish
|
scripts/tarball.ts |
reads .tgz files without the tar program (tested) |
scripts/browser-smoke.ts |
the smoke test |
src-tauri/browser/src/assets.rs |
where the program finds its page |
src-tauri/browser/build.rs |
links the C runtime on Windows |
src-tauri/Cargo.toml |
the desktop feature |
The page in each platform package. One copy in the launcher would be smaller to publish, but then the program would only work through the launcher. Each user downloads only one platform package, so the size is the same for them.
Bun publishes. The repository uses Bun only, and bun publish takes a packed tarball, so the exact file the
smoke test checked is the one that goes to npm. Node is installed in CI only to run the launcher the way npx does.
Our own tarball reader. On Windows runners, Git Bash's GNU tar reads C:\... as a remote host name. Reading
the tarball in TypeScript works the same everywhere.
The version everywhere. bun scripts/version.ts writes the version into npm/nibtree/package.json and its
pins, and check fails if they drift (Versioning and Changelog).
No Tauri in the program. The app crate's desktop feature (on by default) holds everything Tauri: windows,
menus, the preview scheme, the MCP window host and the Tauri side of every command (the #[crate::command] macro
puts it behind cfg(feature = "desktop")). nibtree-browser depends on the app crate with
default-features = false, so it links no WebView: Linux needs no WebKitGTK, and the program is smaller.
Windows CI could not link nibtree-browser. cargo test --workspace on Windows failed with memcpy,
malloc and 100 more unresolved symbols, after msvcrt.lib : warning LNK4003: invalid library format. In a
workspace build the app crate has desktop on, so tauri-build runs: it writes an empty msvcrt.lib to link the
C runtime statically, and puts its folder on the library path of everything that links the app crate, but passes
its matching link arguments to the app's own programs only. src-tauri/browser/build.rs now passes the same
arguments, so nibtree-browser links the C runtime the way the desktop app does, with or without that file. As a
bonus, it needs no Visual C++ redistributable.
- Linux packages need glibc; Alpine and other musl systems are not supported yet.
Adding a platform means a row in platforms.mjs, a matrix entry in browser.yml and a pin in
npm/nibtree/package.json (bun scripts/version.ts set writes it). scripts/npmPackages.test.ts fails when the
pins and the platform list disagree. See also Releases and CI.
These pages are generated from docs/wiki. To correct something, open a pull request against the source file; edits made here are overwritten.
Using Nibtree
- Getting Started
- Welcome Screen
- Workspaces
- Files Panel
- File Operations
- File Icons
- Rounded Panels
- Editor and Tabs
- Pin Reorder and Wrap Tabs
- Single Tab Title
- Split Editor
- New File and Unsaved Changes
- Unload Hidden Tabs
- Editing Code
- Code Appearance
- Markdown Editor
- Image and PDF Preview
- Search Everywhere
- Recent Files
- Navigation Bar
- Find and Replace
- Changes and Commits
- Sign In Prompts
- Commit Box Layout
- Repository Actions
- Commit Options
- Ignoring Files
- Diffs
- Inline Diffs
- Staging View
- Revert a Change
- Resolving Conflicts
- Merge Tool
- Blame
- History and Log
- Merge Commits
- Branches and Tags
- Branches Popup
- Remotes
- Stashes
- Shelf
- Git Menu
- Git Dialogs
- Interactive Rebase
- Worktrees
- AI Agents
- AI Tasks
- AI Usage
- Keep Computer Awake
- Submodules
- Git LFS
- GitHub
- Git Console
- Terminal
- Terminal Features
- Scripts
- Navigation
- Menus
- Settings
- Settings Search
- Color Themes
- Settings Terminal and Automation
- Settings Files
- Updates
- Status Bar and Help
- Notifications
- Memory Use
- Clear Cache
- MCP and CLI
- Git Mergetool
- Keyboard Shortcuts
- Keyboard Shortcuts Editor
- Troubleshooting
- Troubleshooting Git
Developers
- Developer Guide
- Architecture
- Project Layout
- Backend
- How Folder Watching Works
- Folder Watching Bugs We Fixed
- How Workspace Files Work
- How the Preview Scheme Works
- Backend Services
- How Terminal Features Work
- Terminal Bugs We Fixed
- Frontend
- How the Rich Markdown Editor Works
- Rich Markdown Bugs We Fixed
- Git Menu Links
- Menu Keys and Routing
- Frontend Modules
- Blame Bugs We Fixed
- Project Color And Title Bar
- One Diff View
- Diff Bugs We Fixed
- Merge Tool Layouts
- Merge Tool Bugs We Fixed
- Color Theme Bugs We Fixed
- How the Connected Diff Works
- Rounded Panels Bugs We Fixed
- Update Bugs We Fixed
- Status Bar Bugs We Fixed
- MCP and CLI Bugs We Fixed
- Repository Actions Bugs We Fixed
- How the Changes Tab Works
- CodeMirror Patterns
- How the Cursor Works
- How Editor Features Work
- How the Path Bar Works
- Commands and Events
- Settings Reference
- Commands Workspace and Changes
- Commands Branches and Remotes
- Commands History and Extras
- Commands App and Tools
- Testing
- Test Suites
- Debugging
- Debugging with MCP
- Measuring Setting Memory
- How Terminal Memory Is Measured
- How Markdown Diagrams Work
- Releases and CI
- Publishing the Wiki
- Versioning and Changelog
- Browser Version Packages
- Browser Release Checks
- Docker Image
- Platforms and Signing
- Windows Support
- Windows Bugs We Fixed
- Windows MCP and CLI
- Docs and Screenshots
- UI Library
- UI Library MCP
- UI Library Bugs
- UI Library Migration
- Contributing
How features work
- Welcome screen
- Workspaces and folders
- Files panel
- File operations
- File icons
- Editor and tabs
- Pin, reorder and wrap tabs
- Single tab title
- Split editor
- New File and unsaved changes
- Unload hidden tabs
- Editing code
- Code appearance
- Markdown editor
- Image and PDF preview
- Search Everywhere
- Recent Files
- Navigation Bar
- Find and replace
- Changes and commits
- Sign-in prompts
- Commit box layout
- Repository actions
- Commit options
- Ignoring files
- Diffs
- Inline diffs
- Staging view
- Revert a change
- Resolving conflicts
- Merge tool
- Blame
- History and log
- Merge commits
- Commit tabs
- Branches and tags
- Branches popup
- Remotes
- Stashes
- Shelf
- Git menu
- Git dialogs
- Interactive rebase
- Worktrees
- AI agents
- AI usage
- Keep computer awake
- AI tasks
- Submodules
- Git LFS
- GitHub account
- Git Console
- Back and Forward
- Integrated terminal
- Scripts tool window
- Menu bar
- Settings
- Search in Settings
- Color themes
- Rounded panels
- Updates and release channels
- Status bar and help links
- Notifications
- Memory readout and memory log
- Clear Cache
- MCP server and command line tool
- git mergetool mode