Skip to main content
Skip to content
Docs/Overview

Developer Overview

Welcome to Ascendara's developer documentation. This guide covers the application architecture, codebase structure, and everything you need to contribute or build integrations.

Architecture Overview

Ascendara is an Electron + React app. The React renderer talks to the Electron main process through a preload bridge, and the main process runs native helper tools for heavy or platform-specific work:

Diagram
┌─────────────────────────────────────────────────────────────────┐
│                        Renderer Process                         │
│   React 19 · Vite · Tailwind CSS · shadcn/ui · Framer Motion    │
│   src/pages · src/components · src/services · src/context       │
└────────────────────────────────┬────────────────────────────────┘
                                 │ window.electron (contextBridge)
                       electron/preload.js
                                 │ ipcRenderer.invoke / events
┌────────────────────────────────┴────────────────────────────────┐
│                          Main Process                           │
│  electron/app.js — lifecycle, tray, local server, protocol      │
│  electron/modules/ — settings, downloads, games, updates,       │
│    local index, retro, proton, ludusavi, security, recovery …   │
└────────────────────────────────┬────────────────────────────────┘
                                 │ child processes
┌────────────────────────────────┴────────────────────────────────┐
│                         Helper Binaries                         │
│  Downloader, GameHandler, CrashReporter (Rust)  ·               │
│  TorrentHandler, NotificationHelper, LanguageTranslation        │
│  (Python)  ·  Highball (macOS, Apple Silicon)                   │
│  AchievementWatcher (Node.js)  ·  Ludusavi, SteamCMD (external) │
└─────────────────────────────────────────────────────────────────┘

In packaged builds, the renderer is served from a local HTTP server at http://localhost:46859. In development it's served by Vite at http://localhost:5173. The local server also proxies a few third-party APIs (TorBox, KHInsider, FLiNG) for the renderer.

Core Components

Main Process (electron/)

FilePurpose
app.jsEntry point: window creation, tray, local server, protocol registration, app lifecycle
preload.jsExposes the window.electron API to the renderer
modules/index.jsLoads modules; installs the IPC security guard first; lazy-loads non-critical modules
modules/config.jsApp version and branch, platform detection, paths, helper paths
modules/settings.jsSettingsManager: loads, saves, and encrypts settings
modules/security.jsRejects IPC calls that don't come from Ascendara's own window
modules/downloads.jsStarts the downloader and torrent handler, tracks progress, retries, queue
modules/games.jsLibrary, game launching, executables, shortcuts, assets
modules/local-refresh.js, community-index.js, index-relay.jsLocal game index sync, covers, and index relay
modules/launcher-discovery.js, launcher-import.jsImporting games from other launchers
modules/retro/Ascendara Retro library, scanning, catalogue, launching, saves
modules/proton.js, umu-database.js, wine-setup.jsLinux and macOS compatibility layers
modules/ludusavi.jsSave backup and restore
modules/updates.js, install-update.jsApp updates and branch switching
modules/recovery.jsSettings recovery points and version rollback
modules/protocol.jsascendara:// URL handling
modules/discord-rpc.jsDiscord Rich Presence
modules/system.jsSystem info, drive space, dependencies, Defender exclusions

See Project Structure for the full list.

Renderer Process (src/)

DirectoryPurpose
src/pages/Pages, including Big Picture (big-picture/) and Ascend (ascend/)
src/components/Reusable components and shadcn/ui primitives (ui/)
src/services/Business logic and external APIs (Firebase, game info, downloads, TorBox, …)
src/context/React context providers (auth, language, settings, theme, search, tour)
src/hooks/Custom React hooks
src/lib/Utility functions
src/translations/Language files (en.json is the source)

Helper Binaries (binaries/)

ToolLanguagePurpose
AscendaraDownloaderRustDownload, extract, verify, and install games (including Gofile, file hosts, and torrents)
AscendaraGameHandlerRustLaunch games, track playtime, Discord RPC, backups on close
AscendaraTorrentHandlerPythonOlder qBittorrent torrent handler; torrents now download in the Downloader
AscendaraNotificationHelperPython (PyQt6)Desktop and achievement notifications
AscendaraLanguageTranslationPythonTranslates the UI into extra languages
AscendaraCrashReporterRust (FLTK)Error reporting window
AscendaraAchievementWatcherNode.jsWatches achievement files
AscendaraLocalRefreshPythonGame index scraper (not shipped with the app)

IPC Communication

The renderer calls the main process through the API exposed by preload.js:

javascript
// Renderer (React)
const settings = await window.electron.getSettings();
await window.electron.downloadFile(link, game, online, dlc, isVr, updateFlow, version, imgID, size, additionalDirIndex, gameID);

// Main process (electron/modules)
ipcMain.handle("get-settings", () => settingsManager.getSettings());
ipcMain.handle("download-file", async (event, link, game, ...) => { ... });

See the IPC Reference for the available methods and events.

Data Flow

Download Flow

Diagram
User clicks download
        │
        ▼
Renderer: window.electron.downloadFile(...)
        │ IPC: download-file
        ▼
Main: create game folder + {game}.ascendara.json,
      spawn AscendaraDownloader (or TorrentHandler for magnets)
        │
        ▼
Helper: transfer → extract → verify → install,
        writing progress to downloadingData in {game}.ascendara.json
        │
        ▼
Renderer: Downloads page polls window.electron.getDownloads()
          every second; the main process reads downloadingData
          from each game's {game}.ascendara.json

Game Launch Flow

Diagram
User clicks Play
        │
        ▼
Renderer: window.electron.playGame(game, isCustom, backupOnClose, ...)
        │ IPC: play-game
        ▼
Main: resolve executable and launch commands;
      on Linux add Proton/UMU/Wine runner arguments;
      spawn AscendaraGameHandler; update Discord RPC; hide window
        │
        ▼
GameHandler: launch game, track playtime and launch count,
             launch trainer, run Ludusavi backup on exit
        │
        ▼
Main: game-closed event → show window, reset Discord RPC

Development Mode Limitations

When running from source (yarn start):

  • Games can't be launched.
  • Ascend features are disabled unless you configure Firebase credentials.
  • Protected API endpoints (such as reports, ratings, and authenticated requests) may reject requests, because source builds don't include the private request-signing secret.

See Building from Source for details.

TopicDescription
Build from SourceSet up your development environment and build the app
Release AutomationHow official releases are built, signed, and published
Project StructureCodebase walkthrough
System DesignSettings, data files, updates, protocol, security
IPC ReferenceThe window.electron API
Debrid ProvidersThe debrid service and provider adapters
Tech StackTechnologies and dependencies
Creating the ToolsBuilding the helper binaries
Webview DevelopmentAscendara Companion
ContributingHow to contribute to Ascendara

Getting Help