# Insomnia API Client — Admin & Architecture Guide

This guide is for the people who deploy, secure, operate, extend, or contribute to Insomnia: platform engineers rolling it out to a team, security reviewers assessing its data-handling, and developers building on or hacking the codebase. It documents Insomnia's architecture, configuration surface, security model, build/release pipeline, internal module structure, and known technical debt — at a depth sufficient to reason about the app without reading the source yourself.

> [!NOTE]
> **Audience split.** The companion *User Guide* covers using the app and the `inso` CLI. This guide covers everything behind that surface: how it is built, how it stores and moves data, and how to operate and extend it.

---

## 1. Executive Summary

**Insomnia** is a cross-platform desktop **API client** built by **Kong** (Apache-2.0). It is an **Electron** application: a Chromium renderer running a **React** single-page app, paired with a Node.js **main process** that performs privileged work (native HTTP via **libcurl**, filesystem access, OAuth browser flows, Git operations). A companion CLI, **`inso`**, reuses the same core to run collections, tests, and linting headlessly.

| Attribute | Value |
|---|---|
| Product | Insomnia desktop API client (`insomnia` package `v12.5.1-alpha.0` at this commit) |
| Vendor | Kong, Inc. |
| License | Apache-2.0 |
| Runtime | Electron 41 (Chromium + Node.js), Node `>=24` / npm `>=11` for development |
| UI stack | React 18, React Router 7 (loaders/actions), React Aria Components, TailwindCSS |
| Networking | `@getinsomnia/node-libcurl` (native libcurl), `undici`, `ws`, `@grpc/grpc-js`, `socket.io-client` |
| Local store | NeDB (`@seald-io/nedb`) embedded NoSQL |
| Repo layout | npm-workspaces monorepo, 8 published/internal packages |
| Companion CLI | `inso` (`insomnia-inso`), Commander-based, packaged with `@yao-pkg/pkg` |
| Source scale | ~1,905 files, ~3.4M source chars at commit `bece185` (2026-06-05) |

**Architectural one-liner:** a renderer SPA holds UI state and the data layer; anything requiring OS or network privilege is delegated to the Electron main process over a typed IPC bridge; the same data/networking core is bundled into a standalone CLI.

---

## 2. Architecture

### 2.1 Process model

```text
┌──────────────────────────────────────────────────────────────┐
│ Electron Main Process (Node.js)                              │
│  • Window + menu management (window-utils, squirrel-startup) │
│  • Native HTTP via node-libcurl (curlRequest)                │
│  • OAuth browser flows (authorizeUserIn{Window,DefaultBrowser})│
│  • Git operations (isomorphic-git, fs-clients)               │
│  • Filesystem: secure/insecure read, writeFile, backups      │
│  • Spectral ruleset compile/bundle, importers, HAR export    │
│  • Plugin install/window, MCP, LLM config                    │
│  • IPC handler registry (src/main/ipc/main.ts)               │
└───────────────▲──────────────────────────────────────────────┘
                │  typed IPC bridge (ipcMainHandle / ipcMainOn)
                │  exposed to renderer via preload (entry.preload.ts)
┌───────────────┴──────────────────────────────────────────────┐
│ Renderer Process (Chromium) — React SPA                      │
│  • React Router 7 route tree = the entire feature surface    │
│  • NeDB data layer (requests, environments, workspaces, …)   │
│  • CodeMirror / Monaco editors for every input field         │
│  • Pre-request / after-response scripting sandbox            │
│  • Nunjucks template rendering                               │
└──────────────────────────────────────────────────────────────┘
```

- **Entry points:** `packages/insomnia/src/entry.main.ts` (main), `entry.preload.ts` (preload bridge / env injection), and the Vite-served renderer.
- **IPC bridge:** `src/main/ipc/main.ts` registers all `ipcMainHandle`/`ipcMainOn` channels. The renderer never touches libcurl, the filesystem, or Git directly — it calls a channel. A `services.invoke` channel multiplexes data-service calls.
- **Why this matters:** the privilege boundary is the IPC surface. Anything a renderer (and therefore a plugin or a malicious response-driven script) can do to the host must pass through a named, typed channel in `main.ts`.

### 2.2 Key IPC channels (the privilege surface)

| Channel | Responsibility |
|---|---|
| `curlRequest` | Send an HTTP request via native libcurl |
| `getAuthHeader` / `getOAuth2Token` | Compute auth headers / fetch & refresh OAuth2 tokens |
| `authorizeUserInWindow` / `authorizeUserInDefaultBrowser` / `onDefaultBrowserOAuthRedirect` | OAuth login flows |
| `database.*` / `services.invoke` | Data-model CRUD against NeDB |
| `secureReadFile` / `insecureReadFile` / `writeFile` / `readDir` / `readOrCreateDataDir` | Filesystem access |
| `parseImport` | Convert Postman/OpenAPI/cURL/WSDL/HAR → Insomnia resources |
| `bundleSpectralRuleset` / `refreshCompiledRuleset` / `deleteCompiledRuleset` | OpenAPI lint ruleset compilation |
| `generateCodeSnippet` / `getCodeSnippetTargets` | Code generation (httpsnippet) |
| `exportHarCurrentRequest` / `exportRequestsHAR` / `exportWorkspacesHAR` | HAR export |
| `createPlugin` / plugin window channels | Plugin lifecycle |
| `backup` / `restoreBackup` | Local data backup/restore |
| `writeResponseBodyToFile` | Persist response bodies |

> [!IMPORTANT]
> `secureReadFile` exists alongside `insecureReadFile` deliberately. The "secure" path enforces constraints; `insecure*` variants do not. Filesystem reach for scripts and the runner is further bounded by the **`dataFolders`** allow-list (settings, or CLI `-f`).

### 2.3 The renderer feature surface (React Router route tree)

Insomnia's feature inventory maps directly onto its React Router route tree (`packages/insomnia/src/routes`). The major route clusters:

| Route cluster | Feature |
|---|---|
| `auth.*`, `auth.{create,validate,reset,clear}-vault-key`, `auth.update-vault-salt` | Login/logout, account, **Vault** key lifecycle |
| `organization.$organizationId.*` | Organizations, members, collaborators, invites, roles, permissions |
| `…project.$projectId.*` | Projects, project CRUD, move, lint ruleset (refresh/update/delete) |
| `…workspace.$workspaceId.debug.*` | The **Debug** screen: request/folder CRUD, send, response history, **runner** |
| `…workspace.…spec.*` | **Design** documents: OpenAPI editing, generate request collection |
| `…workspace.…test.test-suite.*` | **Unit test** suites, run-all, test results |
| `…workspace.…mock-server.*` | **Mock servers** and mock routes |
| `…workspace.…environment.*` | Environment CRUD, set-active, set-active-global |
| `…workspace.…insomnia-sync.*` | **Cloud Sync**: snapshots, branches, pull/push/restore/rollback/merge |
| `git.*`, `git-credentials.*`, `git-provider.*` | **Git Sync**: clone/commit/push/fetch/branches/diff/stage |
| `import.{resources,scan}` | Import pipeline |
| `…workspace.…{cacert,clientcert}.*` | CA / client certificate management |
| `…workspace.…mcp.tsx`, `ai.*` | **MCP** client + AI features (commit-message/sampling generation) |
| `onboarding.*`, `settings.update`, `organization.$organizationId.storage-rules` | Onboarding, settings, storage policy |

> [!TIP]
> When auditing or extending Insomnia, start from the route tree. Each `*.tsx` route is a React Router **loader/action** pair — the `action` is the mutation entry point, which is the cleanest place to understand "what does this feature actually do."

### 2.4 Data layer and models

Data lives in an embedded **NeDB** database (in-memory with on-disk persistence) plus some `localStorage` and a file-backed fake-localStorage for window state. The model definitions live in `packages/insomnia-data/src/models` and are shared by the app and the CLI.

Full model inventory (each is a typed document with `init()` defaults and a service layer):

`ApiSpec`, `CaCertificate`, `ClientCertificate`, `CloudCredential`, `CookieJar`, `Environment`, `GitCredentials`, `GitRepository`, `GrpcRequest`, `GrpcRequestMeta`, `McpRequest`, `McpPayload`, `McpResponse`, `MockRoute`, `MockServer`, `OAuth2Token`, `Organization`, `PluginData`, `Project`, `ProjectLintRuleset`, `ProtoDirectory`, `ProtoFile`, `Request`, `RequestGroup`, `RequestGroupMeta`, `RequestMeta`, `RequestVersion`, `Response`, `RunnerTestResult`, `Settings`, `SocketIORequest`/`SocketIORequestMeta`/`SocketIOPayload`/`SocketIOResponse`, `Stats`, `UnitTest`, `UnitTestResult`, `UnitTestSuite`, `UserSession`, `WebSocketRequest`/`WebSocketRequestMeta`/`WebSocketPayload`/`WebSocketResponse`, `Workspace`, `WorkspaceMeta`.

> [!NOTE]
> The model hierarchy is **polymorphic by `parentId`** — every document points at its parent (request → request-group/workspace → project → organization). De-polymorphizing this database is an explicit roadmap item (see [§9](#9-technical-debt-and-roadmap)).

### 2.5 Networking

- **HTTP/REST** is sent by **native libcurl** (`@getinsomnia/node-libcurl`) via the `curlRequest` IPC channel — chosen for maximum control and debuggability of TLS, redirects, proxies, and HTTP versions. The full exchange is captured into a **timeline** (NDJSON), surfaced in the response pane and the CLI `--verbose` output.
- **gRPC** uses `@grpc/grpc-js` + `@grpc/proto-loader`, with `grpc-reflection-js` for server reflection.
- **WebSocket** uses `ws`; **Socket.IO** uses `socket.io-client`; **GraphQL** uses `graphql` + `codemirror-graphql`.
- Auth signing is computed in the main process: AWS v4 (`aws4`), OAuth 1 (`oauth-1.0a`), Hawk (`hawk`), ASAP (`httplease-asap`), plus basic/bearer/api-key/NTLM.

### 2.6 Templating and rendering

User input fields support **Nunjucks**-based template tags (`{{ ... }}`) resolved by `src/common/render.ts` and `src/templating`. Tags include dynamic values (UUID, timestamp, hashing, base64), prompts, and **response** tags that chain a value from one request into another. **liquidjs** is also present in the scripting environment.

### 2.7 Sync architecture

Insomnia has **two independent VCS implementations**:

1. **Git Sync** (`src/sync/git`): a real Git client built on **isomorphic-git** with a stack of pluggable filesystem clients (`mem-client`, `ne-db-client`, `routable-fs-client`, `project-routable-fs-client`, `fs-client`) and an HTTP client. It maps Insomnia documents onto files in your repo and supports clone/commit/push/pull/branch/diff. Providers (`src/sync/git/providers`) cover GitHub/GitLab via OAuth (`CustomProvider`, `GitRemoteProviderRegistry`).
2. **Cloud Sync** (`src/main/cloud-sync/core`): a bespoke `VCS` class with delta/merge logic (3-way merge, content hashing) for Insomnia's cloud backend, exposing branches, snapshots, pull/push/restore/rollback.

> [!TIP]
> These are genuinely separate code paths. A Git-Sync bug will not live in `cloud-sync/core` and vice-versa. The sync code is acknowledged by the maintainers as among the gnarliest in the repo ("sync code is spaghetti" — [§9](#9-technical-debt-and-roadmap)).

### 2.8 The `inso` CLI architecture

`inso` (`packages/insomnia-inso`) is **Commander.js**-based. It imports the renderer's `getSendRequestCallbackMemDb` (to reuse the database, Nunjucks templating, libcurl networking, and plugin hooks) and `insomnia-testing`'s `generate`/`runTestsCli`. Build/packaging:

1. `esbuild` transpiles `src` → `dist/index.js` (CommonJS).
2. `bin/inso` is a shell wrapper pointing at `dist/index.js` (development).
3. `@yao-pkg/pkg` produces a standalone `binaries/inso` executable (no Node required).

> [!WARNING]
> Per the maintainers' own notes, `inso` currently **bundles almost the entire renderer** (React components included) and stubs Electron to run in Node. This is a known abstraction problem that limits networking improvements — see the roadmap.

---

## 3. Requirements

### 3.1 End-user runtime

- **OS:** macOS, Windows, or Linux (64-bit).
- No separate runtime needed — Electron is bundled. The CLI binary is self-contained.
- Native module: the app ships a prebuilt `node-libcurl` matched to its Electron version.

### 3.2 Developer / build environment

| Requirement | Value |
|---|---|
| Node.js | `>=24` (see `.nvmrc`) |
| npm | `>=11` |
| Electron (build) | `41.0.3` |
| node-libcurl | `3.2.2` (electron target `41.0.3`, node target `24.14.0`) |
| Linux build deps | `libfontconfig-dev` (Debian/Ubuntu), `libcurl-devel` (Fedora) |
| Windows secure wrapper | MSYS2 + `mingw-w64-ucrt-x86_64-gcc` (`windres`, `g++`) |

> [!NOTE]
> A `flake.nix`/`shell.nix` is provided for a reproducible Nix dev shell.

---

## 4. Configuration Mastery

### 4.1 Settings reference (complete)

Settings are a `Settings` data-model document (`packages/insomnia-data` `settings.ts`). Defaults come from `init()`. This is the authoritative list.

| Setting | Type | Default | Meaning |
|---|---|---|---|
| `theme` / `lightTheme` / `darkTheme` | string | app defaults | Active / light / dark color theme |
| `autoDetectColorScheme` | bool | `false` | Follow OS light/dark |
| `autoHideMenuBar` | bool | `false` | Hide menu bar (Win/Linux) |
| `fontInterface` / `fontMonospace` | string\|null | `null` | UI / mono font overrides |
| `fontSize` | number | `13` | UI font size |
| `fontVariantLigatures` | bool | `false` | Enable ligatures |
| `editorFontSize` | number | `11` | Editor font size |
| `editorIndentSize` | number | `2` | Editor indent width |
| `editorIndentWithTabs` | bool | `true` | Indent with tabs |
| `editorKeyMap` | string | `default` | `default`/`vim`/`emacs`/`sublime` |
| `editorLineWrapping` | bool | `true` | Wrap long lines |
| `enableKeyMapForInlineTextEditors` | bool | `false` | Apply keymap to inline editors |
| `autocompleteDelay` | number (ms) | `1200` | Autocomplete popup delay |
| `nunjucksPowerUserMode` | bool | `false` | Edit raw template syntax |
| `showVariableSourceAndValue` | bool | `false` | Show variable source + value |
| `followRedirects` | bool | `true` | Follow 3xx |
| `maxRedirects` | number | `10` | Redirect cap |
| `timeout` | number (ms) | `30000` | Request timeout (`0`=none) |
| `preferredHttpVersion` | enum | `default` | `V1_0`/`V1_1`/`V2_0`/`V2PriorKnowledge`/`v3`/`default` |
| `validateSSL` | bool | `true` | Verify TLS on requests |
| `validateAuthSSL` | bool | `true` | Verify TLS on auth endpoints |
| `clearOAuth2SessionOnRestart` | bool | `true` | Drop OAuth2 session at startup |
| `maxHistoryResponses` | number | `20` | Responses kept per request |
| `maxTimelineDataSizeKB` | number | `10` | Timeline capture cap |
| `filterResponsesByEnv` | bool | `false` | Scope response history to env |
| `disableResponsePreviewLinks` | bool | `false` | Disable clickable links in previews |
| `disableHtmlPreviewJs` | bool | `false` | Disable JS in HTML preview |
| `proxyEnabled` | bool | `false` | Use a proxy |
| `httpProxy` / `httpsProxy` / `noProxy` | string | `''` | Proxy configuration |
| `useBulkHeaderEditor` | bool | `false` | Default to bulk header editor |
| `useBulkParametersEditor` | bool | `false` | Default to bulk params editor |
| `updateAutomatically` | bool | `true` | Auto-install updates |
| `updateChannel` | enum | `stable` | `stable`/`beta` |
| `disableUpdateNotification` | bool | `false` | Suppress update notices |
| `enableAnalytics` | bool | `true` | Anonymous usage telemetry |
| `showPasswords` | bool | `false` | Reveal masked secrets |
| `hotKeyRegistry` | map | defaults | Keyboard shortcut bindings |
| `pluginPath` | string | `''` | Plugin install directory |
| `pluginConfig` | map | `{}` | Per-plugin `{ disabled }` flags |
| `pluginNodeExtraCerts` | string | `''` | Extra CA certs for plugin Node |
| `npmRegistryUrl` | string | `''` | Custom npm registry for plugins |
| `scriptSandboxEnabled` | bool | `true` | Run scripts sandboxed |
| `scriptStrictModeEnabled` | bool | `true` | Scripts run in strict mode |
| `enableVaultInScripts` | bool | `false` | Allow scripts to read vault |
| `saveVaultKeyLocally` | bool | `true` | Persist vault key on disk |
| `saveVaultKeyToOSSecretManager` | bool | `true` | Store vault key in OS keychain |
| `vaultSecretCacheDuration` | number (min) | `30` | External vault secret cache TTL |
| `dataFolders` | string[] | `[]` | Folders scripts/runner may read/write |
| `disabledSecurityRules` | string[] | `[]` | Disabled security lint rules |
| `disabledBlockedProperties` | string[] | `[]` | Allow specific blocked script properties |
| `disabledBlockedRoots` | string[] | `[]` | Allow specific blocked script roots |
| `hasKonnectPat` | bool | `false` | Konnect PAT present |
| `forceVerticalLayout` | bool | `false` | Force vertical layout (also auto-on under Playwright) |
| `deviceId` | string\|null | `null` | Anonymous device id for analytics |

### 4.2 Environment variables

These configure build/runtime behavior (mostly for the main/preload process and the CLI). They are read via `process.env`.

| Variable | Where | Purpose |
|---|---|---|
| `INSOMNIA_DATA_PATH` | main | Override the app data directory |
| `INSOMNIA_ENV` | constants | Environment label |
| `INSOMNIA_API_URL`, `INSOMNIA_AI_URL`, `INSOMNIA_MOCK_API_URL`, `INSOMNIA_APP_WEBSITE_URL` | preload | Backend service URLs |
| `KONNECT_API_URL` | preload | Kong Konnect API endpoint |
| `INSOMNIA_GITHUB_API_URL`, `INSOMNIA_GITHUB_REST_API_URL` | preload | GitHub endpoints for Git Sync |
| `INSOMNIA_GITLAB_CLIENT_ID`, `INSOMNIA_GITLAB_API_URL`, `INSOMNIA_GITLAB_REDIRECT_URI` | preload | GitLab OAuth for Git Sync |
| `OAUTH_REDIRECT_URL`, `OAUTH_RELAY_URL` | preload | OAuth login relay |
| `INSOMNIA_SESSION` | preload | Injected session |
| `INSOMNIA_SECRET_KEY`, `INSOMNIA_PUBLIC_KEY` | preload | E2EE keypair material |
| `INSOMNIA_VAULT_KEY`, `INSOMNIA_VAULT_SALT`, `INSOMNIA_VAULT_SRP_SECRET` | preload | Vault key material / SRP |
| `INSOMNIA_SKIP_ONBOARDING` | preload | Skip onboarding |
| `PORTABLE_EXECUTABLE_DIR` | preload | Windows portable build dir |
| `HTTP_PROXY`/`HTTPS_PROXY`/`NO_PROXY` (+ lowercase) | CLI | Proxy config for `inso` |
| `INSO_TELEMETRY_DISABLED` | CLI | Disable `inso` telemetry |
| `DEFAULT_APP_NAME` | CLI | App name used to locate data dir |
| `APPDATA` / `XDG_DATA_HOME` | CLI/app | Platform data dir roots |
| `VERSION`, `BUILD_DATE`, `NODE_ENV` | build | Version/build stamping |

> [!CAUTION]
> `INSOMNIA_SECRET_KEY`, `INSOMNIA_VAULT_KEY`, `INSOMNIA_VAULT_SALT`, and `INSOMNIA_VAULT_SRP_SECRET` are **secret material**. Never log them, never bake them into images, and never commit a `.env` containing them.

### 4.3 The `.insorc` CLI config

`inso` loads a `cosmiconfig`-style config (`.insorc`, YAML/JSON) from the working/current dir or `--config`. It carries `options` (workingDir/ci/verbose/printOptions) and `scripts` (named `inso` aliases). See the User Guide §11.8.

### 4.4 Organization storage rules

Organizations can enforce **storage rules** (`organization-storage-rules.ts`, the `storage-rules` route) — for example mandating Local Vault or Git Sync and forbidding cloud storage for sensitive orgs. Admins use this to set policy centrally.

---

## 5. Security

### 5.1 Data residency — the central security property

Insomnia's defining security feature is **per-project storage choice**:

- **Local Vault** keeps everything on disk; nothing leaves the machine.
- **Git Sync** stores data in *your* repository — no Insomnia cloud involvement.
- **Cloud Sync** is opt-in and can be **end-to-end encrypted** (SRP + keypair material).
- **Private Environments** are always local regardless of project storage.

For regulated environments, set **organization storage rules** to forbid cloud storage and require Local Vault or Git Sync.

### 5.2 Secrets and the Vault

- The **Vault** encrypts secrets behind a **Vault Key**. The key may be saved locally (`saveVaultKeyLocally`) and/or in the OS secret manager (`saveVaultKeyToOSSecretManager`).
- Vault salt/key/SRP material is injected via env (`INSOMNIA_VAULT_*`).
- Vault values are **not** exposed to scripts unless `enableVaultInScripts` is enabled.
- External-vault integration caches secrets for `vaultSecretCacheDuration` minutes (default 30).

### 5.3 Script sandboxing

Pre-request/after-response scripts and unit tests run user JavaScript. Controls:

- `scriptSandboxEnabled` (default on) and `scriptStrictModeEnabled` (default on).
- `disabledBlockedProperties` / `disabledBlockedRoots` are **allow-list escape hatches** for the script sandbox's blocked globals — they widen the sandbox, so treat any non-empty value as a deliberate risk acceptance.
- `dataFolders` bounds filesystem reach for scripts/runner (CLI `-f`).

> [!WARNING]
> An after-response script executes code influenced by an external server's response. Combined with a widened sandbox (`disabledBlockedRoots`) or `enableVaultInScripts`, a hostile API could exfiltrate secrets. Keep the sandbox tight and `enableVaultInScripts` off unless required.

### 5.4 TLS and certificates

- `validateSSL` / `validateAuthSSL` (both default on) verify server certs. The CLI can disable per-run with `--disableCertValidation`; never do this against production.
- **Client certificates** (mTLS) and **CA certificates** are configured per workspace and scoped to a host.
- `pluginNodeExtraCerts` adds CA certs for the plugin Node runtime.

### 5.5 Windows DLL-hijack mitigation (secure wrapper)

The repo ships a native **secure wrapper** (`packages/insomnia/src/cpp`, built via `build-secure-wrapper.sh`) that uses Windows `PROCESS_MITIGATION_POLICY` to prefer system paths, mitigating a local DLL search-path hijack ([VulDB 295961](https://vuldb.com/?id.295961)) where a malicious DLL placed in the install directory (writable by underprivileged users) could be loaded by the Electron app.

### 5.6 Plugins — trust boundary

Plugins are npm-style code installed into `pluginPath` with Node access. They are a **trust boundary**: a plugin can do what the main process can. Vet third-party plugins, pin versions, and use `pluginConfig` to disable ones you do not need. `npmRegistryUrl` lets enterprises pin plugins to an internal registry.

### 5.7 Telemetry

Anonymous analytics (`enableAnalytics`, default on) is sent via Segment/Customer.io. Disable it app-wide (`enableAnalytics=false`) or per-CLI (`INSO_TELEMETRY_DISABLED=1`). The CLI honors the app's analytics setting.

### 5.8 Accounts, compliance, and reporting

- Account data is stored under ISO 27001 / SOC 2 Type II / ISO 27018 / CSA STAR per Kong's policy.
- Report vulnerabilities to **[email removed]** (see `SECURITY.md`); do not file public issues for security bugs.

---

## 6. Build, Package, and Release

### 6.1 Monorepo layout

npm workspaces, 8 packages:

| Package | Role |
|---|---|
| `insomnia` | The Electron desktop app (renderer + main) |
| `insomnia-inso` | The `inso` CLI |
| `insomnia-data` | Shared data models, services, DB adapters, common data utils |
| `insomnia-scripting-environment` | The `insomnia` scripting object + sandbox helpers |
| `insomnia-testing` | Test generation + Mocha/Chai test runner used by app and CLI |
| `insomnia-api` | API fetch utilities (`configureFetch`) |
| `insomnia-analytics` | Shared analytics client (Segment) for app + CLI |
| `insomnia-smoke-test` | Playwright smoke/critical tests + mock servers |

(`insomnia-component-docs` is a Docusaurus base-component playground, not shipped.)

### 6.2 Build the app

```bash
npm i                       # install + patch-package + libcurl + verify bundled plugins
npm run dev                 # renderer (vite) + electron, live reload
npm run dev:autoRestart     # also auto-restart main process

# Production build + package
npm run app-build           # react-router build + esbuild main entrypoints
npm run app-package         # electron-builder per electron-builder.config.js
```

- The renderer is built with **react-router build** + **Vite**; the Electron main entrypoints are bundled with **esbuild** (`esbuild.entrypoints.ts`).
- Packaging uses **electron-builder** (Squirrel/NSIS on Windows). On Windows the **secure wrapper** must be built separately (`build-secure-wrapper.sh`).
- `postinstall` runs `patch-package`, verifies bundled plugins, and installs the Electron-targeted libcurl.

### 6.3 Build the CLI

```bash
npm run inso-start          # esbuild watch
npm run inso-package         # build:production + @yao-pkg/pkg → binaries/inso
./packages/insomnia-inso/bin/inso -v
```

### 6.4 Validation

```bash
npm run lint          # ESLint across all workspaces
npm run type-check    # react-router typegen + tsc across workspaces
npm test              # Vitest across workspaces
```

Smoke/E2E (Playwright) live in `insomnia-smoke-test`:

```bash
npm run test:smoke:dev      # against the dev bundle
npm run test:smoke:build    # against the built bundle
npm run test:crit:dev       # critical-path suite
```

> [!NOTE]
> Bundling the **native libcurl** module across Windows/macOS/Linux is the single biggest build-maintenance burden the maintainers call out. One dependency (`apiconnect-wsdl`) has an over-restrictive engine ceiling requiring a manual lockfile edit on refresh.

### 6.5 Updates and channels

Auto-update is handled by **electron-updater**. Users are on the `stable` or `beta` `updateChannel`. To pin a fleet, ship a managed build and disable `updateAutomatically` / `disableUpdateNotification` via a settings policy.

---

## 7. Operations

### 7.1 Where data lives

| Platform | App data directory |
|---|---|
| macOS | `~/Library/Application Support/Insomnia` |
| Windows | `%APPDATA%\Insomnia` (or portable dir) |
| Linux | `$XDG_DATA_HOME/Insomnia` or `~/.config/Insomnia` |

Override with `INSOMNIA_DATA_PATH`. The CLI resolves the same path (via `DEFAULT_APP_NAME`).

### 7.2 Backup and restore

The main process exposes `backup` / `restoreBackup` IPC channels (also surfaced as a `backup.ts` service). For portable backups, **export** workspaces to YAML or use **Git Sync** so the canonical copy lives in version control. Back up before clearing caches.

### 7.3 CI/CD operation

`inso` is the operational surface for pipelines: lint specs (`inso lint spec`), run tests (`inso run test`), run collections (`inso run collection`), export specs (`inso export spec`). It exits non-zero on failure. Prefer `-w` over a locally installed app on build agents, pin a version, and pass `--ci`. Keep secrets in CI secret stores and inject as environment variables; prefer `--includeFullData=redact` if you must emit a report.

### 7.4 Fleet/enterprise rollout checklist

- [ ] Set **organization storage rules** to match your data-residency policy.
- [ ] Decide on Cloud Sync (E2EE) vs Git Sync vs Local Vault per team.
- [ ] Disable `enableAnalytics` if telemetry is disallowed.
- [ ] Pin plugins to an internal `npmRegistryUrl`; disable unused plugins.
- [ ] Keep `enableVaultInScripts` **off** and the script sandbox tight by default.
- [ ] Standardize a `.spectral.yaml` ruleset in repos so app + `inso` lint identically.
- [ ] Control updates (`updateChannel`, `updateAutomatically`) for production stability.
- [ ] On Windows, ship the build with the **secure wrapper** to mitigate DLL hijack.

---

## 8. Module Reference (developer internals)

`packages/insomnia/src` is the heart of the app:

| Path | Responsibility |
|---|---|
| `entry.main.ts` / `entry.preload.ts` | Electron main entry; preload bridge + env injection |
| `main/` | Main-process services: `ipc/main.ts` (channel registry), `network/`, `git-service.ts`, `cloud-sync/core` (VCS), `importers/`, `mcp/`, `backup.ts`, `updates.ts`, `proxy.ts`, `secure-read-file.ts`, plugin lifecycle |
| `ui/` | React SPA: `routes/` (feature surface), `components/` (editors, modals, sidebar, panes, settings, websockets, socket-io, graph-ql-explorer, mcp), `context/`, `hooks/`, `worker/` |
| `common/` | Cross-process utils: `database.ts` (NeDB), `render.ts` (templating), `send-request.ts` (`getSendRequestCallbackMemDb`), `insomnia-v5.ts` + `insomnia-schema-migrations/` (import/migrate), `bundle-spectral-ruleset.ts`, `import.ts`, `constants.ts`, `private-host.ts`, `organization-storage-rules.ts` |
| `network/` | Request execution + auth: `network.ts`, `authentication.ts`, `certificate.ts`, `{basic,bearer,api-key}-auth`, `grpc/`, `main/network/o-auth-{1,2}` |
| `sync/` | `git/` (isomorphic-git + fs-clients + providers), `vcs/`, `delta/`, schemas |
| `templating/` | Nunjucks tags + rendering |
| `plugins/` | Plugin install/load/context API |
| `cpp/` | Windows secure wrapper (DLL-hijack mitigation) |

Supporting packages:

| Path | Responsibility |
|---|---|
| `insomnia-data/src/models` | Typed data models + `init()` defaults |
| `insomnia-data/node-src/services` | Node-side model services (validation, CRUD) |
| `insomnia-inso/src/cli.ts` | Commander command tree (run/lint/export/script/generate-docs) |
| `insomnia-inso/src/db` | DB adapters (NeDB, insomnia export, git-repo) + model loaders |
| `insomnia-scripting-environment/src/objects` | The `insomnia` scripting object: `request`, `response`, `environments`, `variables`, `cookies`, `test`, `execution`, `auth`, `urls`, `send-request`, etc. |
| `insomnia-testing/src` | `generate` (test-file generation) + `run`/`runTestsCli` (Mocha/Chai) |

### 8.1 Request lifecycle (end to end)

```text
User edits request (CodeMirror fields, {{ tags }})
  → action route resolves & persists the Request model (NeDB)
  → render.ts interpolates Nunjucks tags using active environment/variables
  → pre-request script runs in the sandbox (insomnia.*)
  → main process computes auth header (getAuthHeader / getOAuth2Token)
  → curlRequest (native libcurl) sends; timeline (NDJSON) captured
  → Response model persisted; history trimmed to maxHistoryResponses
  → after-response script runs; unit-test assertions recorded
  → response pane renders body/headers/timeline/timing
```

The CLI runs the same pipeline headlessly via `getSendRequestCallbackMemDb`, swapping the UI for stdout reporters.

---

## 9. Technical Debt and Roadmap

Straight from the maintainers' `DEVELOPMENT.md` (verbatim status):

**Open debt:**
- **NeDB is unmaintained** (last published 2016) and deeply tied to the architecture; migration is hard. De-polymorphizing the database is pending.
- **CodeMirror is unmaintained** — every templating/autocomplete field is a CodeMirror instance.
- **`inso` bundles almost the entire renderer** and stubs Electron, which "limits networking improvements." Ideas: a shared DB+templating package, an adapter swapping `node-libcurl` for `fetch`, or removing plugin support from `inso` and reintroducing a fixed API.
- **Sync code is "spaghetti"**; **template rendering** "is spaghetti and has poor discoverability."
- **gRPC state** should move from the renderer into the main process.
- **`curl.ts` and `libcurl-promise`** implementations should be unified.
- The **testing feature doesn't scale** with investment.
- Large responses (~20 MB) can crash the app on weaker hardware.
- `apiconnect-wsdl` forces a manual lockfile engine-ceiling edit on each refresh.

**Completed (for context):** migrated Redux→Remix/React-Router, Lerna→npm workspaces, class→function components, Electron/Spectral upgrades, react-aria+tailwind styling, send-request extraction, NeDB removal *in progress*.

> [!TIP]
> If you contribute, the highest-leverage, well-scoped wins are: unifying the two libcurl code paths, moving gRPC state to main, and extracting a standalone DB+templating package to free `inso` from bundling the renderer.

---

## 10. Contributing

1. Use the `.nvmrc` Node version (`fnm use "$(cat .nvmrc)"`) and npm 11+.
2. `npm ci` from repo root in fresh worktrees — **do not** use `--ignore-scripts` (leaves Electron partially installed and breaks validation).
3. Follow `AGENTS.md`: rely on ESLint/Prettier (no unsolicited reformatting), keep changes strictly scoped.
4. Before considering work done: `npm run lint`, `npm run type-check`, `npm test`. Add smoke tests for UI-visible changes.
5. Unit tests live beside the file under test (`foo.ts` → `__tests__/foo.test.ts`); smoke tests live in `insomnia-smoke-test` (Playwright, POM-based — see its README).
6. Check for circular imports with `npm run check-cycle-references` (madge).

---

## 11. Troubleshooting (operational)

### Error: `Fetch has not been configured. Please call configureFetch() at application startup.`

- **Cause:** `insomnia-api`'s fetch was used before `configureFetch()` ran. In the CLI this is wired at startup; in embedding scenarios it may be missing.
- **Solution:** Ensure `configureFetch(...)` runs before any API call (the CLI does this in `cli.ts`).
- **Prevention:** Don't call API utilities before app/CLI bootstrap completes.

### Error: `3-way merge hit impossible state` / `Cannot delete master branch` (Cloud Sync)

- **Cause:** Cloud-sync VCS merge/branch invariants violated (e.g. deleting the protected `master` branch, or a corrupt delta).
- **Solution:** Use a different branch name; pull the latest snapshot before merging; avoid deleting `master`.
- **Prevention:** Keep snapshots current; don't hand-edit synced data.

### Error: `Invalid Spectral ruleset` / `Failed to resolve host` (lint)

- **Cause:** A malformed `.spectral.yaml`, or a remote `$ref`/ruleset that can't be fetched.
- **Solution:** Validate the ruleset is an object at the top level; ensure remote refs are reachable or vendor them locally.
- **Prevention:** Keep rulesets self-contained and in-repo; lint them in CI.

### Error: `Failed to parse API spec` / `Failed to parse yaml file to Insomnia schema`

- **Cause:** Invalid OpenAPI/YAML, or an Insomnia v5 schema mismatch on import.
- **Solution:** Validate the YAML/OpenAPI; check the export was produced by a compatible Insomnia version.
- **Prevention:** Export/import with matching major versions; lint specs before importing.

### Symptom: Native module / libcurl build failures

- **Cause:** Electron/Node ABI mismatch or missing platform build deps.
- **Solution:** Install platform deps (§3.2), then `npm run install-libcurl-electron`. Clear `~/.cache/electron` on Linux if Electron install conflicts.
- **Prevention:** Pin Node/Electron via `.nvmrc`; run `npm ci` (not `--ignore-scripts`).

### Symptom: `inso` can't find data in CI

- **Cause:** No locally installed app and `DEFAULT_APP_NAME` unset.
- **Solution:** Always pass `-w` pointing at the repo/export, and `--ci`.
- **Prevention:** Commit the `.insomnia`/export into the repo and reference it in `.insorc`.

---

## 12. Quick Reference

### 12.1 Repo facts

| | |
|---|---|
| License | Apache-2.0 |
| App version (this commit) | `12.5.1-alpha.0` |
| Commit | `bece185` (2026-06-05) |
| Node / npm (dev) | `>=24` / `>=11` |
| Electron | `41.0.3` |

### 12.2 Key commands

```bash
npm run dev              # run app with live reload
npm run app-package      # build + package the desktop app
npm run inso-package     # build the standalone inso binary
npm run lint && npm run type-check && npm test   # validate
npm run check-cycle-references                    # detect circular imports
```

### 12.3 `inso` command tree

```text
inso run collection [id]   # run a collection (data-driven, reporters, --output)
inso run test [id]         # run unit test suites
inso lint spec [id|file]   # Spectral-lint an OpenAPI spec
inso export spec [id]      # export an OpenAPI spec (-o, --skipAnnotations)
inso script <name>         # run a named .insorc script
inso generate-docs         # print CLI docs
```

### 12.4 Security defaults to verify

| Setting | Secure value |
|---|---|
| `validateSSL` / `validateAuthSSL` | `true` |
| `enableVaultInScripts` | `false` |
| `scriptSandboxEnabled` / `scriptStrictModeEnabled` | `true` |
| `disabledBlockedRoots` / `disabledBlockedProperties` | `[]` |
| `enableAnalytics` | `false` (if telemetry disallowed) |
| Storage backend | Local Vault / Git Sync for sensitive projects |

---

_Generated June 2026 from Kong/insomnia at bece185. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
