Skip to content
waveverPublic

About

CLI tool to detect desktop app tech stacks, code signatures, and notarization status. 桌面应用技术栈、代码签名与公证状态识别 CLI 工具。

Topics

Resources

Stars

85 stars

Watchers

0 watching

Forks

Repository files navigation

buildby logo

buildby

Is it Electron? Tauri? Native Swift? Find out in one command.
Detect any desktop app's tech stack, CPU architecture, code signature and notarization — macOS, Windows & Linux.

npm downloads stars License Platforms

Website · 简体中文 · Usage · 23 Tech Stacks

buildby demo

Side-by-side comparison (buildby vs / buildby pk)

Try it in 10 seconds

npx @wavever/buildby                        # browse and search installed apps
npx @wavever/buildby discord                # inspect one app
npx @wavever/buildby vs "ChatGPT" "Discord" # side-by-side comparison

Like it? npm i -g @wavever/buildby, then just run buildby.

Formerly desktop-app-build-by (deprecated). The command is still buildby. See CHANGELOG.md.

Install from source
git clone https://github.com/wavever/buildby.git
cd buildby
npm install
npm link

# Or run directly from source
node bin/buildby.js

Highlights

  • 🔍 23 stacks detected — Electron, Tauri, Flutter, Qt, CEF, React Native, .NET, JVM, Unity, Godot… or Native.
  • 🧬 Architecture & versions — arm64 / x86_64 / universal, plus Electron, Flutter, and Qt versions.
  • 🔒 Trust check — developer, Team ID, Apple notarization, Hardened Runtime, Authenticode.
  • ⚡ Fast & safe — pure-JS binary header parsing, no admin rights, cached batch scans.
  • 📤 Export anywhere — --json, --md, --csv for scripts and reports.

Screenshots

Inspect a single app Scan all installed apps Filter by tech stack

Usage

App Browser & Search (Default)

Running buildby with no arguments in a terminal launches the app browser:

buildby                  # Launches app browser
buildby -i               # Search & select mode
buildby interactive      # Same browser, as a subcommand
  • Keyboard Navigation: Use ↑ / ↓ arrows to navigate through installed apps, Enter to select and inspect an app in detail.
  • Instant Search: Type any keyword to filter apps in real time.
  • Scrollable Viewport: Smoothly scroll through all installed apps with pagination indicators (▲ / ▼ and [index/total]).
  • Quick Exit: Press q or Ctrl+C to quit anytime.

Compare two apps (vs / pk)

Compare the tech stack, binary architecture, size ratio, and code signatures of two apps side by side:

# Compare specific apps directly
buildby vs "ChatGPT" "Amphetamine"
buildby pk "WeChat" "Discord"
buildby compare "Visual Studio Code" "Sublime Text"

# Or enter multi-select comparison mode
buildby vs
# → Browse with ↑/↓, press Space to select 2 apps, press Enter to compare!

Inspect a single app

buildby wechat
buildby discord
buildby "visual studio code"
buildby "clash verge"

Output example:

  ╭──────────────────────────────────────────────────────────────────────────╮
  │ 📦 Discord (v0.0.335)                                      macOS · arm64 │
  │ 📂 /Applications/Discord.app                                             │
  ├──────────────────────────────────────────────────────────────────────────┤
  │  CROSS-PLATFORM   ⚡ Electron                                            │
  │ Cross-platform desktop apps with web technologies (HTML/CSS/JS)          │
  │ 🌐 https://www.electronjs.org                                            │
  ├───────────────────────────────────┬──────────────────────────────────────┤
  │ 📋 Key Specifications             │ 🔒 Security & Trust                  │
  │   • Arch: Apple Silicon (arm64)   │   • Signature: ✓ Signed              │
  │   • Size: 375.4 MB                │   • Developer: Discord, Inc. (53Q6…  │
  │   • Version: 0.0.335              │   • Notarization: ✓ Apple Notarized  │
  │   • ID: com.hnc.Discord           │   • Hardened RT: ✓ Enabled           │
  ├───────────────────────────────────┴──────────────────────────────────────┤
  │ 🔍 Detection Evidence                                                    │
  │   • Electron Framework.framework                                         │
  │   • app.asar                                                             │
  ╰──────────────────────────────────────────────────────────────────────────╯

The Security & Trust section is only collected for single-app inspection (buildby <name> and --path). --all and --<stack> skip it so batch scans stay fast.

Scan all installed apps

buildby --all
buildby -a

Scans all apps in /Applications (macOS) or Program Files (Windows) and groups them by tech stack with a distribution chart.

--scan is still supported as a legacy alias for --all.

Batch scans use a local analysis cache. If an app's version and main executable fingerprint have not changed, BuildBy reuses the previous result so repeated scans are nearly instant.

buildby --all --no-cache   # Force a fresh analysis

Export Formats

Markdown Table (--markdown / --md)

Export results as a GitHub Flavored Markdown table, complete with tech stack metadata and an overall distribution summary:

buildby --all --md > installed-apps.md
buildby discord --md

CSV Table (--csv)

Export results to an RFC 4180 compliant CSV spreadsheet ready for Excel, Numbers, or data analysis:

buildby --all --csv > installed-apps.csv

JSON Output (--json)

Add --json to any inspection mode to get machine-readable output on stdout (update is an action command and has no JSON form). Progress and errors stay on stderr, so stdout is always safe to pipe.

buildby discord --json
buildby --all --json | jq '.summary.stacks'
buildby --electron --json | jq -r '.apps[].name'
JSON schema, field notes, and exit codes

Every mode returns the same envelope, so consumers never branch on shape:

{
  "schema": 1,
  "buildbyVersion": "1.5.0",
  "platform": "darwin",
  "query": { "mode": "app", "value": "calibre" },
  "apps": [
    {
      "name": "calibre",
      "stack": "python",
      "stackName": "Python (PyQt)",
      "variant": "PyQt",
      "category": "cross-platform",
      "confidence": "high",
      "evidence": ["Python.framework", "PyQt UI toolkit"],
      "bundleId": "net.kovidgoyal.calibre",
      "version": "7.22.0",
      "sizeBytes": 1052946432
    }
  ],
  "summary": null
}

Notes for consumers:

  • stack is the stable identifier — key on it, not on stackName. stackName is a display label and variant carries the sub-technology (PyQt, Rust · AppKit).
  • evidence is human-oriented and not a stable API. Do not parse it.
  • Sizes are raw bytes; no localized text appears in JSON output.
  • summary is populated for --all only; it is null elsewhere.
  • Signature and notarization are collected for single-app modes only, matching the report behaviour, so they are null under --all.
  • schema is versioned — check it before trusting field semantics.

Exit codes (applied under --json only, so existing usage is unaffected):

Code Meaning
0 At least one app matched
1 No apps matched (payload still valid, apps: [])
2 Error — unsupported platform, missing path, analysis failure

On error, stdout carries a parseable error object instead of apps:

{ "schema": 1, "error": { "code": "path_not_found", "message": "Path not found: /nope" } }

Configuration

BuildBy creates a default JSON config on first run, then reads it later. Batch scans honor cache and excludeApps.

Config paths and options
  • macOS/Linux/other: $XDG_CONFIG_HOME/buildby/config.json or ~/.config/buildby/config.json
  • Windows: %APPDATA%\buildby\config.json

On macOS, existing configs from ~/.buildby/config.json are copied to the new XDG path automatically when the new file does not exist.

You can also point to a custom config file with BUILDBY_CONFIG=/path/to/config.json; BuildBy will create that file with defaults if it does not exist.

{
  "cache": true,
  "excludeApps": [
    "Xcode",
    "com.apple.Safari",
    "/Applications/VMware Fusion.app"
  ]
}

cache: false disables the analysis cache by default. excludeApps removes matching apps from --all and per-stack scans; entries can be app names, Bundle IDs, or full paths. Single-app inspection still works for excluded apps.

"checkForUpdates": false skips the pre-command update prompt. The same opt-out is available as --no-update-check or BUILDBY_NO_UPDATE_CHECK=1.

Language

BuildBy follows your terminal or system language by default. To show English output without changing system language:

LC_ALL=en_US.UTF-8 buildby -a

You can also create an alias:

alias buildby-en='LC_ALL=en_US.UTF-8 buildby'

Filter by tech stack

buildby -e     # All Electron apps (--electron)
buildby -f     # All Flutter apps (--flutter)
buildby -t     # All Tauri apps (--tauri)
buildby -q     # All Qt apps (--qt)
buildby -j     # All JVM apps (--jvm)
buildby -c     # All CEF apps (--cef)
buildby -d     # All .NET / MAUI / WPF apps (--dotnet)
buildby -b     # All Chromium apps (--chromium)
buildby -W     # All NW.js apps (--nwjs)
buildby -r     # All React Native apps (--reactnative)
buildby -w     # All wxWidgets apps (--wxwidgets)
buildby -u     # All Unity apps (--unity)
buildby -n     # All native apps (--native)

Inspect a custom path

buildby --path /Applications/SomeApp.app
buildby --path "C:\Program Files\SomeApp"

Updates

In a terminal, buildby checks whether a newer release is published before executing your command:

  • Notification Box: If an update exists, a notification box is shown.
  • Keyboard Navigation: Use ↑ / ↓ or 1/2 to select Update now and continue or Skip for now, and press Enter (or q / Esc to skip).
  • Seamless Execution: When you choose update, buildby installs the release globally and immediately re-launches your original command using the new version.
  • Opt-out: Pass --no-update-check, set BUILDBY_NO_UPDATE_CHECK=1, or configure "checkForUpdates": false in config.json.
buildby update           # Check for a newer release and install it
buildby update --check   # Only report whether an update exists

update asks npm for the latest published version, so your own registry mirror, proxy and auth settings are respected. When the running copy is a git checkout or an npm linked build, it reports the path and stops instead of installing over it.

Because update is a subcommand, an app literally named "update" can no longer be inspected by name — use buildby --path for that.

Detected Tech Stacks

Stack Description Detection Method
⚡ Electron Node.js + Chromium Electron Framework.framework, app.asar, framework version extraction
🐦 Flutter Google's UI toolkit FlutterMacOS.framework, flutter_windows.dll, framework version
🌐 CEF Chromium Embedded Framework Chromium Embedded Framework.framework, libcef.dll
🌐 Chromium Built directly on Chromium .pak packs + V8 snapshot (Qt WebEngine excluded)
🟩 NW.js Node.js + Chromium (node-webkit) nwjs Framework.framework, app.nw
⚛️ React Native Facebook's React for desktop React.framework, hermes.dll
🦀 Tauri Rust + system WebView Tauri crate markers in binary, v1/v2 variant, WebView2Loader.dll
⚡ Neutralinojs Lightweight HTML/JS desktop app neutralino.js, neutralino.config.json, binary signatures
🐹 Wails Go + system WebView github.com/wailsapp/wails in binary
🔷 Qt C++ cross-platform Qt*.framework (incl. nested), Qt5Core.dll / Qt6Core.dll, Qt version
🟫 GTK GNOME widget toolkit libgtk-3/4.dylib, libgtk-3-0.dll
🧩 wxWidgets C++ wrapper over native widgets libwx*.dylib, wxmswXXu_*.dll
🧩 Sciter Embeddable HTML/CSS engine sciter.dll, libsciter.dylib, binary signatures
🎵 JUCE C++ audio apps and plug-in hosts JUCE v / juce:: markers in binary
🐍 Python py2app / PyInstaller / CPython __boot__.py, base_library.zip, Python.framework
☕ JVM Java/Kotlin/Scala jbr/, libjvm.dylib, .jar in lib/ app/ Java/
🟣 Compose Multiplatform Kotlin UI via Skia libskiko-macos-*.dylib, skiko-awt-runtime-*.jar
🔵 .NET Microsoft .NET / MAUI / WPF MonoBundle/, coreclr.dll, .dll files
🦅 Avalonia Cross-platform .NET UI Avalonia*.dll, libAvalonia*
🎮 Unity Unity game engine UnityPlayer.dll, Data/ layout
🎯 Unreal Engine Epic UE4 / UE5 Content/Paks/*.pak, Contents/UE5/
🤖 Godot Godot game engine *.pck archive + engine marker in binary
🖥️ Native Platform-native technologies Fallback; reports Swift / Objective-C / Rust / Go

Platform Support

Platform App Discovery Detection
macOS /Applications, ~/Applications Framework bundles, in-process Mach-O parser, Info.plist
Windows Program Files, Program Files (x86), AppData/Local/Programs PE header inspection, DLL signatures, directory structure
Linux /usr/share/applications, ~/.local/share/applications, Flatpak, Snap .desktop entries, ELF headers, shared library markers

How It Works

Detection is fast, secure, and purely file-system and binary header based — zero admin privileges required.

  1. Framework directory & DLL scan — check Contents/Frameworks/ (macOS), root directories (Windows/Linux), or linked libraries for known frameworks (Electron, Flutter, CEF, Qt, GTK, etc.).
  2. Binary header inspection — pure JavaScript streaming parser inspects Mach-O load commands (LC_LOAD_DYLIB), Universal/Fat binaries, PE architectures, and ELF headers with zero subprocess overhead.
  3. Resource file patterns — look for app.asar, flutter_assets, neutralino.js, app.nw, etc.
  4. Runtime & Framework versions — extracts runtime versions from Electron (package.json / version files), Flutter framework strings, and Qt dylibs.
  5. JVM & Game Engine detection — detect bundled JRE/JBR runtimes, .jar files, Unity Data, Unreal Engine pak files, and Godot pck archives.
  6. Metadata extraction — parse macOS Info.plist, Windows version resources, and Linux .desktop entries for display name, version, and bundle ID.
  7. Signature & notarization — invoke codesign -dv + spctl --assess on macOS, or PowerShell Get-AuthenticodeSignature on Windows, to surface developer, Team ID, publisher, and Apple notarization or Authenticode trust status.
  8. Smart caching — hashes binary fingerprints and versions so repeated batch scans run near-instantaneously.
  9. Native fallback — apps with no cross-platform framework signatures are classified as Native (Swift / Objective-C / Rust / Go / C++ / Win32).

Detection runs in priority order so the most distinctive signatures are checked first.

Requirements

  • Node.js >= 18
  • macOS, Windows, or Linux
  • macOS: Xcode Command Line Tools (for codesign and spctl signature inspection)
  • Windows: PowerShell on PATH (for Authenticode signature reading)
  • Linux: Standard FreeDesktop / XDG desktop environment

License

MIT

About

CLI tool to detect desktop app tech stacks, code signatures, and notarization status. 桌面应用技术栈、代码签名与公证状态识别 CLI 工具。

Topics

Resources

Stars

85 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages