Skip to main content
This guide covers all build commands, packaging options, and distribution workflows for SuperCmd.

Build Commands

SuperCmd has several build scripts for different purposes:

Development Build

npm run dev
What it does:
  • Builds main process once with npm run build:main
  • Starts TypeScript watch for main process
  • Starts Vite dev server for renderer
  • Launches Electron app in development mode with DevTools
Under the hood, this runs:
npm run build:main && \
concurrently \
  "npm run watch:main" \
  "npm run dev:renderer" \
  "npm run start:electron"

Production Build

npm run build
Builds all components for production:
1

Build main process

npm run build:main
Compiles TypeScript in src/main/ to JavaScript in dist/main/ using tsconfig.main.json.
2

Build renderer

npm run build:renderer
Builds the React UI with Vite, outputting to dist/renderer/. Optimizes for production with minification and code splitting.
3

Build native modules

npm run build:native
Compiles Swift binaries to dist/native/. See details below.

Building Native Modules

The native Swift modules are compiled separately:
npm run build:native

What Gets Built

swiftc -O -o dist/native/color-picker \
  src/native/color-picker.swift \
  -framework AppKit
All native modules are compiled with -O (optimization) for production performance. They are unpacked from the ASAR archive at runtime (see package.json:69).

Packaging

Standard Package (Signed & Notarized)

npm run package
Builds and packages the app with code signing and notarization:
  • Sets NODE_ENV=production
  • Runs full production build
  • Packages with electron-builder
  • Code signs with identity Shobhit Bhosure (T7HT4U4666)
  • Notarizes with Apple (Team ID: T7HT4U4666)
  • Outputs to out/ directory
This requires valid code signing certificates and Apple Developer credentials. If you don’t have these, use the unsigned build.

Unsigned Package (Development)

npm run package:unsigned
Builds and packages without code signing or notarization:
  • Sets CSC_IDENTITY_AUTO_DISCOVERY=false
  • Sets -c.mac.identity=null
  • Sets -c.mac.notarize=false
  • Useful for local testing and development

Build Configuration

electron-builder Settings

Configured in package.json under the build key:
{
  "appId": "com.supercmd.app",
  "productName": "SuperCmd",
  "icon": "supercmd.icns",
  "files": [
    "dist/**/*",
    "package.json"
  ],
  "asarUnpack": [
    "dist/native/**",
    "dist/main/window-manager-worker.js",
    "node_modules/esbuild/**",
    "node_modules/@esbuild/**",
    "node_modules/node-edge-tts/**",
    "node_modules/node-window-manager/**",
    "node_modules/electron-liquid-glass/**"
  ],
  "directories": {
    "output": "out"
  }
}

ASAR Unpacking

Certain files must be unpacked from the ASAR archive:
  • Native modules - Swift binaries in dist/native/
  • Worker scripts - window-manager-worker.js
  • Binary dependencies - esbuild, node-edge-tts, node-window-manager, electron-liquid-glass

macOS Configuration

{
  "mac": {
    "category": "public.app-category.utilities",
    "target": "dmg",
    "hardenedRuntime": true,
    "entitlements": "./entitlements.mac.plist",
    "entitlementsInherit": "./entitlements.mac.plist"
  }
}
Entitlements include:
  • Camera usage description
  • Microphone usage description
  • Speech recognition usage description

Output Artifacts

After running npm run package, you’ll find artifacts in the out/ directory:
out/SuperCmd-1.0.5-arm64.dmg
out/SuperCmd-1.0.5-arm64-mac.zip

Distribution Formats

  • DMG - Drag-and-drop installer for macOS
  • ZIP - Compressed archive with the .app bundle

Auto-Updates

SuperCmd includes electron-updater for automatic updates:
{
  "publish": [
    {
      "provider": "github",
      "owner": "SuperCmdLabs",
      "repo": "SuperCmd",
      "releaseType": "release"
    }
  ]
}
Updates are pulled from GitHub releases automatically.

Build Process Details

TypeScript Compilation

Main Process:
  • Uses tsconfig.main.json
  • Compiles src/main/**/*.ts to dist/main/**/*.js
  • Target: ES2020
  • Module: CommonJS
Renderer Process:
  • Handled by Vite with @vitejs/plugin-react
  • Hot module replacement in dev mode
  • Optimized bundle in production
  • Outputs to dist/renderer/

Extension Bundling

Extensions are bundled at runtime using esbuild:
  • Format: CommonJS
  • Bundles @raycast/api and @raycast/utils imports
  • Provides custom require() shim
  • See src/main/extension-runner.ts:100

Continuous Integration

name: Build

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: macos-latest
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '22'
      
      - name: Install dependencies
        run: npm install
      
      - name: Build native modules
        run: npm run build:native
      
      - name: Build app
        run: npm run build
      
      - name: Package app
        run: npm run package:unsigned
      
      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: SuperCmd-${{ runner.os }}
          path: out/*.dmg

Troubleshooting

Install Xcode Command Line Tools:
xcode-select --install
Run npm run build:native explicitly before packaging:
npm run build:native && npm run package
Use the unsigned build for local development:
npm run package:unsigned
Ensure files that need filesystem access are listed in asarUnpack in package.json:69-77.
Check that dev dependencies aren’t being bundled. Ensure they’re in devDependencies, not dependencies in package.json.

Next Steps

Build docs developers (and LLMs) love