JSON Project Structure
Everything MPDEV needs to know about your installer lives in a single JSON file. Before filling in any property values, it helps to understand how this file is organized.
The three sections
Every JSON project has up to three sections:
{
"common properties go here": "...",
"msi": {
"MSI-specific properties go here": "..."
},
"msix": {
"MSIX-specific properties go here": "..."
}
}
Common section
Properties placed at the top level apply to both MSI and MSIX builds. This is where you put everything that is shared – package name, version, files, shortcuts, registry entries, and so on.
msi section
Properties placed inside "msi": { } apply only to the MSI build. Use this for MSI-specific features like upgradeCode, custom actions, or MSI install dialogs.
msix section
Properties placed inside "msix": { } apply only to the MSIX build. Use this for MSIX-specific features like capabilities, minimum OS version, or Package Support Framework configuration.
If you only build one output type, you still have the common section plus the matching per-output section.
Inheritance – how common and per-output sections combine
When MPDEV builds an output, it starts with everything from the common section and then layers the per-output section on top. The rule is simple:
Any property set in the per-output section replaces the common value for that output – regardless of whether it is a scalar, an object, or an array.
Example – override a scalar
{
"version": "1.0.0",
"msi": { "version": "1.0.0.42" },
"msix": { "version": "1.0.0.0" }
}
The MSI gets version 1.0.0.42. The MSIX gets version 1.0.0.0.
Example – override an array
{
"fileSystemEntries": [
{ "sourcePath": "build", "targetPath": "$.installDir" }
],
"msix": {
"fileSystemEntries": [
{ "sourcePath": "build", "targetPath": "$.installDir" },
{ "sourcePath": "extras\\msix-readme.txt",
"targetPath": "$.installDir\\readme.txt" }
]
}
}
The MSI ships only the build/ folder. The MSIX ships the build/ folder and the extra readme file – but you must list both entries explicitly because the per-output array replaces (not appends to) the common one.
How paths work
MPDEV uses paths in many places – file sources, install directories, icon locations, output folders. There are three ways to write a path.
Hardcoded (absolute) path
A full path on disk. Use this when you need to point to a fixed location:
"sourcePath": "C:\\BuildServer\\Artifacts\\MyApp.exe"
Relative path
A path relative to the working directory where mpdev runs. This is the most common way to reference your source files:
"sourcePath": "build\\MyApp.exe"
Relative source paths resolve from the working directory where mpdev is invoked, NOT from the JSON file's location. If your package.json lives in a subfolder, either:
- Run
mpdevfrom the parent directory, or - Use
--working-dirto point to the folder containing your source files.
Environment variable path
Use %VARIABLE% syntax to reference Windows environment variables. These are expanded at build time:
"installDir": "%ProgramFiles%\\MyApp"
Common variables you will use:
| Variable | Typical value |
|---|---|
%ProgramFiles% | C:\Program Files |
%CommonProgramFiles% | C:\Program Files\Common Files |
%ProgramData% | C:\ProgramData |
%MY_CUSTOM_VAR% | Whatever value you set before running mpdev |
You are not limited to standard Windows variables. Any environment variable you define yourself works the same way – for example %BUILD_NUMBER% or %MY_APP_VERSION% set in your CI pipeline or in a terminal session before running mpdev.
If an environment variable does not exist at build time, it is replaced with an empty string without error. Double-check your variable names if a value disappears unexpectedly.
To write a literal % that should not be expanded, double it: %%PERCENT%%.
Source paths vs target paths
MPDEV distinguishes between two kinds of paths:
| Source path | Target path | |
|---|---|---|
| Points to | A file or folder on your disk | A location inside the installed package |
| Allowed forms | Relative or absolute | Absolute only |
| Example | build\\MyApp.exe | %ProgramFiles%\\My App\\MyApp.exe |
Source paths are resolved relative to the working directory where mpdev runs. You can change this with the --working-dir CLI argument.
Cross-property references with $.
Instead of repeating the same value in multiple places, you can reference another property with the $.propertyName syntax:
{
"installDir": "%ProgramFiles%\\My Application",
"fileSystemEntries": [
{ "sourcePath": "build", "targetPath": "$.installDir" }
],
"shortcuts": [
{ "target": "$.installDir\\MyApp.exe" }
]
}
Here $.installDir resolves to %ProgramFiles%\\My Application everywhere it appears. If you later change the install directory, every reference updates automatically.
You can also override or create properties from the command line using the --properties flag:
mpdev build package.json --properties $.version=2.0.0 $.platform=x86
This is useful in CI pipelines where values change per build. Full details are in the CLI Reference.