/desktop

Replit Desktop App

Primary LanguageTypeScript

Replit Desktop

Welcome to the Replit desktop app for MacOS, Windows, and Linux.

The app is developed using Electron and packaged and distributed using Electron Forge.

Development

To get started, clone this repository and run pnpm install to install dependencies.

From there, you can start the app by running one of the following commands:

# Start the app against replit.com (as the user will see it)
pnpm start

# Start the app against a local dev server running repl-it-web (useful for testing local web changes that may affect the app)
pnpm start:local

# Start the app against staging.replit.com (useful for testing changes that may affect the app on staging)
pnpm start:staging

If you need to build a production version of the app, you can run:

pnpm make

You can then launch a packaged version of the app (needed to test certain features like auto-updating) by running the outputted binary locally (e.g. on an M1 Mac: ./out/Replit-darwin-arm64/Replit.app/Contents/MacOS/Replit).

To test your changes on other platforms, we recommend using a Virtual Machine host like UTM.

API Versioning

The Electron app communicates with the web frontend through the replitDesktop global object defined in src/preload.ts. As we develop both applications, this API has to be able to adapt, but at the same time can't break existing clients. The main failure mode we're trying to avoid is someone opening an older version of the Electron app and loading a newer version of the web client which requires a new API that's not supported by the old Electron client.

We're following a set of principles inspired by protobuf versioning:

  • don't remove the existing APIs
  • don't modify existing API call signatures
  • adding new APIs in the Electron app is ok, in the web client these should be optionally typed, and checked for existence dynamically (if ('logout2' in replitDesktop) { ... })

Deeplinking

The app supports deeplinks with the replit protocol which can be used to open specific pages or flows directly, launching the app if it's not already running.

The following deeplinks are currently supported:

  • replit://home: Opens the desktop app home page in the focused window (or a new window if none are open).
  • replit://new: Opens a new window which launches the Repl creation flow.
    • Optionally accepts a language string param which prefills the new Repl modal with that language's template (defaults to Python).
  • replit://authComplete: Completes the authentication flow which is triggered by the app during the login process, which redirects to the browser to generate a valid auth token that can be exchanged in order to authenticate the user associated with the browser's session. No-op if the user is already logged in.
    • Requires an authToken string param which represents a valid auth token generated by the repl-it-web server that is necessary to complete the authentication process.
  • replit://repl/@:username/:slug: Opens the Repl associated with that username and slug in the focused window (or a new one if none are open).

Release

To publish a new release of the app, run the release script like so:

pnpm release $version

where version is either a semver release keyword like major, minor, or patch, or an exact version like v1.0.0. While you can pass in exact versions, it's recommended to use semver keywords in most cases.

This will trigger a GitHub workflow that builds the artifacts for each platform and uploads them to a new Release by pushing a tagged commit to main.

Note that the Release will be in a draft state until you manually publish it. Make sure you add release notes to describe what changed since the last published version as they will be displayed to users when they download updates.

Before you run the script, make sure that the GH_TOKEN environment variable is a valid fine-grained personal access token with read access to metadata and read/write access to actions and code in order for the publish process to succesfully push the final build artifacts (exe, dmg, etc) from CI. You can view and update it via the repository settings as described here.

Auto Updates

The MacOS and Windows apps support auto-updating on start-up using the Electron autoUpdater module.

As part of the auto-updating process, the app will communicate with our Update Release Server which acts as a proxy for this repo's GitHub releases and exposes an API to fetch the latest artifacts for each platform.

Code Signing

As part of the Release process, we sign the MacOS and Windows apps according to the instructions here.

This is done to verify that the app comes from us and to prevent users from seeing warnings when installing the app. See instructions on how to sign for each platform below:

MacOS

To sign the app on MacOS, you need to set the APPLE_ID, APPLE_PASSWORD, and APPLE_TEAM_ID environment variables before you run pnpm make. Those are accessible in 1Password.

Alternatively, if you are a member of the company's Apple Developer Team, you can use your own Apple ID and app-specific password.

Windows

To sign the Windows app, you need to set the WINDOWS_CERTIFICATE_FILE and WINDOWS_CERTIFICATE_PASSWORD environment variables before you run pnpm make.

To avoid leaking the certificate itself, we generate it from a Base64 encoded string rather than committing it to git. You can find the encoded certificate and the certificate password in 1Password.

You can view and download the certificate itself by visiting the Comodo SSL Store Certpanel dashboard and logging in with the credentials found in 1Password.

Note that to recreate the pfx file (which is what's ultimately needed to sign the app) from the cer or crt file that you download from the Certpanel dashboard, you will need to generate it by via openssl by following the instructions here. To do so, you will need our private key (also in 1Password) as well as the intermediate certificates that Comodo provides.

CI

We sign the app in CI as part of the build and release process when publishing a new release. Make sure that the above env vars (APPLE_* and WINDOWS_*) remain valid credentials and are kept up to date in the repository secrets settings used by GitHub actions otherwise the app will not get correctly signed on subsequent releases.