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