Skip to content

[FEATURE]:Publish a fully portable Windows build of OpenCode Desktop #37893

Closed as not planned

Description

@wenceslas

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Description

OpenCode Desktop currently publishes a Windows NSIS installer, but no portable ZIP or portable executable.

A portable distribution would be useful for managed, air-gapped, or restricted Windows environments where users cannot install applications.

Requested packaging:

Publish a signed opencode-desktop-windows-x64-portable.zip or Electron Builder portable executable.
Allow the portable build to store its configuration, credentials, logs, cache, and application data in a data directory next to the executable.
Use PORTABLE_EXECUTABLE_DIR or a dedicated variable such as OPENCODE_PORTABLE_HOME.
Avoid registry entries, Start Menu shortcuts, and uninstall information in portable mode.
Disable or adapt automatic updates for the portable package.

A simple no-install executable would already be useful, but a fully self-contained profile would be preferable for USB, air-gapped, and enterprise deployments.

Related: #8087, where a portable ZIP was mentioned as an alternative to a signed installer.

Activity

  1. valentinobuttaro commented on Aug 31, 2026

    @valentinobuttaro

    Does it only work with a USB stick?
    Is it possible to run the .exe file from the desktop?

  2. overdoingism commented on Sep 17, 2026

    @overdoingism

    Proof-of-concept: full portability is achievable with ~5 lines of code (verified on v1.18.31)

    I built a working portable copy of OpenCode Desktop on Windows and wanted to share the findings, since they point at a very small official fix.

    What I verified

    1. The engine already honors XDG env vars on Windows.
    The bundled sidecar (out/main/chunks/node-*.js) uses standard xdg-basedir logic:

    xdgData   = env.XDG_DATA_HOME   || join(home, ".local", "share")
    xdgConfig = env.XDG_CONFIG_HOME || join(home, ".config")
    xdgCache  = env.XDG_CACHE_HOME  || join(home, ".cache")
    xdgState  = env.XDG_STATE_HOME  || join(home, ".local", "state")

    So opencode.db, auth.json, config, agents, plugins, rg.exe and models.json all follow these four variables — no code change needed on the engine side. (The in-tree TEST_ONBOARDING mode already redirects exactly these plus userData to a tmp root, so there's precedent.)

    2. The only missing piece is Electron's userData.
    In out/main/index.js:

    app.setPath("userData", join(app.getPath("appData"), appId)); // = %APPDATA%\ai.opencode.desktop

    Two gotchas I hit:

    • --user-data-dir does not help — the explicit setPath() overrides it.
    • Overriding the APPDATA env var also does not help — Chromium resolves Roaming AppData via the registry (SHGetKnownFolder), not the environment.

    So userData needs an actual code hook. Minimal change:

    app.setPath("userData",
      process.env.OPENCODE_USER_DATA || join(app.getPath("appData"), appId));

    3. Everything else is already env-var friendly.

    • Updater cache (%LOCALAPPDATA%\<appId>-updater) follows LOCALAPPDATA.
    • The sidecar is an in-process Electron utility (no external Node/Bun), so nothing else escapes the process environment.
    • No asar-integrity fuses are enabled in the shipped exe, and the single-instance lock is keyed on userData — a portable instance with its own profile runs fine alongside the installed one (verified).

    Proposed implementation

    A launcher script makes the whole folder movable:

    @echo off
    setlocal
    set "ROOT=%~dp0"
    set "XDG_DATA_HOME=%ROOT%data\opencode-data"
    set "XDG_CONFIG_HOME=%ROOT%data\opencode-config"
    set "XDG_CACHE_HOME=%ROOT%data\opencode-cache"
    set "XDG_STATE_HOME=%ROOT%data\opencode-state"
    set "OPENCODE_USER_DATA=%ROOT%data\desktop"
    start "" "%ROOT%\OpenCode.exe"
    endlocal

    Even better (and matching the OPENCODE_PORTABLE_HOME suggestion in this issue): support a single variable that the app expands internally, so users don't need to know about XDG at all:

    // main process
    const portableHome = process.env.OPENCODE_PORTABLE_HOME;
    if (portableHome) {
      for (const [k, sub] of Object.entries({
        XDG_DATA_HOME: "data", XDG_CONFIG_HOME: "config",
        XDG_CACHE_HOME: "cache", XDG_STATE_HOME: "state",
      })) process.env[k] ??= join(portableHome, sub);
    }
    app.setPath("userData", portableHome ? join(portableHome, "desktop") : /* existing */);

    Then the launcher is one set + a start. (I verified the multi-variable variant end-to-end: 3.2 GB tree on a USB-style path, running in parallel with an installed instance, all state — including the SQLite db and engine logs — landing next to the exe.)

    Edge cases worth deciding for an official build

    • Auto-updater: with env redirection the updater cache moves into the portable folder and NSIS in-place updates replace files next to the exe (works). Still, consider a flag to disable auto-update or switch to zip-based updates in portable mode, as requested.
    • Deep links: opencode:// is registered by the installer pointing at the install path; in portable mode it should be registered per-machine on first launch (HKCU) or via an explicit option.
    • Air-gapped first run: the engine downloads rg.exe + models.json into XDG_CACHE_HOME/opencode — fine for USB use, but worth documenting that pre-seeding that folder makes first run offline-capable.
    • SmartScreen: not a concern in practice — the exe is signed (Anomaly Innovations).

    Happy to share my patch script / test notes if useful.

    (Made by Qwen 3.8 27b Q5)

  3. RafaelAlt commented on Oct 12, 2026

    @RafaelAlt

    Hi everyone. I also wanted a portable version exactly like the win64 desktop, so I went ahead and had a simple script built for me that fetches and launches the latest opencode.exe I uploaded it to https://github.com/RafaelAlt/OCDP if anyone wanna take a look.

  4. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed request! To restate it: you'd like a portable Windows build of OpenCode Desktop (a ZIP or an electron-builder portable .exe) that keeps all its config, credentials, logs, cache and data in a folder next to the executable, adds no registry entries, Start Menu shortcuts or uninstall information, and turns off or adapts auto-updates. That would make it usable on managed, air-gapped and USB setups.

    Right now Desktop is published for Windows only as an NSIS installer, so this would be a new packaging option. Maintainers will consider it.

    Related issues and PRs:

  5. neriousy commented on Nov 12, 2026

    @neriousy
    Member

    Thanks for the suggestion. This isn't something we plan to build, so closing to keep the tracker focused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions