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.
- 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 createAlternatively, you can use npx to execute the create package command directly:
npx @interopio/iocd-cli@latest create- 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.
- Install the necessary dependencies for the seed project:
npm install- 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- 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- 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 buildProject 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.mdComponents
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.jsonfile. The schema is located in the/node_modules/@interopio/iocd-cli/dist/schemasfolder. Add a$schemaproperty 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.keyfile in your project repository to prevent leaking your license key. By default, this file is ignored in the.gitignoresettings.
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 devoriocd 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:
- Base modifications (
modifications/base/) are applied first - Mode-specific modifications (
modifications/dev/ormodifications/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.replacemarker - 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.mergeThe following example demonstrates how to enable auto updates:
{
"autoUpdater": {
"enabled": true,
"updateSource": {
"type": "Service",
"baseUrl": "https://updates.yourcompany.com"
},
"interval": 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
.mergeextension to deep merge with existing configuration. - Without
.merge, the file completely replaces the original. - Changes are applied when running
iocd devoriocd 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 --availableAvailable templates:
workspaces- Workspace managementgroups- Window groupingsplash-screen- Loading screenlaunchpad- 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 devornpm run dev): Executes astartscript (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 buildornpm run build): Executes abuildscript (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) andmodificationsarray - build: Object with optional
script(npm script name) andmodificationsarray
Managing Apps
# Install app dependencies
iocd apps install
# Start apps in dev mode
iocd apps dev
# Build apps for production
iocd apps buildDevelopment
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:
- Apply all relevant modifications - Base modifications and dev-specific modifications are copied to components
- Start all apps - Runs the dev script for each app (typically starting dev servers with hot-reload)
- 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 devInstalling & 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.tsWriting 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:
- Build all apps - Executes build scripts for each app in production mode
- Reinstall components - Downloads and installs fresh component versions
- Apply all modifications - Copies base and build-specific modifications to components
- Code sign binaries - Signs executables and libraries (if configured)
- Create build artifacts - Generates installers (
.exesetup on Windows,.dmgon macOS,.ziparchives) - 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 installationBuild Output
Depending on the OS, you can configure Electron Forge makers to produce different types of artifacts. The following configurations have been tested:
Windows
- Squirrel.Windows installer (
.exesetup)
- 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
}
}
}- Portable ZIP archive
macOS
- DMG disk image
- 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 it hasn't been tampered with. Both Windows and macOS require code signing for distribution.
Windows
PFX Certificate File
Using a PFX certificate file:
{
"win": {
"codeSign": {
"type": "signtool",
"pfxPath": "path/to/certificate.pfx",
"pfxPassword": "${WIN_PFX_PASS}"
}
}
}Certificate Store
You can also use a certificate store (e.g., DigiCert KeyLocker):
{
"win": {
"codeSign": {
"type": "signtool",
"certificateSha1": "${WIN_CERT_SHA1}"
}
}
}When configuring your code signing settings, consider the following:
- If using DigiCert KeyLocker, run
smctl windows certsyncbefore building to sync certificates to Windows store. - Either
"pfxPath"or"certificateSha1"must be provided (not both). - You can set
"type"to"off"to disable code signing.
Custom Script
For advanced signing scenarios, you can provide a custom signing script:
{
"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
Code Signing Configuration
{
"mac": {
"codeSign": {
"type": "keychain",
"identity": "Developer ID Application: Your Company (TEAM_ID)"
}
}
}Options:
"type":"keychain"(use keychain certificate),"certificate"(use.p12file),"custom"(custom script), or"off"(no signing)"identity": Developer ID Application identity or SHA-1 hash (optional, auto-selected if not specified)"keychain": Keychain name or path (optional - uses default keychain if not specified)
Custom Script
For advanced signing scenarios, you can provide a custom signing script:
{
"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
{
"mac": {
"notarization": {
"type": "notarytool",
"appleId": "${MAC_NOTARIZATION_APPLE_ID}",
"appleIdPassword": "${MAC_NOTARIZATION_APPLE_ID_PASSWORD}",
"appleTeamId": "${MAC_NOTARIZATION_APPLE_TEAM_ID}"
}
}
}When configuring your notarization settings, 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 (
.exesetup 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:
- 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
- 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"
},
"interval": 60
}
}- 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.
- 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@latestYou can also use npx to directly execute package commands:
npx @interopio/iocd-cli@latest createThe 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
Build fails with "License not found":
- Ensure that the
IOCD_LICENSE_KEYenvironment variable is set or create aniocd.license.keyfile in the/configfolder with your license key.
Code signing fails on Windows:
- Verify that the certificate is valid and not expired.
- Check that
"pfxPassword"is set correctly. - For certificate store signing: ensure that
smctl windows certsynchas been run first. - Verify that exactly one of
"pfxPath"or"certificateSha1"is configured (not both).
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.
The platform won't start in development mode:
- Run
iocd setupto verify component installation. - Verify that that the
components/iocddirectory exists. - Review the logs in the system
/tempdirectory.
Components not downloading:
- Verify network connectivity.
- Verify the component store configuration in the
iocd.cli.config.jsonfile located in the/configfolder. - For GitHub stores: ensure that the repository access and credentials are correct.