Desktop Build Guide

Desktop Build Guide

The following files were used as context for generating this wiki page:

Purpose and Scope

This document covers building the WSHawk Desktop application from source, including compiling the Python sidecar binary, packaging the Electron app, and the CI/CD pipeline that produces platform-specific installers.

For the Desktop architecture, see Desktop Application Architecture. For the Desktop features, see Desktop Advanced Features.

Sources: docs/DESKTOP_V3_GUIDE.md:700-900


Prerequisites

System Requirements

| Requirement | Version | Purpose | |---|---|---| | Node.js | 18+ (20 recommended) | Electron runtime and build tools | | Python | 3.8+ (3.11 recommended) | Scanner engine and sidecar compilation | | npm | 9+ | Dependency management | | pip | 21+ | Python dependency management | | Git | 2.25+ | Source control |

Platform-Specific Requirements

| Platform | Additional Dependencies | |---|---| | Linux | libarchive-tools (for .pacman builds), build-essential | | macOS | Xcode Command Line Tools | | Windows | Visual Studio Build Tools (for native modules) |


Build Process Overview

The build has three sequential stages:

graph LR
    A["Stage 1:<br/>Compile Python<br/>Sidecar"] --> B["Stage 2:<br/>Prepare Desktop<br/>Assets"]
    B --> C["Stage 3:<br/>Build Electron<br/>Installer"]

    style A fill:#16213e,stroke:#0f3460,color:#fff
    style C fill:#1a1a2e,stroke:#e94560,color:#fff

Stage 1: Compile Python Sidecar

Install Python Dependencies

# Clone the repository
git clone https://github.com/regaan/wshawk
cd wshawk

# Install WSHawk as editable package (pulls in all dependencies)
pip install -e .

# Install PyInstaller
pip install pyinstaller

# Install extra dependencies needed by the sidecar
pip install uvicorn fastapi python-socketio dnspython python-whois cryptography pyyaml

Compile with PyInstaller

pyinstaller wshawk-bridge.spec

This produces a standalone binary:

  • Linux/macOS: dist/wshawk-bridge
  • Windows: dist/wshawk-bridge.exe

The wshawk-bridge.spec File

The spec file is a Python script that tells PyInstaller exactly what to bundle:

Key Sections:

| Section | Purpose | |---|---| | Analysis() | Entry point (gui_bridge.py), module scanning | | hiddenimports | Modules PyInstaller can't detect automatically (80+ entries) | | excludes | Heavy modules to omit (tkinter, matplotlib, numpy, playwright) | | PYZ() | Compress Python bytecode | | EXE() | Build the final executable |

Hidden Imports

PyInstaller uses static analysis to detect imports. Dynamic imports (common in FastAPI, uvicorn, and socketio) are missed. The spec file explicitly lists them:

Server Framework:

'uvicorn', 'uvicorn.config', 'uvicorn.main', 'uvicorn.lifespan',
'uvicorn.protocols.http.httptools_impl',
'starlette', 'starlette.routing', 'starlette.middleware',
'fastapi', 'fastapi.routing', 'fastapi.middleware.cors',
'engineio', 'socketio',

Web Pentest Engines (all 22):

'wshawk.web_pentest.crawler',
'wshawk.web_pentest.fuzzer',
'wshawk.web_pentest.port_scanner',
'wshawk.web_pentest.dir_scanner',
# ... all 22 engines

Third-Party Libraries:

'dns', 'dns.resolver', 'dns.rdatatype',
'whois',
'cryptography', 'cryptography.x509',

Excluded Modules

Large dependencies that aren't needed in the sidecar are excluded to reduce binary size:

| Excluded | Size Saved | Reason | |---|---|---| | tkinter | ~15MB | No GUI needed (Electron provides it) | | matplotlib | ~30MB | No chart generation in sidecar | | numpy | ~25MB | Not used in production scanner | | pandas | ~40MB | Not used | | scipy | ~35MB | Not used | | pytest | ~5MB | Testing framework | | playwright | ~200MB | Optional, users install separately |

Total savings: ~350MB, reducing the binary from ~450MB to ~80-120MB.

Sources: wshawk-bridge.spec:1-100


Stage 2: Prepare Desktop Assets

Copy Sidecar Binary

# Create bin directory
mkdir -p desktop/bin

# Copy the compiled binary (Linux/macOS)
cp dist/wshawk-bridge desktop/bin/

# Copy the compiled binary (Windows)
cp dist/wshawk-bridge.exe desktop/bin/

Install Electron Dependencies

cd desktop
npm install

This installs:

  • electron (40.6.0) — Runtime
  • electron-builder (26.8.1) — Packaging tool
  • socket.io-client (4.8.3) — Real-time communication

Prepare Icons

mkdir -p build
cp src/assets/logo.jpg build/icon.png

For full icon support across platforms:

  • icon.png — Linux (any size, 256x256+ recommended)
  • icon.ico — Windows (use an ICO converter)
  • icon.icns — macOS (use iconutil or an ICNS converter)

Copy License

cp ../LICENSE LICENSE.txt

Sources: .github/workflows/build.yml:50-80


Stage 3: Build Electron App

Development Mode

cd desktop
npm start

This runs Electron in dev mode. The sidecar is spawned using python3 -m wshawk.gui_bridge from the project root (no binary needed).

Production Build

cd desktop
npx electron-builder --publish never

Build Targets

The package.json build section configures platform-specific outputs:

| Platform | Target | Output File | |---|---|---| | Linux | AppImage | dist/wshawk-3.0.1.AppImage | | Linux | pacman | dist/wshawk-3.0.1.pacman | | Linux | deb | dist/wshawk-3.0.1.deb | | Windows | NSIS | dist/WSHawk Setup 3.0.1.exe | | macOS | DMG | dist/WSHawk-3.0.1-arm64.dmg |

package.json Build Configuration

{
    "build": {
        "appId": "com.rothackers.wshawk",
        "productName": "WSHawk",
        "extraResources": [{
            "from": "bin",
            "to": "bin",
            "filter": ["**/*"]
        }],
        "linux": {
            "target": ["pacman", "AppImage", "deb"],
            "category": "Security"
        },
        "win": {
            "target": "nsis"
        },
        "mac": {
            "target": "dmg",
            "category": "public.app-category.developer-tools"
        }
    }
}

The extraResources section ensures the sidecar binary is bundled inside the app at resources/bin/.

Sources: desktop/package.json:37-87


CI/CD Pipeline

GitHub Actions Workflow

The .github/workflows/build.yml automates the entire build across all three platforms:

graph TB
    subgraph "Trigger"
        Tag["Push tag v*.*.*"]
        Manual["workflow_dispatch"]
    end

    subgraph "Build Matrix (parallel)"
        Linux["ubuntu-latest"]
        Windows["windows-latest"]
        Mac["macos-latest"]
    end

    subgraph "Build Steps"
        Checkout["Checkout code"]
        Setup["Node 20 + Python 3.11"]
        PipInstall["pip install -e . + extras"]
        PyInstaller["pyinstaller wshawk-bridge.spec"]
        CopyBin["Copy binary to desktop/bin/"]
        NpmInstall["npm install"]
        Build["electron-builder --publish never"]
        Upload["Upload artifacts"]
    end

    subgraph "Release"
        Download["Download all artifacts"]
        Release["Create GitHub Release"]
        Attach["Attach .exe .dmg .AppImage .pacman .deb"]
    end

    Tag --> Linux
    Tag --> Windows
    Tag --> Mac
    Manual --> Linux
    Manual --> Windows
    Manual --> Mac

    Linux --> Checkout
    Windows --> Checkout
    Mac --> Checkout
    Checkout --> Setup --> PipInstall --> PyInstaller --> CopyBin --> NpmInstall --> Build --> Upload

    Upload --> Download --> Release --> Attach

    style Tag fill:#16213e,stroke:#0f3460,color:#fff
    style Attach fill:#1a1a2e,stroke:#e94560,color:#fff

Platform-Specific Steps

| Step | Linux | macOS | Windows | |---|---|---|---| | Extra deps | apt install libarchive-tools | — | — | | Binary name | wshawk-bridge | wshawk-bridge | wshawk-bridge.exe | | Copy command | cp dist/wshawk-bridge desktop/bin/ | Same | cp dist/wshawk-bridge.exe desktop/bin/ | | Code signing | — | Ad-hoc (unsigned) | — | | Notarization | — | Skipped (no Apple ID) | — |

Triggering a Build

# Tag and push to trigger CI
git tag -a v3.0.1 -m "v3.0.1 release"
git push origin v3.0.1

# Or trigger manually via GitHub Actions UI

The fail-fast: false matrix strategy ensures all platform builds complete independently — a Linux failure won't cancel the Windows and macOS builds.

Release Job

After all three platform builds succeed, the release job:

  1. Downloads artifacts from all three build jobs
  2. Creates a GitHub Release tagged with the version
  3. Attaches all installer files to the release

Sources: .github/workflows/build.yml:1-150


Troubleshooting

Common Build Issues

| Issue | Cause | Fix | |---|---|---| | Spec file not found | wshawk-bridge.spec in .gitignore | Remove from .gitignore, git add -f wshawk-bridge.spec | | ModuleNotFoundError: uvicorn | Missing dependency in build env | pip install uvicorn fastapi python-socketio | | bsdtar not found (Linux pacman) | Missing libarchive-tools | sudo apt install libarchive-tools | | Cannot read 'channel' (electron-builder) | Missing repository in package.json | Add "repository": {"type": "git", "url": "..."} | | EPERM: chmod (Linux AppImage) | Snap/Flatpak restrictions | Run from native install, not sandboxed | | Disconnected in app | Sidecar binary not starting | Check binary exists in resources/bin/, check stderr logs |

Debugging the Sidecar

# Run the sidecar manually to see errors
./desktop/bin/wshawk-bridge

# Or in development mode
python3 -m wshawk.gui_bridge

If the sidecar crashes, the Electron console (Ctrl+Shift+I → Console tab) will show [Python Error] messages from stderr.

Verifying the Build

# Check binary is self-contained
file dist/wshawk-bridge
# Should output: ELF 64-bit LSB executable (Linux) or Mach-O (macOS)

# Check it starts
./dist/wshawk-bridge
# Should output: INFO: Uvicorn running on http://127.0.0.1:8080

# Check it's bundled in the app
ls desktop/dist/linux-unpacked/resources/bin/
# Should contain: wshawk-bridge

Sources: docs/DESKTOP_V3_GUIDE.md:700-900


Related Documentation

Sources: docs/DESKTOP_V3_GUIDE.md:1-960, .github/workflows/build.yml:1-150