Skip to main content

Seed Project

Overview

Use modifications to change component configuration, replace assets, and add app definitions without editing downloaded files. Store these changes in /modifications so that you can apply them again after a component update.

Folders & Processing Order

The following example demonstrates where to place modifications for the iocd component:

modifications/
├── base/
│   └── iocd/
│       ├── config/
│       │   └── apps/
│       └── assets/
├── dev/
│   └── iocd/
│       └── config/
└── build/
    └── iocd/
        └── config/

The CLI applies /modifications/base first, followed by /modifications/dev or /modifications/build for the selected mode. A file in the mode folder can therefore override a base modification. The directory structure beneath a component name matches the target structure inside that component.

Use /modifications/base/iocd/config/apps for app definitions and /modifications/base/iocd/assets for assets. Use the development and build folders when an app needs different URLs or settings in each mode.

The CLI resets tracked modifications before running dev or build, then applies the selected changes. Removing a modification source file also removes its tracked output when the modifications are reset and reapplied.

ℹ️ For additional examples, see Multi-Environment Builds in the io.Connect Seed Project and How to Avoid Overwriting Component App Definitions on the Developer Community site.

Replacing & Deleting Files

An ordinary file replaces the corresponding component file. Special filenames provide additional operations:

File Description
system.json.merge Merges the contents into system.json, preserving properties that aren't specified.
filename.delete Removes the corresponding filename from the component.
.replace Replaces the target directory with the contents of the modification directory containing this marker.
.delete Removes the target directory corresponding to the modification directory containing this marker.

JSON Merging

A .json.merge file recursively merges object properties into the corresponding JSON file. New properties are added, supplied values override existing ones, and omitted properties remain unchanged.

The following example demonstrates a merge into an app configuration file named settings.json. These settings belong to the example app and aren't platform configuration properties:

{
    "display": {
        "theme": "light",
        "showToolbar": true
    },
    "features": {
        "search": true
    }
}

To change the theme and enable notifications, create settings.json.merge:

{
    "display": {
        "theme": "dark"
    },
    "features": {
        "notifications": true
    }
}

The resulting settings.json will contain:

{
    "display": {
        "theme": "dark",
        "showToolbar": true
    },
    "features": {
        "search": true,
        "notifications": true
    }
}

Named Merge Files

Use a suffix after .json.merge- to separate changes targeting the same file:

system.json.merge
system.json.merge-autoUpdate
system.json.merge-launchpad
system.json.merge-myFeature

All these files target system.json. Base modifications are applied before modifications for the selected mode. Within each directory, files are processed in the order returned by the file system. Don't rely on the names to establish an ordering between conflicting merge files in the same directory.

Platform Selection

If the suffix contains darwin or win32, the merge file will apply only on that platform:

File Platform
system.json.merge-darwin macOS.
system.json.merge-win32 Windows.
system.json.merge-myFeature-win32 Windows.

Merge files without a platform identifier apply on both platforms.

Array Merging

Available since @interopio/iocd-cli 0.0.71

As of @interopio/iocd-cli 0.0.71, arrays are concatenated by default - e.g., merging {"apps": ["app3", "app4"]} into {"apps": ["app1", "app2"]} will produce {"apps": ["app1", "app2", "app3", "app4"]}. Earlier versions replaced the target array.

To select another operation, replace the array value in the merge file with a directive object:

Directive Description Example
"$append" Adds items to the end, matching the default behavior. {"apps": {"$append": ["app3"]}}
"$prepend" Adds items to the beginning. {"apps": {"$prepend": ["dashboard"]}}
"$remove" Removes matching items. {"apps": {"$remove": ["legacy-app"]}}
"$replace" Replaces the entire array. {"apps": {"$replace": ["only-this-app"]}}

⚠️ Note that if the target property is missing or isn't an array, the CLI sets it to the array in the directive, regardless of the directive type. A "$remove" directive for a missing property therefore adds the listed items.

For object values, "$remove" compares the result of JSON.stringify(). The complete serialized object must match, including property order. The following merge removes an object containing only the specified "name" property. It won't match an object with additional properties:

{
    "apps": {
        "$remove": [{ "name": "unwanted-app" }]
    }
}

Object and array modifications can be combined in one file. The following example demonstrates how to change an app setting, extend one array, remove an item from another, and prepend a startup app:

{
    "display": {
        "theme": "dark"
    },
    "features": {
        "enabledPlugins": ["my-plugin"],
        "disabledPlugins": { "$remove": ["old-plugin"] }
    },
    "startupApps": { "$prepend": ["dashboard"] }
}

System Configuration

To change platform settings, add a system.json.merge file in /modifications/base/iocd/config. Use the actual system configuration structure for the feature you are changing.

The following example demonstrates how to change the default logging category to "debug" while preserving its configured appenders and other categories:

{
    "logging": {
        "configuration": {
            "categories": {
                "default": {
                    "level": "debug"
                }
            }
        }
    }
}

For development only, place this file in /modifications/dev/iocd/config. To use "error" for production builds, add the same structure with "level": "error" in /modifications/build/iocd/config/system.json.merge. These files will be applied after the base modifications for their respective modes.

Use .json.merge when preserving unspecified defaults. A file named system.json will replace the entire configuration.

The CLI replaces ${<VARIABLE>} placeholders in copied .json files and in the files produced by .json.merge files. Files of other types are copied unchanged. The following variables are available:

Variable Description
${COMPONENTS_PATH} Folder containing the additional components. Resolves to %IO_CD_ROOT_DIR%/components in builds and to the seed /components folder in development mode. The platform expands %IO_CD_ROOT_DIR% at runtime.
${PRODUCT_NAME} Product name from the basic settings.
${PRODUCT_SLUG} Product slug from the basic settings.
${PRODUCT_VERSION} Product version from the basic settings.

Any other name is replaced with the value of the environment variable with that name. Names that don't match a variable are replaced with an empty string, so check the spelling of each placeholder. Backslashes in the values are converted to forward slashes.

ℹ️ For details on platform properties, see the Developers > Configuration > System section. For a complete auto update example, see the Publishing & Auto Updates section.

Icons & Images

The native app icon, tray icon, and platform branding images are controlled via the /modifications/base/iocd/assets/images folder. Create the /images folder if it doesn't exist, and add the image files you want to override.

Use the exact filenames in the following tables because the CLI, Electron Forge configuration, and platform runtime look for these paths during development and packaging.

Native App Icons

File Description Requirements
logo.ico Windows executable icon. The CLI embeds it into the main executable during npm run dev and npm run build. The Electron Forge Squirrel maker also uses it as the setup executable icon. Use a Windows .ico file with multiple sizes, such as 16x16, 32x32, 48x48, and 256x256.
logo.icns App icon for macOS. The CLI copies it into the <installation_location>/Resources folder and sets CFBundleIconFile to logo.icns. The Electron Forge DMG maker also uses it for the generated .dmg. Use a macOS .icns file with multiple sizes. You can create it with Icon Composer or iconutil.
logo.png Image asset used by the platform UI and branding. Use a PNG file, recommended size 512x512. This doesn't replace the native Windows .exe or macOS .app icon by itself.

On Windows, close any running instance of the app before running the command again, because the CLI has to patch the executable icon and metadata. If the Windows executable icon is stored somewhere else, update the "win.exe.exeIconPath" setting in config/iocd.cli.config.json or set the WIN_EXE_ICON_PATH environment variable. The default path is recommended because it also keeps the Squirrel installer icon aligned with the app icon.

On macOS, keep the file name logo.icns. The CLI expects this name when it updates the app bundle and signs the result.

Tray Icons

modifications/base/iocd/assets/
└── images/
    ├── tray-light.ico
    ├── tray-dark.ico
    ├── tray.ico
    ├── tray-alert-light.ico
    ├── tray-alert-dark.ico
    ├── tray-alert.ico
    ├── logo-alert.ico
    ├── trayTemplate.png
    ├── trayTemplate@2X.png
    ├── tray-alertTemplate.png
    └── tray-alertTemplate@2x.png

On Windows, the tray icon changes with the current platform theme:

State Lookup Order
Light theme tray-light.ico, then tray.ico, then logo.ico
Dark theme tray-dark.ico, then tray.ico, then logo.ico
Light theme with active notifications tray-alert-light.ico, then tray-alert.ico, then logo-alert.ico, then the current tray icon
Dark theme with active notifications tray-alert-dark.ico, then tray-alert.ico, then logo-alert.ico, then the current tray icon

On macOS, the platform uses template PNG files (monochrome icons) instead of .ico files:

State Lookup Order High-DPI Companion
Default trayTemplate.png trayTemplate@2X.png
Active notifications tray-alertTemplate.png, then the current tray icon tray-alertTemplate@2x.png

The alert tray icon is used only when the platform has active notifications, the notification badge is enabled, and the tray notifications item is enabled. The "tray" object in system.json controls whether the tray menu and its items are shown. It doesn't provide custom icon file names.

After replacing any of these files, run npm run dev to apply them in development mode, or npm run build to create a new package.