Seed Project

Overview

Available since io.Connect Desktop 10.0

The io.Connect seed project is the main approach for delivering, customizing, and packaging io.Connect Desktop. The seed project enables you to control the entire process of creating your own custom distribution package, reducing the time for adopting new platform versions.

The seed project provides the following benefits:

  • installing the latest or a specific version of the platform components;
  • integrating the platform license key;
  • customizing the platform system configuration;
  • customizing the platform assets like logos, icons, splash screen, loader, and more;
  • customizing various branding features via the CLI configuration (the product name and description, the names and icons of the produced artifacts);
  • development and production modes that support different configuration settings;
  • templates for the customizable system apps (e.g., Workspaces App, Web Group App, Launchpad);
  • adding your own custom apps to be packaged with your platform build;
  • test templates for writing and executing your own tests;
  • producing artifacts (installers, bundles) for Windows and macOS;
  • code signing settings;
  • publishing and auto update settings;
  • CI/CD integration settings;

The @interopio/iocd-cli library provides an io.Connect CLI which is a necessary tool for creating and managing a seed project.

ℹ️ For more details on the available io.Connect CLI commands, see the CLI section.

Requirements

To be able to create and use an io.Connect seed project, the following requirements must be met:

  • Node.js v22 or later;
  • npm v9 or later;
  • OS: Windows 10 or later, macOS 11 or later;
  • License: the seed project requires a valid license key for io.Connect Desktop;

Quick Start

Execute the following steps to quickly setup your seed project.

  1. Install the io.Connect CLI to create a seed project:
  • Install the io.Connect CLI:
npm install -g @interopio/iocd-cli@latest
  • Navigate to your project directory and create the seed project by executing the following command:
iocd create

Alternatively, you can use npx to execute the create package command directly:

npx @interopio/iocd-cli@latest create
  1. Follow the prompts and provide a product name, select the desired platform components, select which templates to add for customization, and provide a valid license key.

⚠️ Note that the Application Adapters aren't currently available as installable components via the io.Connect CLI. Until they become available, they will be delivered to you as separate bundles which you have to add manually to your project.

  1. Install the necessary dependencies for the seed project:
npm install
  1. Prepare the project for usage by executing the following command. This will install the selected components and the dependencies for all customizable apps:
npm run setup
  1. To run your seed project in development mode in order to test your platform and your interop-enabled apps, execute the following command:
npm run dev
  1. After customizing and testing your platform project, you can produce build artifacts both for Windows and for macOS by executing the following command:
npm run build

Project Structure

The following demonstrates the basic structure of the seed project:

.
├── apps/                       # Contains the customizable system apps. You can place your own apps here to be bundled with the package.
├── components/                 # Downloaded platform components.
│   ├── iocd/                   # The main platform component (required).
│   └── <other-components>      # Additional licensed components (devTools, demos, and more).
├── config/                     # Seed project configuration files.
│   ├── forge.config.js         # Electron Forge configuration.
│   ├── iocd.cli.config.json    # io.Connect CLI configuration.
│   └── iocd.license.key        # License key file.
├── modifications/              # Contains all platform customizations (icons, images, and more) and configuration overrides.
│   ├── base/                   # Modification that will be applied in all modes (development/build).
│   ├── dev/                    # Modifications that will be applied only in development mode.
│   └── build/                  # Modifications that will be applied only during production builds.
├── tests/                      # Automated tests.
│   └── basic.test.js           # Example test suite.
├── .github/workflows/          # Pre-configured GitHub Actions workflow example for CI/CD automation.
├── package.json
└── README.md

Components

The following table lists the currently available components that can be installed via the seed project:

Component Description
"demos" Contains a set of web demo apps that can be used for testing and PoC purposes.
"devTools" Contains the io.Connect Dev Tools.
"iocd" Required. This is the main platform component.

Configuration

Basic Settings

The metadata for your product can be configured in the package.json file:

{
    "name": "my-product-slug",
    "version": "1.0.0",
    "description": "My product description.",
    "productName": "My Product Name",
    "author": "My Company"
}

The values specified in these fields are automatically populated by the io.Connect CLI when you execute the create command.

The following table describes the purpose of each property:

Property Type Description
"author" string Used as a company name (also used to auto-generate copyright).
"description" string Used as a product description in installers and metadata.
"name" string Used as a project identifier (e.g., folder name, executable name, package name, and more).
"productName" string Used as a human-readable product name displayed to users in UIs.
"version" string Used as a version for your platform app.

The settings for configuring the io.Connect CLI are in the iocd.cli.config.json file located in the /config folder.

The following is a basic configuration for the io.Connect CLI specifying the store from which to download the platform components and the list of components and component versions to retrieve:

{
    "components": {
        "store": {
            "github": {
                "repo": "interopio/iocd-components/releases"
            }
        },
        "list": {
            "iocd": "latest"
        }
    }
}

ℹ️ For details on all available configuration settings for the io.Connect CLI, see the complete JSON schema for the iocd.cli.config.json file. The schema is located in the /node_modules/@interopio/iocd-cli/dist/schemas folder. Add a $schema property to your configuration file to enable IDE autocompletion and validation.

License Key

io.Connect Desktop requires a valid license key to operate.

ℹ️ For details on how to obtain a license key for io.Connect Desktop 10.0, contact us.

During the process of creating the seed project, you will be prompted to provide a valid license key for io.Connect Desktop. Copy and paste your license key when prompted to continue the project creation. If you don't provide a valid license key, you won't be able to create a seed project.

The io.Connect CLI will create automatically an iocd.license.key file located in the /config folder of the seed project. You can use this file to manage your license key later.

⚠️ Note that you must never commit the iocd.license.key file in your project repository to prevent leaking your license key. By default, this file is ignored in the .gitignore settings.

For the purpose of setting up CI/CD automation, you can also use the IOCD_LICENSE_KEY environment variable to store and obtain the license key from your GitHub secrets during build.

Customization

Modifications

Modifications are the recommended way to customize io.Connect Desktop components without directly editing component files. They allow you to change configurations, add apps, modify assets, and override default behavior while preserving your changes across component updates.

Key Concepts:

  • Modifications are stored separately from components in the modifications/ folder
  • Changes persist when components are updated or reinstalled
  • Mode-specific modifications allow different behavior in dev vs. build mode
  • Files are copied or merged into components when running iocd dev or iocd build

Directory Structure:

modifications/
├── base/                     # Applied in all modes
│   └── iocd/
│       ├── config/
│       ├── assets/
│       └── apps/
├── dev/                      # Applied only in dev mode
│   └── iocd/
│       └── config/
└── build/                    # Applied only in build mode
    └── iocd/
        └── config/

Processing Order:

  1. Base modifications (modifications/base/) are applied first
  2. Mode-specific modifications (modifications/dev/ or modifications/build/) are applied second, overriding base when needed

Common Use Cases:

  • Replace logos and icons in modifications/base/iocd/assets/
  • Configure system settings in modifications/base/iocd/config/
  • Add app definitions in modifications/base/iocd/apps/
  • Use different URLs for dev (localhost) vs. build (file://) in mode-specific folders

Special File Types:

  • .json.merge - Deep merges with existing JSON instead of replacing
  • .delete - Removes the corresponding file
  • .replace marker - Replaces entire directory (place in directory to replace)

System Configuration

The io.Connect Desktop system configuration (the system.json file) controls platform-wide settings like auto-updates, logging, and feature flags. To customize these settings, create modification files that merge with the default configuration.

Location:

modifications/base/iocd/config/system.json.merge

The following example demonstrates how to enable auto updates:

{
    "autoUpdater": {
        "enabled": true,
        "updateSource": {
            "type": "Service",
            "baseUrl": "https://updates.yourcompany.com"
        },
        "updateIntervalMinutes": 60
    }
}

The following example demonstrates how to configure the system logging:

{
    "logging": {
        "level": "info",
        "appender": "default"
    }
}

Mode-Specific Configurations

Using different settings for development and production build mode:

Dev mode (modifications/dev/iocd/config/system.json.merge):

{
    "logging": {
        "level": "debug"
    },
    "features": {
        "devTools": true
    }
}

Build mode (modifications/build/iocd/config/system.json.merge):

{
    "logging": {
        "level": "error"
    },
    "features": {
        "telemetry": true
    }
}

When modifying the system configuration, consider the following:

  • Use .merge extension to deep merge with existing configuration.
  • Without .merge, the file completely replaces the original.
  • Changes are applied when running iocd dev or iocd build.
  • Environment variables like ${PRODUCT_VERSION} are automatically expanded.

Icons & Images

Default logo:

Replace the default logo files in modifications/base/iocd/assets/images/:

modifications/base/iocd/assets/
└── images/
    ├── logo.ico   # Windows executable icon (multiple resolutions)
    ├── logo.icns  # macOS app bundle icon (multiple resolutions)
    └── logo.png   # App icon (used in UI)

Requirements:

  • logo.ico: Windows icon file with multiple sizes (16x16, 32x32, 48x48, 256x256)
  • logo.icns: macOS icon file with multiple sizes (use Icon Composer or iconutil)
  • logo.png: PNG file, recommended size 512x512

Apps

io.Connect Desktop includes several built-in apps that you can replace with your own custom versions:

  • Workspaces - Workspace management UI
  • Groups - Window grouping UI
  • Splash Screen - Platform splash screen
  • Launchpad - App launcher
  • Notifications - Notification center

Apps in the apps/ folder allow you to customize these built-in apps or add entirely new functionality. This approach keeps your core platform apps in the same repository, eliminating the need to manage them across multiple repositories and simplifying version control, deployment, and coordination.

Using Template Apps

Template aspp can be selected during project creation or added later:

# Add a template app
iocd apps add workspaces

# List available templates
iocd apps list --available

Available templates:

  • workspaces - Workspace management
  • groups - Window grouping
  • splash-screen - Loading screen
  • launchpad - App launcher

Once added, build your implementation on top of the template in the apps/ folder.

Creating Custom Apps

For custom apps, create a folder in apps/ with an iocd.app.json file:

apps/
└── my-custom-app/
    ├── iocd.app.json       # Defines modifications and build behavior
    ├── package.json
    └── src/

Example iocd.app.json:

In this example:

  • Dev mode (triggered by iocd dev or npm run dev): Executes a start script (typically starts a dev server with hot-reload) and copies the development app configuration so the app definition points to the dev server
  • Build mode (triggered by iocd build or npm run build): Executes a build script (typically builds optimized production assets) and copies the final built assets to the modifications folder
{
   "dev": {
        "script": "start",
        "modifications": [
            {
                "source": "/config/my-app-dev.json",
                "destination": "/modifications/dev/iocd/config/apps/my-app.json"
            }
        ]
    },
    "build": {
        "script": "build",
        "modifications": [
            {
                "source": "/dist/",
                "destination": "/modifications/build/iocd/assets/my-app"
            }
        ]
    }
}

The iocd.app.json file defines:

  • base: Array of modifications applied in all modes
  • dev: Object with optional script (npm script name) and modifications array
  • build: Object with optional script (npm script name) and modifications array

Managing Apps

# Install app dependencies
iocd apps install

# Start apps in dev mode
iocd apps dev

# Build apps for production
iocd apps build

Development

Development mode allows you to quickly start io.Connect Desktop with all your configured changes and apps, enabling rapid iteration and testing during development.

When you run dev mode, the CLI will:

  1. Apply all relevant modifications - Base modifications and dev-specific modifications are copied to components
  2. Launch the platform - Starts the platform with all changes applied
# Start io.Connect Desktop in dev mode
iocd dev

# Or using npm script
npm run dev

⚠️ Note that in order to run any custom apps you may have in the /apps folder, you must run npm run apps-dev in a separate terminal to start them. If you don't start them, io.Connect Desktop may fail to start.

Installing & Updating Components

To install a component or update existing component while in development mode, use the following command:

# Update components
iocd components install <component-name>

# Or using npm script (note the -- before the component name)
npm run components-install -- <component-name>

This command will download and install the latest version of the specified component.

If you want to install a specific version, use:

iocd components install <component-name>@<version>

# Or using npm script (note the -- before the component name)
npm run components-install -- <component-name>@<version>

Testing

Testing is based on WebdriverIO and depends on the @interopio/wdio-iocd-service package, which enables starting and controlling io.Connect Desktop from WebdriverIO. This allows you to create and run comprehensive end-to-end (E2E) tests for your io.Connect Desktop platform.

Running Tests

Tests are written in the tests/ folder and can be executed using:

# Run all tests
npm test

# Or using the WebdriverIO CLI directly
npx wdio run ./wdio.config.ts

Writing Tests

Tests are written using WebdriverIO syntax with the io.Connect Desktop service handling app lifecycle. Example test structure:

describe("io.Connect Desktop Platform", () => {
    it("should launch successfully", async () => {
        // Your test logic here.
        // The @interopio/wdio-iocd-service handles starting/stopping io.Connect Desktop.
    });
});

Add your test files to the tests/ directory. They'll run automatically in CI/CD pipelines.

Building for Production

The build process creates production-ready installers for distribution. It orchestrates multiple steps to produce signed, optimized packages ready for deployment.

What happens during build:

  1. Build all apps - Executes build scripts for each app in production mode
  2. Reinstall components - Downloads and installs fresh component versions
  3. Apply all modifications - Copies base and build-specific modifications to components
  4. Code sign binaries - Signs executables and libraries (if configured)
  5. Create build artifacts - Generates installers (.exe setup on Windows, .dmg on macOS, .zip archives)
  6. Publish to release server - Uploads artifacts for auto-updates (if configured)

Build System:

The build process is based on Electron Forge, a complete toolchain for building and packaging Electron apps. The main configuration is located in /config/forge.config.js, where you can customize makers, publishers, and build behavior.

Build Commands

# Build installer
iocd build

# Or using npm script
npm run build

# Build options
iocd build --output custom/path         # Custom output directory
iocd build --publish-only               # Skip build, only publish
iocd build --skip-install               # Skip component installation

Build Output

Depending on the OS, you can configure Electron Forge makers to produce different types of artifacts. The following configurations have been tested:

Windows

  1. Squirrel.Windows installer (.exe setup)
  • You can change the install GIF by replacing the install.gif in assets folder.
  • The app will be installed into %LocalAppData%\YourAppName. Squirrel is opinionated and does not allow changing this path.
  • By default the UserData folder generated by the platform will stay in %LocalAppData%\interop.io\io.Connect Desktop folder. You can change this by add the following system.json.merge-win32 file in modifications/base/iocd/config/system.json.merge-win32 (the merge file has win32 suffix which indicates it is only applied on Windows OS):
{
    "paths": {
        "userData": "%LocalAppData%/${PRODUCT_SLUG}/UserData/%IO_CD_ENV%-%IO_CD_REGION%",
        "cache": {
            "location": "%LocalAppData%/${PRODUCT_SLUG}/Cache/%IO_CD_ENV%-%IO_CD_REGION%",
            "copy": true
        }
    }
}
  1. Portable ZIP archive

macOS

  1. DMG disk image

  2. ZIP archive

The full list of makers is available in the Electron Forge documentation.

Code Signing

Code signing ensures that your app is trusted by operating systems and users can verify that it hasn't been compromised. Both Windows and macOS require code signing for distribution.

The settings for code signing are located under the "codeSign" property of the "win" top-level key for Windows and the "mac" top-level key for macOS in the iocd.cli.config.json seed project configuration file.

Windows

The "type" property of the "codeSign" object under the "win" top-level key accepts the following values:

Value Description
"custom" Use a custom signing script.
"signtool" Use a certificate and a sign tool to sign. The certificate can be retrieved from a PFX certificate file or from the Windows Certificate Store.
"off" Disable code signing.
  • PFX Certificate File

The is the most common method for code-signing on Windows. It uses a PFX certificate with a password. The PFX file contains both the certificate and the private key needed by the sign tool.

To configure signing via a PFX certificate file, provide the path to the file and the PFX password:

// In `config/iocd.cli.config.json`.
{
    "win": {
        "codeSign": {
            "type": "signtool",
            "pfxPath": "path/to/certificate.pfx",
            "pfxPassword": "${WIN_PFX_PASS}"
        }
    }
}
  • Certificate from the Windows Certificate Store

This method uses a certificate that already exists in the Windows Certificate Store. This is the approach you would use with services like DigiCert KeyLocker. For instance, with KeyLocker, you sync the certificate into the local Windows Certificate Store and sign using the certificate hash. The advantage is that the private key never leaves the HSM which is good for more security-sensitive environments.

To configure signing via a certificate from the Windows Certificate Store, provide the certificate SHA-1:

// In `config/iocd.cli.config.json`.
{
    "win": {
        "codeSign": {
            "type": "signtool",
            "certificateSha1": "${WIN_CERT_SHA1}"
        }
    }
}

When configuring your code signing settings, consider the following:

⚠️ Note that if using DigiCert KeyLocker, you must run smctl windows certsync before building to sync certificates to the Windows Certificate Store.

  • Custom Script

For advanced signing scenarios, you can provide a custom signing script:

// In `config/iocd.cli.config.json`.
{
    "win": {
        "codeSign": {
            "type": "custom",
            "customCodeSignScriptPath": "path/to/custom-sign.js"
        }
    }
}

Your custom script should export a function that receives the binary path and config:

// custom-sign.js
module.exports = async function(binaryPath, config) {
    // Your custom signing logic here.
    console.log(`Signing ${binaryPath}`);
    // Use any signing tool or API you need.
};

macOS

On macOS the process is a little different and more tightly controlled. It also requires an extra step called notarization.

Code Signing Configuration

The "type" property of the "codeSign" object under the "mac" top-level key accepts the following values:

Value Description
"certificate" Use a .p12 certificate file.
"custom" Use a custom signing script.
"keycahin" Use a certificate from macOS Keychain.
"off" Disable code signing.
  • Keychain

This methods uses a certificate from macOS Keychain. This is the mode to use if you want to use an Apple Developer ID certificate. You must download the certificate from the Apple Developer Portal, import it into your Keychain, and it will become available for code signing tools.

// In `config/iocd.cli.config.json`.
{
    "mac": {
        "codeSign": {
            "type": "keychain",
            "identity": "Developer ID Application: Your Company (TEAM_ID)"
        }
    }
}

You can use the following properties of the "codeSign" object to specify your Developer ID Application identity and Keychain to use:

Property Type Description
"identity" string Developer ID Application identity or SHA-1 hash (optional, auto-selected if not specified).
"keychain" string Keychain name or path (optional, uses the default Keychain if not specified).
  • Certificate

This method uses a .p12 certificate file that's imported into a temporary keychain during the build. The temporary keychain is removed after the build.

// In `config/iocd.cli.config.json`.
{
    "mac": {
        "codeSign": {
            "type": "certificate",
            "certificatePath": "./certs/mac-cert.p12",
            "certificatePassword": "${MAC_CERT_PASSWORD}"
        }
    }
}
  • Custom Script

For advanced signing scenarios, you can provide a custom signing script:

// In `config/iocd.cli.config.json`.
{
    "mac": {
        "codeSign": {
            "type": "custom",
            "customCodeSignScriptPath": "path/to/custom-sign.js"
        }
    }
}

Your custom script should export a function that receives the app bundle path and config:

// custom-sign.js
module.exports = async function(appBundlePath, config) {
  // Your custom signing logic here
  console.log(`Signing ${appBundlePath}`);
  // Use any signing tool or API you need
};

Notarization Configuration

Notarization is required for distributing any macOS app outside the App Store. This is how Apple verifies that the app is safe and hasn't been compromised. If an app isn't notarized, users will see warnings or may not be able to run it at all.

The notarization settings are located under the "notarization" property of the "mac" top-level key:

// In `config/iocd.cli.config.json`.
{
    "mac": {
        "notarization": {
            "type": "notarytool",
            "appleId": "${MAC_NOTARIZATION_APPLE_ID}",
            "appleIdPassword": "${MAC_NOTARIZATION_APPLE_ID_PASSWORD}",
            "appleTeamId": "${MAC_NOTARIZATION_APPLE_TEAM_ID}"
        }
    }
}

⚠️ Note that when configuring your notarization settings, you should consider the following:

  • Notarization is required for distribution outside the Mac App Store.
  • Use an app-specific password (not your regular Apple ID password).
  • Generate an app-specific password at appleid.apple.com.
  • You can set "type" to "off" to skip notarization (for development builds).
  • Custom Script

For advanced notarization scenarios, you can provide a custom notarization script:

{
    "mac": {
        "notarization": {
            "type": "custom",
            "customNotarizationScriptPath": "path/to/custom-notarize.js"
        }
    }
}

Your custom script should export a function that receives the app bundle path and config:

// custom-notarize.js
module.exports = async function(appBundlePath, config) {
    // Your custom notarization logic here.
    console.log(`Notarizing ${appBundlePath}`);
    // Use any notarization tool or API you need.
};

CI/CD Automation

Continuous Integration and Continuous Deployment (CI/CD) automates building, testing, and publishing your io.Connect Desktop platform. The seed project includes a GitHub Actions workflow located in .github/workflows/build.yml. It produces signed installers and can publish them to a release server.

Auto Updates

Setting up auto updates allows your users to automatically receive new versions of your platform.

Requirements:

Auto-updates are supported for specific build artifact types:

  • Windows: Squirrel.Windows installers (.exe setup files)
  • macOS: DMG on macOS

Other build outputs (portable ZIP on Windows, ZIP on macOS) do not support automatic updates.

Execute the following steps to setup the platform auto updates:

  1. Set up a release server.

You can use existing solutions or build your own:

  • Existing services: Nucleus, Hazel, or other update servers (see Electron update services)
  • Custom solution: Build your own update server following Squirrel protocols
  1. Configure io.Connect Desktop to check the update server.

Create or modify modifications/base/iocd/config/system.json.merge:

{
    "autoUpdater": {
        "enabled": true,
        "updateSource": {
            "type": "Service",
            "baseUrl": "https://updates.yourcompany.com"
        },
        "updateIntervalMinutes": 60
    }
}
  1. Publish updates.

Choose one of the following approaches:

Automatic publishing during build - configure publishers in config/forge.config.js:

module.exports = {
    publishers: [
        {
            name: "@electron-forge/publisher-electron-release-server",
            config: {
                baseUrl: "https://updates.yourcompany.com",
                username: process.env.RELEASE_SERVER_USERNAME,
                password: process.env.RELEASE_SERVER_PASSWORD
            }
        }
    ]
};

Manual upload - after building, manually upload the installer artifacts to your release server.

  1. Test the auto updates.
  • Install your platform using the signed installer
  • Publish a new version to your update server
  • Launch the platform and verify it detects and installs the update

CLI

To be able to create and use a seed project, you must install the io.Connect CLI via the @interopio/iocd-cli library:

npm install -g @interopio/iocd-cli@latest

You can also use npx to directly execute package commands:

npx @interopio/iocd-cli@latest create

The io.Connect CLI provides various commands for creating and manipulating a seed project for io.Connect Desktop.

Commands

The io.Connect CLI offers the following main commands:

Command Description
apps Command with sub-commands for managing the customizable system apps in the seed project.
build <options> Builds and packages the io.Connect Desktop platform for distribution.
components Command with sub-commands for managing the seed project components.
create <options> Creates a new seed project. Accepts options for configuring the seed project.
dev Starts io.Connect Desktop in development mode (the platform isn't packaged yet).
help <command> Displays help for the specified command.
license Displays current license key information.
modifications Command with sub-commands for managing the seed project modifications.
setup Prepares the seed project for first usage. This will install the specified components and will install the dependencies for all customizable system apps.
test Runs the test suite.

create

The create command accepts the following options:

Option Description
--source <url/path> Override component source during setup
--non-interactive Run in non-interactive mode using provided options
--product-name <name> Product name for non-interactive mode
--folder-name <name> Folder name for non-interactive mode
--components <components> Comma-separated list of components (e.g., "iocd,demos,devTools")
--applications <applications> Comma-separated list of apps (e.g., "groups,workspaces")
--license-key <key> License key for non-interactive mode
--use-current-folder Install in current folder (non-interactive mode)
-h, --help Display help for command

build

The build command accepts the following options:

Option Description
--output <path> Output directory for packages (default: "dist/packages")
--publish-only Skip the build phase and only publish packages (does nothing if no publish is configured) (default: false)
--skip-install Skip installing components during the build process (default: false)
-h, --help Display help for command

components

The components command has the following sub-commands:

Command Description
uninstall <name> Remove a component from the project
install [name] Install all components listed in iocd.cli.config.json or a specific component by name
list List all installed components
browse Browse all available components from currently selected store
pin Pin all "latest" component versions to their current specific versions for reproducible builds
download [options] [output-dir] Download all available components (including prereleases) for all platforms from the current store to a local directory in local store format (-f, --force Overwrite existing files without prompting)
help [command] Display help for command

apps

The apps command has the following sub-commands:

Command Description
install [options] Install dependencies for all template apps
build [options] Build all template apps and copy output to modifications folder. Requires prior installation of dependencies.
dev [options] Start all template apps in development mode
list List all template apps that are added to the seed project, and all available templates
add <appName> Add a new template app from the registry
help [command] Display help for command

modifications

The modifications command has the following sub-commands:

Command Description
apply [component] Apply all modifications or modifications for specific component
help [command] Display help for command

Troubleshooting

This guide addresses common issues when running the io.Connect Desktop CLI

1. Node.js SSL/TLS Certificate Errors

Symptoms:

  • SELF_SIGNED_CERT_IN_CHAIN errors
  • unable to verify the first certificate
  • CLI cannot connect to GitHub or npm registry

Root Cause: Corporate proxies often intercept HTTPS traffic and re-sign requests with an internal certificate. Node.js doesn't trust these certificates by default, causing HTTPS requests to fail.

Solutions:

Starting from Node.js 24, Node uses the operating system's trust store. If your corporate certificate is already trusted by your OS (which is usually the case), no manual configuration is needed.

# Check your Node.js version
node --version

# If below v24, upgrade Node.js

For Node.js 24+, you can also explicitly enable system certificates:

Windows (PowerShell - current session):

$env:NODE_OPTIONS = "--use-system-ca"
npm run setup

Windows (PowerShell - permanent for current user):

[Environment]::SetEnvironmentVariable("NODE_OPTIONS", "--use-system-ca", "User")
# Restart your terminal for changes to take effect

macOS/Linux (current session):

NODE_OPTIONS="--use-system-ca" npm run setup

macOS/Linux (permanent):

# Add to your shell profile (~/.zshrc or ~/.bashrc)
echo 'export NODE_OPTIONS="--use-system-ca $NODE_OPTIONS"' >> ~/.zshrc
source ~/.zshrc

Option B: Disable TLS Verification (Development Only)

⚠️ Warning: This disables security checks. Use only in development environments.

Windows (PowerShell - current session):

$env:NODE_TLS_REJECT_UNAUTHORIZED = "0"
npm run setup

Windows (PowerShell - permanent for current user):

[Environment]::SetEnvironmentVariable("NODE_TLS_REJECT_UNAUTHORIZED", "0", "User")
# Restart your terminal for changes to take effect

macOS/Linux (current session):

NODE_TLS_REJECT_UNAUTHORIZED=0 npm run setup

macOS/Linux (permanent - not recommended):

echo 'export NODE_TLS_REJECT_UNAUTHORIZED=0' >> ~/.zshrc
source ~/.zshrc

2. Node.js Proxy Configuration Issues

Symptoms:

  • npm run setup fails with network errors
  • GitHub API requests fail even though the browser can access GitHub
  • ECONNREFUSED or timeout errors
  • CLI cannot download components from GitHub
  • "Network error: fetch failed" with retries

Root Cause: Node.js does not automatically use system proxy settings (WinHTTP on Windows, system preferences on macOS). Even if your browser works behind a proxy, Node.js applications need explicit proxy configuration.

Solution:

The CLI (version 0.0.54+) automatically detects and uses your system proxy settings. If you're experiencing proxy-related issues, ensure you're running the latest version of the CLI:

npm i @interopio/iocd-cli@latest

After updating, run the setup command again. The CLI will automatically route requests through your system's configured proxy.

Verification:

If you want to verify your proxy settings are correctly configured at the system level:

Windows (PowerShell):

# Check system proxy (WinHTTP)
netsh winhttp show proxy

# Test if GitHub API is reachable
curl https://api.github.com/repos/interopio/iocd-components/releases?per_page=1

macOS/Linux:

# Check network configuration
scutil --proxy

# Test connectivity
curl -I https://api.github.com

If the browser/curl works but the CLI still fails after updating, there may be a TLS certificate issue (see next section).

3. npm Registry Errors

Symptoms:

  • E400 Bad Request when installing packages
  • npm error 400 Bad Request - GET https://registry.npmjs.org/@interopio%2f...
  • Timeouts when downloading npm packages

Root Cause: npm uses its own SSL policy and doesn't automatically inherit Node.js TLS settings. Corporate proxies may also block or interfere with npm registry requests.

Solutions:

Disable npm Strict SSL

npm config set strict-ssl false

Configure Corporate npm Registry

If your organization has an internal npm registry or proxy:

# Set your corporate registry
npm config set registry https://your-corporate-registry.com/

# Or use a scoped registry for @interopio packages
npm config set @interopio:registry https://registry.npmjs.org/

View Current npm Configuration

npm config get registry
npm config list

4. npm Proxy Configuration

Symptoms:

  • npm install fails with ECONNREFUSED or timeout errors
  • Package downloads hang or fail while CLI operations (like downloading components) work fine
  • npm ERR! network errors during dependency installation

Root Cause: The CLI uses its own HTTP client with automatic proxy support from environment variables. However, npm has its own network stack and may not inherit these settings. npm requires explicit proxy configuration through its own config system.

Solution:

The CLI automatically uses proxy settings from HTTP_PROXY/HTTPS_PROXY environment variables for its own network operations (downloading components from GitHub). However, npm package installations are handled by npm itself, which may need separate proxy configuration:

npm config set proxy http://your-proxy-server:port
npm config set https-proxy http://your-proxy-server:port

Note: In most enterprise environments, IT departments already configure HTTP_PROXY/HTTPS_PROXY environment variables system-wide. If these are set, the CLI will use them automatically. Check with your IT team if you're unsure whether these are configured.

5. Build fails with "License not found":

  • Ensure that the IOCD_LICENSE_KEY environment variable is set or create an iocd.license.key file in the /config folder with your license key.

6. Code signing fails on Windows:

  • Verify that the certificate is valid and not expired.
  • Check that "pfxPassword" is set correctly.
  • Verify that exactly one of "pfxPath" or "certificateSha1" is configured (not both).

7. Notarization for macOS fails:

  • Use an app-specific password, not a regular Apple ID password.
  • Generate an app-specific password at appleid.apple.com.
  • Verify that your Apple Developer Program membership is active.
  • Ensure that "appleTeamId" matches your Developer Team ID.

8. The platform won't start in development mode:

  • Run iocd setup to verify component installation.
  • Verify that that the components/iocd directory exists.
  • Review the logs in the system /temp directory.

9. Components not downloading:

  • Verify network connectivity.
  • Verify the component store configuration in the iocd.cli.config.json file located in the /config folder.
  • For GitHub stores: ensure that the repository access and credentials are correct.