Skip to main content

Overview

SuperCmd’s extension runtime provides full compatibility with Raycast extensions without requiring any modifications to extension code. The runtime achieves this through a sophisticated bundling and shimming system that intercepts extension imports and provides SuperCmd’s implementations of the Raycast API.

Architecture

The extension execution model follows these key principles:
1

Extension Discovery

Extensions are discovered from configured directories and the Raycast registry
2

Build-Time Bundling

Extension code is bundled to CommonJS using esbuild at install time
3

Runtime Shimming

A custom require() function provides React and @raycast/api implementations
4

Isolated Execution

Extensions run in isolated contexts while sharing React with the host app

Extension Loading

Discovery Process

Extensions are discovered from multiple sources:
The system scans these directories for valid package.json files that define Raycast extension manifests.

Extension Structure

Each extension must have:
  • package.json: Manifest defining commands, preferences, and metadata
  • src/: Source code directory containing command entry points
  • assets/: Optional icon and media files
  • node_modules/: Runtime dependencies (installed at build time)

Build System

Bundling with esbuild

SuperCmd bundles extensions at install time, not runtime. This approach provides:
  • Fast Loading: Pre-built bundles load instantly
  • Dependency Resolution: All imports are resolved at build time
  • Code Optimization: Minification and tree-shaking reduce bundle size

TypeScript Configuration

Extensions can define custom TypeScript compiler options:
This allows extensions to use:
  • Custom baseUrl and paths for import aliases
  • Alternative jsx configurations
  • Extension-specific compiler flags

Runtime Execution

Bundle Loading

When a command is executed, SuperCmd loads the pre-built bundle:

Custom Require Shim

The renderer process provides a custom require() function that intercepts module requests:
Extensions share the same React instance as the host app. This is critical for React contexts, hooks, and component lifecycle to work correctly.

Extension Context

Each extension receives a context object with metadata and preferences:
This context is accessible via the environment object:

Preferences System

Preference Definition

Extensions define preferences in their manifest:

Preference Resolution

Preferences support platform-specific defaults:

Dependency Management

Runtime Dependencies

Extensions can declare runtime dependencies in package.json:
SuperCmd installs these dependencies at extension install time:

External Packages

Certain packages must remain external due to native bindings or special handling:

Platform Compatibility

Platform Filtering

Extensions can specify platform requirements:

Error Handling

Build Failures

When a build fails, SuperCmd provides detailed diagnostics:

Runtime Errors

Extension errors are captured and reported through the SuperCmd UI:

Performance Optimizations

Build Caching

Pre-built Bundles

All commands are built at install time, eliminating runtime compilation overhead.

Incremental Builds

Only changed commands are rebuilt when extensions are updated.

Parallel Bundling

Multiple commands can be built in parallel for faster installation.

Shared Dependencies

React and common utilities are loaded once and shared across all extensions.

On-Demand Building

If a pre-built bundle is missing, SuperCmd builds it on-demand:

Best Practices

  • Keep command entry points small and focused
  • Use dynamic imports for large dependencies
  • Minimize the number of external dependencies
  • Test extensions with NODE_ENV=production
  • Use console.log() for debugging (appears in main console)
  • Check .sc-build/ directory for built bundles
  • Inspect bundled code to verify transformations
  • Test with real Raycast extensions to ensure compatibility
  • Avoid heavy computation in component render functions
  • Use React.memo() for expensive components
  • Leverage useCallback() and useMemo() hooks
  • Keep bundle sizes under 1MB when possible

See Also

Raycast API

Learn about the Raycast API compatibility layer

Electron Architecture

Understand the Electron process architecture

Native Modules

Explore SuperCmd’s native Swift integrations

Extension Registry

Install and manage extensions