Cottontail
Cottontail is the default runtime for a TypeScript main process. It’s built with Zig on JavaScriptCore and provides the Node.js and Bun-compatible APIs Electrobun applications need — which means existing code and npm packages can work without a Cottontail-based app shipping Node or Bun.
Why a separate runtime at all? Because a desktop app’s runtime has a different job than a general-purpose server runtime. Cottontail carries the APIs applications actually use and leaves out the rest. Project dependencies use Hutch’s built-in npm-compatible resolver by default, or an explicitly selected external package manager. Bundling and native build machinery live in Hutch, so the runtime that ships inside every app stays small.
Bun is also a first-class package-manager choice for a Cottontail project: set
packageManager: "bun" in hutch.config.ts. That explicitly selects the
external dependency tool. Separately, Cottontail implements Bun-compatible
application APIs including the Bun.$ shell interface.
Hutch uses Cottontail in two separate roles. The build-time Cottontail that loads config and runs scripts is paired with the Hutch release, unless a project pragma overrides it. For a Cottontail main process, the selected Electrobun devkit separately pins the exact runtime placed in the application bundle; it does not inherit Hutch’s build-time pair. End users install neither one. A Bun main process bundles the devkit-pinned Bun runtime instead.
Windows ARM64 preview
Section titled “Windows ARM64 preview”The Windows ARM64 canary supports JavaScriptCore’s Baseline, DFG, and FTL JIT tiers and WebAssembly. Native npm addons also need Windows ARM64 binaries or a working build from source. Existing x64 installations keep receiving x64 updates; users can download and install your ARM64 build to switch architectures.
Select Cottontail
Section titled “Select Cottontail”New projects use Cottontail by default. Spelled out explicitly, the configuration is:
import type { ElectrobunConfig } from "electrobun";
export default { app: { name: "Cottontail App", identifier: "dev.example.cottontail-app", version: "0.1.0", }, build: { mainProcess: "cottontail", cottontail: { entrypoint: "src/bun/index.ts", }, },} satisfies ElectrobunConfig;One naming note: the conventional src/bun directory does not select the
runtime. electrobun/main is the canonical, runtime-neutral SDK import. With
the configuration above, Cottontail executes this code:
import { BrowserWindow } from "electrobun/main";
new BrowserWindow({ title: "My App", url: "views://mainview/index.html",});Modular standard library
Section titled “Modular standard library”Cottontail 0.6.0 and later separate optional standard-library APIs into capability modules. Hutch always packages the core runtime. It scans the final, tree-shaken main-process bundle for recognized module specifiers and namespace accesses, then includes the selected capabilities and their dependencies from the runtime’s manifest. At runtime, capabilities load on demand.
For example, import { Database } from "bun:sqlite" selects sqlite, and
import { gzipSync } from "node:zlib" selects compression. Direct
Cottontail.sqlite and Cottontail.compression accesses are also recognized.
Your application’s bundled dependencies participate in the same scan.
The scanner matches known text in the output bundle; it does not execute your
code or infer every JavaScript access. Computed imports, aliased namespaces,
destructuring, and files loaded later may hide usage. In particular, do not
assume a global compatibility access such as Bun.SQL selects sql.
Use a recognized module import or explicitly include the capability in
electrobun.config.ts:
import type { ElectrobunConfig } from "electrobun";
export default { app: { name: "Plugin App", identifier: "dev.example.plugin-app", version: "0.1.0", }, build: { mainProcess: "cottontail", cottontail: { entrypoint: "src/bun/index.ts", capabilities: ["sqlite", "sql"], }, },} satisfies ElectrobunConfig;The list is additive: it keeps everything automatically detected and adds these modules. An empty list does not disable scanning, and there is no exclusion list. Capability names describe packaging, not a permissions sandbox. This setting affects Cottontail app bundles, not Bun main processes or Hutch’s build-time runtime.
Each build logs the capabilities discovered by the scan, before explicit includes and transitive dependencies are added. If a packaged app reports a missing capability, add the name to this list, rebuild, and exercise that path in the resulting app on each target platform. See the configuration reference for the full list of names.
Runtime and build ownership
Section titled “Runtime and build ownership”The clean split between Cottontail and Hutch is worth internalizing, because it explains where every capability lives:
| Concern | Owner |
|---|---|
| Execute the bundled TypeScript main process | Cottontail |
| Node.js and Bun-compatible runtime APIs | Cottontail |
| Install packages, execute their binaries, and maintain their lockfile | Hutch by default, or an explicit external package manager |
| Bundle main-process and webview source | Hutch |
| Acquire compilers and native platform artifacts | Hutch |
| Sign, notarize, wrap, and package releases | Hutch |
Everything build-related stays out of the runtime shipped to every user.
Runtime compatibility
Section titled “Runtime compatibility”Cottontail is built to run existing Node.js and Bun-oriented application
code, and for typical application code it does. But compatibility isn’t the
same as being interchangeable in every case: native addons, runtime-specific
implementation details, and uncommon APIs can expose differences. The
practical advice is the same as for any runtime: commit hutch.lock or the
lockfile owned by your explicitly selected package manager, and exercise your
application on every target platform before release.
Pin Cottontail
Section titled “Pin Cottontail”Most projects don’t need a build-time pin: without one, Hutch uses the
Cottontail version that release was built and tested with, and hutch upgrade
advances the pair. Pin only when the build pipeline needs a different exact
version:
// @hutch cottontail=0.7.1Inspect the active version with hutch cottontail version.
This pragma controls build-time execution only. The Cottontail shipped for
build.mainProcess: "cottontail" remains the exact version declared by the
selected Electrobun devkit.