Configuration Reference
Oidis Builder uses a layered configuration system. Configuration is defined in JSONP files — JSON extended with C-style comments and Builder preprocessing directives.
JSONP Format
JSONP is Oidis Builder's configuration format. It extends JSON with:
- C-style comments — both
// line commentsand/* block comments */are allowed anywhere - Builder preprocessing expressions —
<? @var name ?>substitutes variables at build time - Arithmetic in expressions —
<? @var build.year ?>inserts the current year during build
{
// This is a valid comment
"name": "my-project",
"version": "2026.0.1",
"license": "Copyright 2025-<? @var build.year ?> Acme Corp.",
/* Block comment:
Can span multiple lines */
"target": {
"name": "MyApp"
}
}
JSONP files have the .jsonp extension. The builder also accepts plain .json files (comments not supported).
Configuration File Hierarchy
The builder loads configuration in the following order (later layers override earlier ones):
1. Builder global config (~/.oidis/config or builder's own commons.jsonp)
2. package.conf.jsonp (project root — committed to git)
3. imported configs (via "imports" directive)
4. solution config (active solution from "solutions" map)
5. private.conf.jsonp (project root — NOT committed to git)
Never commit private.conf.jsonp to git. It contains machine-specific paths, credentials, and developer overrides. Add it to .gitignore under the "Project individual ignore patterns" section at the bottom.
package.conf.jsonp — Project Configuration
Located at the project root. Defines the project identity, dependencies, build targets, and deployment settings. Validated against a JSON schema by the builder.
The file must be wrapped in the JSONP loader call:
Io.Oidis.Builder.DAO.Resources.Data({
$interface: "IProjectSolution",
// ... your configuration ...
});
Top-level Fields
| Field | Type | Description |
|---|---|---|
name | string | Project identifier (used as package name) |
version | string | Project version in calendar format (YYYY.M.patch) |
description | string | Human-readable description |
homepage | string | Project website URL |
repository | string or object | Git repository URL |
author | object | Author info: { name, email, organization } |
license | string | License text or SPDX identifier |
loaderClass | string | Fully qualified class name of the application Loader |
guiLoaderClass | string | Fully qualified class name of the GUI Loader (optional) |
schema | string | Path to a custom JSON schema for validation |
noServer | boolean | Disable the built-in development server |
noCompress | boolean | Disable JS/CSS minification even in prod builds |
lintErrorsAsWarnings | boolean | Treat lint errors as warnings (don't fail the build) |
dependencies
Defines project dependencies — other repositories or packages to install under <project>/dependencies/.
Connection string form:
"dependencies": {
"io-oidis-commons": "git+https://gitlab.com/oidis/io-oidis-commons.git#develop",
"io-oidis-gui": "git+https://gitlab.com/oidis/io-oidis-gui.git#2026.0.1",
"my-local-dep": "dir+D:/workspace/my-local-dep"
}
Connection string format: [type]+[url/path]{#[branch/tag]}
| Type | Description |
|---|---|
git | Clone from a Git repository (supports http://, https://, ssh://, git://) |
dir | Use a locally cloned directory (path must be absolute) |
Detailed dependency form:
"dependencies": {
"my-cpp-lib": {
"version": "1.2.0",
"location": {
"type": "git",
"path": "https://example.com/my-cpp-lib.git",
"branch": "main"
},
"install-script": {
"name": "build.js",
"path": "resource/scripts/",
"attributes": ["--release"],
"ignore-parent-attributes": false
},
"configure-script": {
"name": "configure.cmake",
"attributes": ["-DCMAKE_BUILD_TYPE=Release"]
},
"platforms": ["win", "linux"]
}
}
Platform-specific dependency paths (in private.conf.jsonp):
"dependencies": {
"my-native-lib": {
"location": {
"type": "dir",
"path": {
"win": "D:/libs/my-native-lib-win",
"linux": "/home/user/libs/my-native-lib-linux",
"mac": "/Users/user/libs/my-native-lib-mac"
}
}
}
}
Architecture-specific paths:
"path": {
"win": {
"x32": "D:/libs/my-lib-win32",
"x64": "D:/libs/my-lib-win64"
}
}
imports
Include other JSONP config files. The builder merges them into the project config:
"imports": {
"commons": "bin/project/configs/commons.jsonp",
"licensesRegister":"bin/project/configs/licensesRegister.jsonp",
"deploy": "bin/project/configs/deploy.jsonp"
}
Import keys are arbitrary labels — they only serve to differentiate the entries. Import paths are relative to the project root.
Use imports to split large configurations into logical files. Keep credentials in private.conf.jsonp and share tool settings via imported files in bin/project/configs/.
solutions
Named build configurations. The active solution is selected via --solution=<name> or the solutionsLocation field.
"solutions": {
"default": "static",
"app": "bin/project/solutions/app.jsonp",
"static": "bin/project/solutions/static.jsonp",
"arm": "bin/project/solutions/arm.jsonp",
"winInstaller":"bin/project/solutions/winInstaller.jsonp"
}
When the value is another key within the solutions map, it is followed as an alias (e.g., "default": "static" means the default solution is static).
When a solution is selected, its JSONP file is loaded and merged into the project configuration after package.conf.jsonp.
target
Target application configuration. Controls what the build produces.
"target": {
"name": "MyApp",
"copyright": "Copyright 2025-<? @var build.year ?> Acme Corp.",
"toolchain": "nodejs",
"toolchainSettings": {
"version": "module"
},
"platforms": ["win", "linux", "mac"],
"icon": "resource/graphics/icon.ico",
"width": 1280,
"height": 800,
"maximized": false,
"elevate": false,
"singletonApp": true,
"startPage": "index.html",
"appDataPath": "%APPDATA%/MyApp",
"resources": {
"myFiles": {
"input": "resource/data/**/*",
"output": "data/**/*",
"skipReplace": true
}
}
}
toolchain values:
| Value | Description |
|---|---|
nodejs | Node.js / JavaScript application |
gcc | C/C++ with GCC |
clang | C/C++ with Clang/LLVM |
msvc | C/C++ with MSVC (Windows) |
arm | Cross-compile for ARM |
aarch32 | Cross-compile for AArch32 |
aarch64 | Cross-compile for AArch64 |
java | Java/Maven project |
python | Python project |
toolchainSettings (for C++ toolchains):
| Field | Description |
|---|---|
version | Module system (module for ES modules) |
cmakeToolchain | Path to CMake toolchain file |
cmakeOptions | Additional CMake options array |
cmakeGenerator | CMake generator name |
initScript | Init script path |
CC, CXX, LD, etc. | Compiler/linker overrides |
CFLAGS, CXXFLAGS, LDFLAGS | Compiler flag overrides |
SYSROOT | Cross-compilation sysroot path |
types | TypeScript type declarations to include |
serverless | Disable server (for embedded targets) |
withDependenciesScan | Enable dependency scanning |
resources entries (each is a named resource set):
| Field | Type | Description |
|---|---|---|
input | string | Glob pattern for source files |
output | string | Destination path/pattern |
files | array | Array of { src, dest } explicit file mappings |
embed | boolean | Embed into the binary |
copy | boolean | Copy without processing |
skipReplace | boolean | Skip variable replacement during copy |
resx | boolean | Treat as Windows resource file |
keepLinks | boolean | Preserve symbolic links |
platforms | string[] | Restrict to specific platforms |
protect | string | boolean | Obfuscation settings |
postBuildCopy | boolean | Copy after build completes |
toolchain | string | string[] | Restrict to specific toolchains |
deploy
Deployment server configuration.
"deploy": {
"server": {
"prod": {
"location": "https://hub.oidis.io",
"user": "",
"pass": ""
},
"dev": {
"location": "https://hub.dev.oidis.io",
"user": "",
"pass": ""
},
"eap": {
"location": "https://hub.eap.oidis.io",
"user": "",
"pass": ""
}
},
"agentsHub": "https://services.oidis.io",
"chunkSize": 0,
"user": "",
"pass": ""
}
Keep user and pass empty in package.conf.jsonp. Override them in private.conf.jsonp with your actual credentials — that file is never committed.
docs
Documentation generation settings.
"docs": {
"systemName": "MyProject Docs",
"copyright": "Copyright 2026 Acme Corp.",
"htmlOutput": "build/target/docs"
}
modules
Custom script modules that integrate with the builder task system. See Module System for full details.
"modules": {
"my-hook": {
"script": "resource/scripts/my-hook.js",
"args": [],
"interpreter": "node",
"overrideTask": false,
"events": {
"before": "compile",
"after": ["typescript", "sass-compress"]
}
}
}
runConfigs
Named configurations for oidis run. Selected via --run-config=<name>.
"runConfigs": {
"default": {
"release": "dev",
"platform": "app-win-nodejs",
"port": 3000,
"args": []
},
"demo": {
"release": {
"name": "myRelease",
"platform": "app-linux-nodejs"
}
}
}
private.conf.jsonp — Machine-Specific Overrides
Located at the project root alongside package.conf.jsonp. Never committed to git.
Contains machine-specific overrides: local dependency paths, credentials, and developer-specific settings. Every field from package.conf.jsonp can be overridden here.
Common use cases:
Io.Oidis.Builder.DAO.Resources.Data({
$interface: "IProjectSolution",
// Override dependency to a local clone
"dependencies": {
"io-oidis-commons": "dir+D:/workspace/io-oidis-commons"
},
// Credentials for deploy servers
"deploy": {
"server": {
"dev": {
"user": "myuser",
"pass": "mytoken"
}
}
},
// Where to find the default solution
"solutionsLocation": "D:/deployed-apps/myproject"
});
| Field | Description |
|---|---|
solutionsLocation | Path where the default solution is deployed (used by oidis run) |
solutions | Override solution paths with local paths |
dependencies | Override dependency sources with local clones |
Builder Global Configuration (commons.jsonp)
The builder ships a global commons.jsonp that provides default values shared across all Oidis projects. Projects typically inherit it via imports.
Key global settings (configured in builder's commons.jsonp, overridable in your private.conf.jsonp):
| Field | Type | Description |
|---|---|---|
deployServer | object | Default deploy server URLs for prod, dev, eap |
deployCredentials | object | Credentials for each deploy server profile |
deployAgentsHub | string | URL of the agents hub |
servicePort | number | Port for Builder service mode (default: 3666) |
hub | object | Oidis Hub connection: { url, user, pass } |
cloud | object | Cloud sync: { url, syncBase } |
dockerRegistry | object | Docker registry: { url, user, pass, email } |
workspaces | object | Named path aliases (e.g., { "MY_WORKSPACE": "D:/projects" }) |
symbols | object | Custom variable substitutions for JSONP preprocessing |
vcvarsPath | string | Path to MSVC vcvarsall.bat (Windows, required for C++ builds) |
noReport | boolean | Disable telemetry reports |
noSelfupdate | boolean | Disable automatic builder self-update checks |
noAutoinstall | boolean | Disable automatic dependency install on startup |
noExternalTypes | boolean | Disable external TypeScript type downloads |
dependenciesDownloadConfig | object | { maxRetry: 3, timeout: 5 } — retry and timeout for downloads |
ntfyConfig | object | Push notification settings for the ntfy-notify task (see below) |
ntfyConfig
Configuration for the ntfy-notify
task. ntfy is a simple open-source push notification service — self-hostable or
available as a free public service at https://ntfy.sh.
Default values are provided in the builder's commons.jsonp. Override them per project in
package.conf.jsonp, or per developer in private.conf.jsonp to use a personal topic.
// package.conf.jsonp — project-level overrides
"ntfyConfig": {
"server": "https://ntfy.sh",
"topic": "my-project-builds",
"title": "My Project Builder",
"priority": "default"
}
// private.conf.jsonp — personal override (never committed)
"ntfyConfig": {
"topic": "my-personal-phone-topic"
}
| Field | Type | Description |
|---|---|---|
server | string | ntfy server URL (default: https://ntfy.sh) |
topic | string | Channel/topic name subscribers listen to |
title | string | Notification title shown on the device |
priority | string | Message priority: min, low, default, high, urgent |
For private use, deploy your own ntfy instance (Docker image available) and point server to it.
This gives full control over retention, authentication, and access policies.
Workspace Aliases
Define workspace aliases to avoid absolute paths in shared config:
// In private.conf.jsonp or builder config:
"workspaces": {
"MAIN": "D:/projects",
"SHARED": "D:/shared-libs"
}
Then reference them in dependency paths:
"dependencies": {
"io-oidis-commons": "dir+[WORKSPACE_MAIN]/io-oidis-commons"
}
Symbols
Custom key-value substitutions available in JSONP preprocessing:
"symbols": {
"MY_ENV": "production",
"SERVER_URL": "https://myserver.io"
}
Reference in JSONP: <? @var symbols.MY_ENV ?>
Solution Files
Solutions define the final build target characteristics (platforms, runtimes, packaging). They extend package.conf.jsonp and are stored in bin/project/solutions/.
Standard solutions provided by builder:
| Solution | File | Description |
|---|---|---|
static | bin/project/solutions/static.jsonp | Static Node.js binary (pkg-packaged) |
app | bin/project/solutions/app.jsonp | Full desktop application with Chromium |
shared | bin/project/solutions/shared.jsonp | Shared library (not packaged) |
arm | bin/project/solutions/arm.jsonp | ARM cross-compiled binary |
winInstaller | bin/project/solutions/winInstaller.jsonp | Windows self-installer package |
To select a solution at build time:
oidis build prod --solution=arm
oidis build prod --solution=app
oidis rebuild --solution=winInstaller
Variable Substitution in JSONP
The builder performs variable substitution in JSONP string values using <? @var path.to.value ?> expressions. Available variables at build time:
| Variable | Value |
|---|---|
build.year | Current 4-digit year |
build.time | Build timestamp (ISO format) |
build.type | Build type (dev, eap, prod) |
build.releaseName | Active release name |
build.platform | Target platform identifier |
target.version | Project version from package.conf.jsonp |
target.name | Project name |
symbols.* | Custom symbols from config |
Extending the Config Schema
Every top-level config field added to IProject or IAppConfiguration must also be registered in
the JSON Schema so the validator can accept it. The builder validates all loaded configuration before
task execution using the z-schema library (JSON Schema Draft 4).
How the schema is assembled
EnvironmentArgs.loadSchema() builds the final schema in three steps:
- Loads
<builder>/resource/configs/default.conf.schema.json— the shared base schema (plain JSON) - Loads
<project>/bin/project/configs/package.conf.schema.jsonp— project-specific additions (JSONP) - Merges both with
Resources.Extend(defaultSchema, projectSchema)— project fields override/extend the defaults at every level
The project schema file supports an extendsConfig chain: each package can extend a dependency's
schema, building up an inherited hierarchy. The builder's own project schema extends
io-oidis-connector, which extends io-oidis-localhost, and so on.
Where to register a new field
A new top-level block (e.g. fooConfig) must appear in both files:
| File | Role |
|---|---|
resource/configs/default.conf.schema.json | Shared base — defines the type for all projects |
bin/project/configs/package.conf.schema.jsonp | Project additions — must also declare the field for the merge to include it |
Registering only in the .json base is not enough: if the project schema's properties section is
merged in via Resources.Extend, any key absent from the project schema's properties is silently
dropped from the merged result, causing a validation error.
The definition + $ref pattern
Use JSON Schema Draft 4 conventions. Complex config blocks belong in definitions and are referenced
by name with $ref:
// bin/project/configs/package.conf.schema.jsonp
Io.Oidis.Builder.DAO.Resources.Data({
// ...
definitions: {
// Define the shape of the new block:
IFooConfig: {
type: "object",
properties: {
url: { type: "string" },
timeout: { type: "integer", minimum: 0 },
enabled: { type: "boolean" }
}
}
},
properties: {
// ...existing properties...
// Reference the definition:
fooConfig: {
$ref: "#/definitions/IFooConfig"
}
}
});
The same definition must also appear in resource/configs/default.conf.schema.json:
{
"definitions": {
"IFooConfig": {
"type": "object",
"properties": {
"url": { "type": "string" },
"timeout": { "type": "integer", "minimum": 0 },
"enabled": { "type": "boolean" }
}
}
},
"properties": {
"fooConfig": { "$ref": "#/definitions/IFooConfig" }
}
}
nexusConfig / INexusConfig (lines 47–70 and 312–314 of package.conf.schema.jsonp) is the
canonical reference example for this pattern in the builder.
Validator behaviour
The builder uses z-schema with assumeAdditional: true, which means objects without an explicit
additionalProperties field in the schema are treated as open (any extra keys are allowed). However,
properties declared in a properties block are still type-checked against their schema. A field
that is present in the data but absent from the merged schema's properties triggers an
"Additional properties not allowed" error even with assumeAdditional: true, because the merge
can produce a schema that explicitly enumerates only a subset of properties.
See also: JSONP System | CLI Reference | Build Process