Skip to main content
The desktop application is built using Electron with Svelte 5, and packaged with electron-builder for cross-platform distribution.

Prerequisites

Before building the desktop app, ensure you have:
  • Node.js 18+ or Bun 1.0+
  • Go 1.25+ (for building the streaming server binary)
  • Git
  • Platform-specific build tools:
    • Windows: Visual Studio Build Tools or Windows SDK
    • macOS: Xcode Command Line Tools
    • Linux: Standard build tools (build-essential on Debian/Ubuntu)

Build Configuration

The build configuration is defined in raffi-desktop/package.json under the build key:
{
  "build": {
    "appId": "al.kaleid.raffi",
    "productName": "Raffi",
    "directories": {
      "buildResources": "build",
      "output": "release"
    },
    "files": [
      "dist/**/*",
      "electron/**/*",
      "package.json"
    ],
    "asar": true
  }
}

Development Build

To run the desktop app in development mode:
1

Navigate to desktop directory

cd raffi-desktop
2

Install dependencies

npm install
3

Run development server

This command builds the server binary and starts Electron:
npm run electron:dev
The electron:dev script runs:
  • Server build (npm run server:build)
  • Vite dev server on http://localhost:5173
  • Electron with NODE_ENV=development
4

Run Electron only (optional)

If the server binary is already built:
npm run electron:dev:only

Production Build

Build Process

The production build process involves three stages:
1

Build the streaming server

The server:build script runs build_binary.cjs, which compiles the Go server for your platform:
# Outputs: electron/decoder-windows-amd64.exe
go build -ldflags="-s -w -extldflags '-static'" \
  -tags=sqlite_omit_load_extension \
  -o ../raffi-desktop/electron/decoder-windows-amd64.exe
2

Build the frontend

The build script compiles the Svelte app using Vite:
npm run build
This outputs the compiled frontend to the dist/ directory.
3

Package with electron-builder

Run the complete build and packaging process:
npm run dist
This runs all three steps: server:build, build, and electron-builder.

Platform-Specific Builds

Windows

Build Targets:
  • NSIS installer (.exe)
  • MSI installer (.msi)
Configuration:
{
  "win": {
    "target": ["nsis", "msi"],
    "icon": "build/icons/icon.ico",
    "extraResources": [
      {
        "from": "electron/decoder-windows-amd64.exe",
        "to": "decoder-windows-amd64.exe"
      }
    ]
  }
}
Output Location: raffi-desktop/release/ Artifacts:
  • Raffi-Setup-{version}.exe - NSIS installer
  • Raffi-{version}.msi - MSI installer

macOS

Build Targets:
  • DMG disk image
  • ZIP archive
Configuration:
{
  "mac": {
    "target": ["dmg", "zip"],
    "icon": "build/icons/icon.icns",
    "category": "public.app-category.video",
    "extraResources": [
      {
        "from": "electron/decoder-aarch64-apple-darwin",
        "to": "decoder-aarch64-apple-darwin"
      },
      {
        "from": "electron/decoder-x86_64-apple-darwin",
        "to": "decoder-x86_64-apple-darwin"
      }
    ]
  }
}
Output Location: raffi-desktop/release/ Artifacts:
  • Raffi-{version}.dmg - Disk image
  • Raffi-{version}-mac.zip - ZIP archive
  • Universal binary support (both ARM64 and x64 server binaries included)

Linux

Build Targets:
  • Debian package (.deb)
  • AppImage (.AppImage)
  • RPM package (.rpm)
Configuration:
{
  "linux": {
    "target": ["deb", "AppImage", "rpm"],
    "icon": "build/icons",
    "category": "Video",
    "extraResources": [
      {
        "from": "electron/decoder-x86_64-unknown-linux-gnu",
        "to": "decoder-x86_64-unknown-linux-gnu"
      }
    ]
  }
}
Output Location: raffi-desktop/release/ Artifacts:
  • Raffi-{version}.deb - Debian package
  • Raffi-{version}.AppImage - Universal Linux package
  • Raffi-{version}.rpm - Red Hat package

Build Output Structure

After running npm run dist, the release/ directory contains:
release/
├── Raffi-{version}.{platform-extension}  # Main installer/package
├── Raffi-{version}.{platform-extension}.blockmap  # Update deltas
├── latest.yml / latest-mac.yml / latest-linux.yml  # Auto-update metadata
└── builder-debug.yml  # Build configuration used

File Associations

The desktop app registers handlers for common video formats:
  • .mp4 - MP4 Video
  • .mkv - Matroska Video
  • .avi - AVI Video
  • .webm - WebM Video
  • .mov - QuickTime Video
These associations are configured in the fileAssociations section of the build config.

ASAR Packaging

The app uses ASAR archives (asar: true) to package the application code, with specific files unpacked:
{
  "asarUnpack": [
    "node_modules/**/*.node",
    "node_modules/**/prebuilds/**"
  ]
}
This ensures native modules work correctly while keeping the package size optimized.

Publishing

The app is configured to publish releases to GitHub:
{
  "publish": {
    "provider": "github",
    "owner": "kaleidal",
    "repo": "raffi"
  }
}
Built-in auto-updater checks for new releases and downloads delta updates when available.

Build docs developers (and LLMs) love