Skip to main content

morphir.toml Specification

This document provides the complete specification for the morphir.toml configuration file format.

File Format​

Morphir uses TOML v1.0.0 for configuration files. All configuration is in morphir.toml at the project or workspace root.

Top-Level Sections​

SectionRequiredDescription
[morphir]NoMorphir toolchain settings
[project]ConditionalProject metadata (required for project mode)
[workspace]ConditionalWorkspace settings (required for workspace mode)
[frontend]NoSource language configuration
[ir]NoIR format and generation settings
[codegen]NoCode generation targets and options
[dependencies]NoProject dependencies
[dev-dependencies]NoDevelopment-only dependencies
[extensions]NoExtension registration
[tasks]NoCustom tasks and hooks
[test]NoTest configuration
[publish]NoPublishing configuration

[morphir] Section​

Morphir toolchain version and global settings.

[morphir]
# Required Morphir IR version (semver constraint)
# Ensures compatibility with toolchain and extensions
version = "^4.0.0"

# Minimum CLI version required (optional)
min_cli_version = "4.0.0"

Fields​

FieldTypeDefaultDescription
versionstringRequiredSemver constraint for IR version (e.g., "^4.0.0", "~4.1", "4.0.0")
min_cli_versionstringNoneMinimum CLI version required

Version Constraint Syntax​

SyntaxMeaningExample
"4.0.0"Exact versionOnly 4.0.0
"^4.0.0"Compatible (major)>=4.0.0, <5.0.0
"~4.1.0"Compatible (minor)>=4.1.0, <4.2.0
">=4.0.0"Minimum version4.0.0 or higher
">=4.0.0, <5.0.0"RangeBetween 4.0.0 and 5.0.0

[project] Section​

Project metadata and structure. Required for project mode.

[project]
# Package identifier (organization/name format)
name = "my-org/my-project"

# Semantic version
version = "1.0.0"

# Human-readable description
description = "A Morphir domain model for order processing"

# Package authors
authors = ["Jane Doe <jane@example.com>"]

# License identifier (SPDX)
license = "Apache-2.0"

# Repository URL
repository = "https://github.com/my-org/my-project"

# Homepage URL
homepage = "https://my-org.github.io/my-project"

# Source directory (relative to morphir.toml)
source_directory = "src"

# Modules exposed as public API
exposed_modules = ["Domain.User", "Domain.Order", "Domain.Product"]

# Output directory for build artifacts
output_directory = ".morphir-dist"

# Keywords for package discovery
keywords = ["domain", "orders", "e-commerce"]

Fields​

FieldTypeDefaultDescription
namestringRequiredPackage identifier in org/name format
versionstringRequiredSemantic version (e.g., "1.0.0", "2.1.0-beta.1")
descriptionstring""Human-readable description
authorsarray[]List of authors (name and/or email)
licensestringNoneSPDX license identifier
repositorystringNoneRepository URL
homepagestringNoneHomepage URL
source_directorystring"src"Source code directory
exposed_modulesarrayAll modulesModules in the public API
output_directorystring".morphir-dist"Build output directory
keywordsarray[]Keywords for discovery

Package Name Format​

Package names follow the format organization/project-name:

  • Organization: Lowercase, alphanumeric, hyphens allowed (e.g., my-org, finos)
  • Project: Lowercase, alphanumeric, hyphens allowed (e.g., my-project, morphir-sdk)
  • Separator: Forward slash /

Examples:

  • morphir/sdk
  • my-company/order-domain
  • finos/morphir-examples

[workspace] Section​

Workspace configuration for multi-project setups.

[workspace]
# Glob patterns for discovering member projects
members = [
"packages/*",
"libs/*",
"apps/*"
]

# Patterns to exclude from member discovery
exclude = [
"packages/deprecated-*",
"packages/internal-*"
]

# Default member for commands without --project flag
default_member = "packages/core"

# Shared output directory
output_dir = ".morphir"

# Parallel build settings
parallel = true
max_jobs = 4

Fields​

FieldTypeDefaultDescription
membersarray[]Glob patterns for member discovery
excludearray[]Patterns to exclude from discovery
default_memberstringNoneDefault project for commands
output_dirstring".morphir"Workspace output directory
parallelbooltrueEnable parallel builds
max_jobsintegerCPU countMaximum parallel jobs

Member Discovery​

Members are discovered by:

  1. Matching directories against members patterns
  2. Excluding matches against exclude patterns
  3. Finding morphir.toml with [project] section in matched directories

[frontend] Section​

Source language and parser configuration.

[frontend]
# Default source language
language = "elm"

# Language-specific settings
[frontend.elm]
elm_version = "0.19"
optimize = true

[frontend.morphir-dsl]
strict_mode = true
allow_incomplete = false

# Pattern-based language selection
[[frontend.rules]]
pattern = "src/legacy/**/*.morphir"
language = "morphir-dsl"

[[frontend.rules]]
pattern = "src/experimental/**/*.ml"
language = "ocaml"

Fields​

FieldTypeDefaultDescription
languagestringAuto-detectDefault source language

Built-in Languages​

LanguageExtensionsDescription
elm.elmElm source files
morphir-dsl.morphir, .mdslMorphir DSL

Language-Specific Options​

[frontend.elm]​

FieldTypeDefaultDescription
elm_versionstring"0.19"Elm language version
optimizeboolfalseEnable optimizations

[frontend.morphir-dsl]​

FieldTypeDefaultDescription
strict_modeboolfalseStrict parsing mode
allow_incompletebooltrueAllow incomplete definitions

Frontend Rules​

Rules select language based on file path patterns:

[[frontend.rules]]
pattern = "src/**/*.elm" # Glob pattern
language = "elm" # Language for matching files

Rules are evaluated in order; first match wins.

[ir] Section​

IR format and generation settings.

[ir]
# IR format version
format_version = 4

# Output mode
mode = "vfs" # "classic" or "vfs"

# Strict mode (fail on warnings)
strict_mode = false

# Include source locations in IR
include_source_locations = true

# Preserve documentation
include_docs = true

Fields​

FieldTypeDefaultDescription
format_versioninteger4IR format version
modestring"vfs"Output mode: "classic" (single file) or "vfs" (directory tree)
strict_modeboolfalseTreat warnings as errors
include_source_locationsbooltrueInclude source locations in IR
include_docsbooltrueInclude documentation in IR

[codegen] Section​

Code generation configuration.

[codegen]
# Targets to generate
targets = ["typescript", "scala", "spark"]

# Output format
output_format = "pretty" # "pretty" or "compact"

# Output directory (relative to project output)
output_dir = "generated"

# Target-specific configuration
[codegen.typescript]
module_format = "esm"
strict = true

[codegen.scala]
package_prefix = "com.myorg"
scala_version = "2.13"

[codegen.spark]
spark_version = "3.5"
scala_version = "2.13"

# Module-specific target overrides
[codegen.modules."Domain.Api"]
targets = ["typescript"] # Only generate TypeScript for this module

[codegen.modules."Domain.Internal"]
targets = [] # Skip codegen for internal modules

# Pattern-based rules
[[codegen.rules]]
pattern = "**/Internal/**"
targets = []

[[codegen.rules]]
pattern = "**/Api/**"
targets = ["typescript", "openapi"]

Fields​

FieldTypeDefaultDescription
targetsarray[]Code generation targets
output_formatstring"pretty"Output formatting
output_dirstring"generated"Output directory

Built-in Targets​

TargetDescription
typescriptTypeScript/JavaScript
scalaScala 2.x/3.x
javaJava
sparkApache Spark
json-schemaJSON Schema
openapiOpenAPI specification

Target-Specific Options​

[codegen.typescript]​

FieldTypeDefaultDescription
module_formatstring"esm""esm", "commonjs", or "umd"
strictbooltrueEnable strict TypeScript
declarationbooltrueGenerate .d.ts files

[codegen.scala]​

FieldTypeDefaultDescription
package_prefixstringNonePackage prefix
scala_versionstring"2.13"Scala version

[codegen.spark]​

FieldTypeDefaultDescription
spark_versionstring"3.5"Spark version
scala_versionstring"2.13"Scala version

[dependencies] Section​

Project dependencies.

[dependencies]
# Path dependency (local)
"my-org/common" = { path = "../common" }

# Version dependency (from registry)
"morphir/sdk" = "^3.0.0"

# Git dependency
"other-org/utils" = { git = "https://github.com/other-org/utils.git", tag = "v1.0.0" }

# Detailed specification
[dependencies."finos/morphir-examples"]
version = "^2.0.0"
features = ["extra-types"]

Dependency Formats​

Version String (Registry)​

"morphir/sdk" = "^3.0.0"

Path (Local)​

"my-org/common" = { path = "../common" }

Git​

# By tag
"org/pkg" = { git = "https://github.com/org/pkg.git", tag = "v1.0.0" }

# By branch
"org/pkg" = { git = "https://github.com/org/pkg.git", branch = "main" }

# By commit
"org/pkg" = { git = "https://github.com/org/pkg.git", rev = "abc123" }

Detailed​

[dependencies."org/pkg"]
version = "^2.0.0"
features = ["feature1", "feature2"]
optional = false

Dependency Fields​

FieldTypeDescription
versionstringSemver constraint
pathstringLocal path
gitstringGit repository URL
tagstringGit tag
branchstringGit branch
revstringGit commit hash
featuresarrayOptional features to enable
optionalboolOptional dependency

[dev-dependencies] Section​

Development-only dependencies (same format as [dependencies]).

[dev-dependencies]
"morphir/test-utils" = "^1.0.0"
"my-org/test-fixtures" = { path = "../test-fixtures" }

[extensions] Section​

Extension registration and configuration.

[extensions]
# WASM component (local path)
spark-codegen = { path = "./extensions/spark-codegen.wasm" }

# WASM component (URL)
scala-codegen = { url = "https://extensions.morphir.dev/scala-codegen-1.0.0.wasm" }

# Native executable
my-analyzer = { command = "./bin/my-analyzer", args = ["--mode", "jsonrpc"] }

# Disable auto-discovered extension
legacy-ext = { enabled = false }

# Extension-specific configuration
[extensions.spark-codegen.config]
spark_version = "3.5"
scala_version = "2.13"

Extension Fields​

FieldTypeDescription
pathstringLocal path to WASM or executable
urlstringURL to download extension
commandstringExecutable command
argsarrayCommand arguments
enabledboolEnable/disable extension
configtableExtension-specific configuration

[tasks] Section​

Custom tasks and hooks.

[tasks]
# Simple command task
lint = "elm-review"

# Task with description
[tasks.integration]
description = "Run integration tests"
run = "./scripts/integration-tests.sh"

# Task with dependencies
[tasks.ci]
description = "Full CI pipeline"
depends = ["check", "test", "build"]

# Task with working directory
[tasks.docs]
description = "Generate documentation"
run = "morphir docs generate"
cwd = "./docs"

# Pre/post hooks for built-in tasks
[tasks."pre:build"]
run = "echo 'Starting build...'"

[tasks."post:build"]
run = "prettier --write .morphir-dist/"

[tasks."post:codegen"]
run = "./scripts/post-codegen.sh"

Task Fields​

FieldTypeDescription
descriptionstringHuman-readable description
runstringShell command to execute
dependsarrayTask dependencies (run first)
cwdstringWorking directory
envtableEnvironment variables

Built-in Tasks​

TaskDescription
buildCompile project to IR
checkLint and validate
testRun tests
codegenGenerate code for targets
packCreate distributable package
publishPublish to registry
cleanRemove build artifacts

Hooks​

Hooks extend built-in tasks:

HookTiming
pre:<task>Before task runs
post:<task>After task succeeds

[test] Section​

Test configuration.

[test]
# Test directory
directory = "tests"

# Test patterns
include = ["**/*Test.elm", "**/*Spec.elm"]
exclude = ["**/helpers/**"]

# Test runner settings
timeout = 30000 # milliseconds
parallel = true

Fields​

FieldTypeDefaultDescription
directorystring"tests"Test directory
includearray["**/*Test.*"]Include patterns
excludearray[]Exclude patterns
timeoutinteger30000Test timeout (ms)
parallelbooltrueRun tests in parallel

[publish] Section​

Publishing configuration.

[publish]
# Registry URL
registry = "https://registry.morphir.dev"

# Include patterns
include = [
"src/**/*.elm",
"morphir.toml",
"README.md",
"LICENSE"
]

# Exclude patterns
exclude = [
"**/*.test.elm",
"**/Internal/**"
]

Fields​

FieldTypeDefaultDescription
registrystringDefault registryRegistry URL
includearrayStandard filesFiles to include
excludearray[]Files to exclude

Complete Example​

Single Project​

[morphir]
version = "^4.0.0"

[project]
name = "my-org/order-domain"
version = "1.0.0"
description = "Order processing domain model"
authors = ["Jane Doe <jane@example.com>"]
license = "Apache-2.0"
source_directory = "src"
exposed_modules = ["Domain.Order", "Domain.Product", "Domain.Customer"]

[frontend]
language = "elm"

[frontend.elm]
elm_version = "0.19"

[codegen]
targets = ["typescript", "scala"]

[codegen.typescript]
module_format = "esm"

[codegen.scala]
package_prefix = "com.myorg.orders"

[dependencies]
"morphir/sdk" = "^3.0.0"
"my-org/common-types" = { path = "../common-types" }

[dev-dependencies]
"morphir/test-utils" = "^1.0.0"

[tasks.ci]
description = "CI pipeline"
depends = ["check", "test", "build", "codegen"]

Workspace​

[morphir]
version = "^4.0.0"

[workspace]
members = ["packages/*", "apps/*"]
exclude = ["packages/deprecated-*"]
default_member = "packages/core"
output_dir = ".morphir"

# Shared settings inherited by all projects
[frontend]
language = "elm"

[frontend.elm]
elm_version = "0.19"

[codegen]
targets = ["typescript"]

# Shared dependencies
[dependencies]
"morphir/sdk" = "^3.0.0"

[extensions]
spark-codegen = { path = "./extensions/spark-codegen.wasm" }

[tasks.ci]
description = "Workspace CI"
depends = ["check", "test", "build"]

Validation Rules​

Required Fields​

ModeRequired Sections/Fields
Project[project], project.name, project.version
Workspace[workspace], workspace.members

Naming Constraints​

FieldConstraint
project.name^[a-z][a-z0-9-]*/[a-z][a-z0-9-]*$
project.versionValid semver
Module namesPascalCase, dot-separated

Path Constraints​

FieldConstraint
source_directoryMust exist, relative path
output_directoryRelative path
dependencies.*.pathMust contain morphir.toml

Error Messages​

ErrorDescription
E001Missing required field
E002Invalid package name format
E003Invalid version format
E004Source directory not found
E005Circular dependency detected
E006Unknown extension
E007Invalid glob pattern
E008Duplicate project name in workspace