Skip to content
investiDocs

Desktop app

The Investi desktop shell for macOS and Windows: what it loads, investi:// deep links, notifications, security, and current release status.

On this page

The Investi desktop app is a Tauri 2 shell around the web app. It opens your Investi deployment in one native window and adds investi:// deep links and native notifications. It has no research UI of its own. Signed releases are published for macOS and Windows, and /downloads always links to the latest one.

Status#

Item State
macOS universal build (Apple silicon and Intel) Published since 0.1.0 (November 2, 2026). Signed with a Developer ID, notarized by Apple and stapled. Requires macOS 11 or later.
Windows installer (x64) Published since 0.1.0. Not code-signed yet, so Windows SmartScreen warns before it runs, and the downloads page says so. Requires Windows 10 or later.
Automatic updates Release builds include the updater, which checks once at startup. Each release ships signed update files and a latest.json manifest.
Chrome Web Store listing None. Install the extension in developer mode (see Chrome extension).

Releases are published to the public VirSanghavi/investi-releases repository with a SHA256SUMS.txt file, and only after a CI job has verified notarization and the update signatures. You can also keep using Investi in any modern browser; the web app is the same.

Downloads page#

/downloads decides what to show at request time, from two inputs:

  1. The release status file (apps/desktop/release-status.json), bundled into the web app at build time. For each platform it records the minimum OS, the architecture, whether builds are signed (and notarized, for macOS), an optional explicit artifact, and a file name pattern.
  2. The latest published GitHub release of the releases repository named in that file, fetched from the GitHub API with a 4 second timeout and cached for 10 minutes.

A platform shows a download button only when one of these holds:

  • The latest GitHub release is published (not a draft) and has an asset whose name matches the platform's pattern (Investi_<version>_universal.dmg for macOS, Investi_<version>_x64-setup.exe for Windows). Only https://github.com/ download links are accepted. Releases are published only after a CI job verifies notarization.
  • Or the status file names an explicit https artifact. For macOS that counts only when the file also marks the build signed and notarized.

Anything else, including a private repository, a 404, a timeout or malformed data, shows Coming soon with "No macOS build has been published yet" (or Windows). The status file sets artifact to null for both platforms, so the buttons come from the published GitHub release.

When a build is available, its card shows the file name, size and the start of its SHA-256 checksum, taken from the release's SHA256SUMS.txt or GitHub's own digest. A Windows build without code signing carries a notice that SmartScreen may warn, and to choose More info, then Run anyway.

The page also detects your OS and puts that card first. On a phone or tablet it says the desktop app needs a Mac or Windows computer and that the web app works in your phone's browser. Local development builds are never offered.

Which URL it loads#

The app resolves your Investi origin when it starts. First match wins:

  1. INVESTI_DESKTOP_URL in the environment when the app starts
  2. INVESTI_DESKTOP_URL set when the app was built
  3. http://localhost:3100

Only http and https URLs with a host are accepted, and only the origin is kept; any path is dropped.

Before loading, the app opens a TCP connection to the host with a 1.5 second timeout. If it connects, the window opens on /home. If it does not, the app shows a bundled offline page with the URL, the error and a Retry button. An HTTP error from a reachable server still loads, and the web app renders it.

The window remembers its size and position. A second launch, or a deep link while the app is running, focuses the existing window instead of opening another.

Menu item Shortcut Action
Go, Reload Cmd+R (Ctrl+R on Windows) Recheck reachability and reload the current page
Go, Home Cmd+Shift+H (Ctrl+Shift+H) Open /home
Go, Open in Browser Cmd+Shift+O (Ctrl+Shift+O) Open the current page in your default browser

Back and Next buttons sit in the app's top bar, left of the search box, on every screen (in the browser too). They are the page history: Back returns to the previous screen, Next goes forward again, and each is dimmed when there is nowhere to go.

Swipe to go back or forward, as in Chrome: a two-finger swipe left or right on a Mac trackpad (from 0.1.3), or a swipe from the screen edge on a Windows touch screen. It moves through the pages you visited in the app, never outside your Investi.

The app registers the investi URL scheme. A deep link becomes a path on your configured origin, so a link can never point the window at another site.

Link Opens
investi:// or investi://home /home
investi://research/SPXC /research/SPXC
investi://portfolio /portfolio
investi://discover /discover
investi://history /history
investi://analytics /analytics
investi://settings /settings
investi://calendar /calendar
investi://markets /markets
investi://notebook /notebook

The scheme and route names are case-insensitive, and a trailing slash is allowed. Research tickers are upper-cased and must be 1 to 10 characters: they start with a letter, then letters or digits, with single . or - separators (for example BRK.B or BF-B).

Everything else is rejected and logged:

  • Unknown routes and extra path segments
  • Empty segments, . and .., or any segment starting with .
  • Any character other than ASCII letters, digits, /, . and -. This rejects % escapes, ? queries, # fragments, @, :, backslashes, whitespace and non-ASCII text.
  • Links longer than 128 characters

Note: On macOS, the operating system hands the app a link that has already been parsed, which resolves dot segments first. investi://research/../settings therefore arrives as investi://research/settings and opens /research/SETTINGS. That is still an allowed route on your configured origin.

If your deployment is unreachable when a link arrives, the offline page shows, and Retry goes to the linked page. To try a link with the app running on macOS:

Shell
open 'investi://research/SPXC'

Notifications for web pages#

Pages on your configured origin get window.__TAURI__, so the web app can detect the desktop shell and send native notifications:

TypeScript
const tauri = (window as any).__TAURI__;
if (tauri?.notification) {
  const { isPermissionGranted, requestPermission, sendNotification } = tauri.notification;
  let granted = await isPermissionGranted();
  if (!granted) granted = (await requestPermission()) === "granted";
  if (granted) sendNotification({ title: "SPXC alert", body: "Crossed your 50-day moving average" });
} else if ("Notification" in window) {
  // regular browser path
}

Pages can also listen for deep links with tauri.event.listen("deep-link://new-url", ...) and read the link that launched the app with tauri.deepLink.getCurrent(). The shell already navigates the window for deep links, so the web app needs no code for them to work.

Note: No page in the Investi web app calls the notification API yet, so the desktop app does not send notifications today. The API above is available for when it does.

Security model#

  • Remote pages get three abilities. Your Investi origin can send notifications, listen for events, and read the launch deep link. It has no file system, shell, window control or other plugin access. This applies only to the main window and only to your exact configured origin.
  • The offline page is sandboxed. The bundled fallback page can call only the shell's two commands (show connection info and retry), and the remote site cannot call them. It runs under a strict Content Security Policy: no inline script, and scripts, styles and fonts only from the app bundle.
  • Navigation stays on your origin. The window loads only your configured origin and the bundled offline page. Other http, https and mailto links open in your default browser. Other schemes are blocked. target=_blank and window.open never create a second window: same-origin links open in the main window, others in your browser.
  • No broker credentials. Schwab sign-in runs in the web app and opens in your system browser, because it is on another origin. The app stores only its window size and position, plus the webview's normal cookie store for your Investi session.
  • Read-only, like the web app. The desktop app cannot place, change or cancel an order.