Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Project configuration

proton.project.json contains application identity and CLI build/package metadata. It is a JSON object with four recognized top-level fields. Unknown fields are rejected. Window state, command registration and capabilities belong to the MoonBit application builder, not this file.

The default filename is proton.project.json. To use another filename such as moon.proton.json, pass --config moon.proton.json to dev, build or package; it is not an automatically discovered alias.

Top-level fields

FieldTypeRequirement / meaning
identifierstringRequired, validated application identifier
backendobjectOptional at decoding; provides the CLI backend location and entry
frontendobjectOptional frontend command and asset configuration
packageobjectOptional distribution metadata; required for metadata-driven packaging

identifier is trimmed and must have at least two nonempty dot-separated components. Each component starts with an ASCII letter or digit and contains only ASCII letters, digits or hyphens.

A minimal configuration is:

{
  "identifier": "com.example.app",
  "backend": { "path": ".", "package": "app" }
}

Backend

When backend is present, both fields are required.

FieldTypeInterpretation
pathstringDirectory, resolved relative to the configuration directory
packagestringMoon package selector used from that directory

Frontend

All frontend fields are optional at decoding. Individual CLI commands impose additional requirements.

FieldTypeDefault / interpretation
pathstringConfiguration directory if omitted; command working directory
dev_urlstringNo default; development page URL
before_devstringNo default; frontend server command
before_buildstringNo default; frontend build command
diststringNo default; output directory, relative to frontend.path when specified

dev requires a frontend command when it manages a configured development URL. --no-frontend connects to an externally managed server. build runs the configured build command before validating the frontend output and building the backend. An existing occupied development endpoint is rejected when the CLI is responsible for starting its server.

Paths and resources

Backend/frontend paths, package icons, package resources and package output are resolved from the configuration directory. frontend.dist is resolved from the frontend directory. Absolute paths remain absolute. Path separators follow the host operating system. Loading configuration preserves path strings and does not require referenced files or directories to exist; build and packaging operations check the inputs they use.

@proton.resource_dir() is the application resource base: the CLI supplies the project root in development; packaged applications use their resources directory; direct runs without managed metadata use the startup working directory. Installed resources are not a persistent writable data store.

package

These fields belong to the package object in proton.project.json.

FieldTypeDefault / meaning
product_namestringRequired display name
versionstringRequired application version; independent of Proton's version
formatsstring arrayHost defaults when omitted
iconsstring arrayEmpty; icon paths relative to configuration directory
preparestringAbsent; preparation command
resourcesstring arrayEmpty; additional packaged resources
sign.binariesstring arrayEmpty; additional binaries selected for signing
url_schemesstring arrayEmpty; registered application URL schemes
document_typesobject arrayEmpty; document associations
outputstringdist, relative to configuration directory
platformsobjectOptional macos, windows, linux overrides

A document type contains required name and extensions; role defaults to Viewer. The canonical identifier is the top-level identifier, not a package field. Changing the product name does not change application identity.

package.sign

FieldTypeDefault / meaning
binariesstring array[]; additional binaries to sign, relative to the configuration directory

Omitting sign adds no extra binaries. This object does not enable signing: use package --sign or --notarize.

package.document_types[]

FieldTypeDefault / meaning
namestringRequired document type display name
extensionsstring arrayRequired nonempty list of file extensions
rolestringViewer; document role passed to packaging

package.platforms

FieldTypeDefault / meaning
macosobjectAbsent; macOS overrides
windowsobjectAbsent; Windows overrides
linuxobjectAbsent; Linux overrides

Each platform object accepts the following fields. Unknown fields are rejected, including nsis_install_mode outside Windows.

FieldTypeDefault / meaning
formatsstring arrayShared package.formats; an explicit list replaces it
resourcesstring array[]; appended to shared resources, duplicates removed
signobjectAbsent; accepts only binaries (string array, default []), appended to shared signing inputs with duplicates removed
nsis_install_modestringWindows only; currentUser (default), perMachine, or both
minimum_system_versionstringmacOS only; major.minor[.patch]. Sets LSMinimumSystemVersion; omitted when unset. Does not change compilation targets or validate binary compatibility.

If the resolved format list is empty, the host default formats apply. CLI options override the resolved configuration. See packaging behavior for supported formats, signing and installation modes.

Configuration ownership and directory layout

Proton does not require the directory layout of either scaffold template. The CLI locates the backend, frontend and resources through this file; see the path resolution rules under Paths and resources below.

File or entryResponsibility
moon.modModule name and versioned dependencies
moon.pkgPackage imports, targets and executable entry declarations
moon.work (when using multiple modules)Groups modules into a workspace
proton.project.jsonApplication identity, CLI build paths and packaging metadata
MoonBit App builderWindows, commands, capabilities and lifecycle behavior

A module dependency makes a module available; a package import selects the APIs used by that package. backend.package selects the build entry and does not replace Moon's package declarations.

Build output

Moon writes build artifacts under _build/ by default. Frontend output depends on the frontend build tool and should correspond to frontend.dist. frontend/dist is an isomorphic template choice, not a fixed framework path. The packager writes distributables to package.output, which defaults to dist.

These directories hold generated artifacts determined by source, build commands and project configuration. The runtime and helper installed by setup live in shared user-level storage, outside the application source tree.

Complete configuration example

The paths below are illustrative: referenced icons, resources and commands must exist in the application project.

{
  "identifier": "com.example.notes",
  "backend": { "path": "backend", "package": "app" },
  "frontend": {
    "path": "frontend",
    "dev_url": "http://127.0.0.1:4300",
    "before_dev": "warren dev --browser-entry main --direct --port 4300",
    "before_build": "warren build --browser-entry main",
    "dist": "dist"
  },
  "package": {
    "product_name": "Notes",
    "version": "1.0.0",
    "formats": ["app", "zip"],
    "icons": ["icons/app.icns", "icons/app.ico", "icons/app.png"],
    "prepare": "node scripts/prepare.mjs",
    "resources": ["resources"],
    "sign": { "binaries": [] },
    "url_schemes": ["notes"],
    "document_types": [
      { "name": "Note", "extensions": ["note"], "role": "Editor" }
    ],
    "output": "dist",
    "platforms": {
      "macos": { "formats": ["app", "dmg"] },
      "windows": { "formats": ["nsis"], "nsis_install_mode": "currentUser" },
      "linux": { "formats": ["appimage"] }
    }
  }
}

Runtime configuration

Load configuration independently, then install it on the application:

let config = @proton.load_config()
let app = @proton.html("Hello", "<h1>Hello</h1>")..config(config)

if config.frontend is Some(frontend) {
  if frontend.dev_url is Some(url) {
    println(url)
  }
}

load_config() reads and validates the complete typed AppConfig, raising AppConfigError immediately on failure. Development uses proton.project.json; packaged applications use proton-package.json. For an explicit file path, use @proton.AppConfig::load(path). Applications can also construct AppConfig directly.

Read fields from the configuration value. Nested sections are optional structs: config.frontend contains dev_url, path, dist, before_dev, and before_build. JSON package maps to config.package_config; JSON backend.package maps to the backend's app_package field.

proton_cli dev supplies the effective configuration after --url, --command, --frontend-path, and --package overrides. Packaging likewise embeds the effective configuration, including CLI overrides for formats and platform settings. Relative paths retain their spelling; reading a field does not resolve paths or execute commands.

app..config(config) installs an independent copy and is mutually exclusive with app..identifier(...). Invalid configuration or a mismatch with the packaged identity prevents startup. Retain config to inspect it; there is no application configuration getter. app.name() and app.version() read the installed snapshot without further file I/O.