Skip to content

Genotype Configuration

Genotype uses genotype.toml to configure source files, generated packages, and target languages.

Put global options at the top of the file and target options in their corresponding sections:

name = "bookstore-types"
version = "0.1.0"
src = "src"
dist = "dist"
[ts]
enabled = true
[rs]
enabled = true
[rs.manifest.package]
edition = "2024"
[py]
enabled = true
version = "latest"
module = "bookstore_types"

This configuration reads .type files from src and generates TypeScript, Rust, and Python packages in dist/ts, dist/rs, and dist/py.

You can also use the full section names [typescript], [rust], and [python]. The examples below use their short forms.

package controls how generated types are packaged:

  • true (default): Generate package metadata and directory structure.
  • false: Write source files directly into each target’s output directory to integrate into an existing package.
package = false

You can override this setting for individual targets using their package option.

name sets the project name used when generating package manifests:

name = "bookstore-types"

If omitted, Genotype derives the name from the project directory. Use the target’s manifest to set a different package name.

version sets the default package version for all targets. It accepts a semantic version string and has no default:

version = "0.1.0"

A version set in a target’s manifest overrides this value. If neither is set, the generated manifest omits the version.

root sets the project root directory relative to the directory containing genotype.toml. It defaults to ".":

root = "./types"

src sets the source directory relative to root. It defaults to "src":

src = "schemas"

entry selects source files using a glob pattern relative to src. It defaults to "**/*.type", which includes .type files in the source directory and its subdirectories:

entry = "api/**/*.type"

You can also select a single entry file:

entry = "api.type"

Genotype resolves modules imported by the selected files as well.

dist sets the output directory relative to root. It defaults to "dist":

dist = "generated"

Each target has its own directory inside it. See target output directory to customize these paths.

build.file controls generated file tracking:

  • true (default): Read and update genotype.build.toml next to the configuration file for cleanup.
  • false: Disable build tracking and cleanup.
[build]
file = true

build.cleanup controls what happens to previously generated files that are no longer produced:

  • true (default): Remove stale generated files, preserving files you have modified.
  • false: Keep stale generated files.
[build]
cleanup = false

build.cleanup has no effect when build.file = false. To disable both:

[build]
file = false
cleanup = false

warning_comment controls the generated file comment:

  • true (default): Identify generated source files with a comment warning against editing them.
  • false: Omit the comment.
warning_comment = false

formatters is an array of formatter configurations. It defaults to [].

Global formatters run after each enabled target is compiled, in array order, followed by that target’s formatters. Commands run from the target’s output directory.

formatters = [
{ kind = "shell", cmd = "format-generated", args = ["."] },
]

Use target formatters for commands that apply to just one language.

Use kind = "shell" to run an executable directly. cmd is required; args is an optional array of strings, defaulting to []:

[ts]
enabled = true
formatters = [
{ kind = "shell", cmd = "prettier", args = ["--write", "."] },
]

Despite its name, shell doesn’t interpret shell expressions. To use pipes or other shell syntax, invoke a shell explicitly through cmd and args.

You can also use an executor as kind, with the same cmd and args options:

kind Command prefix
"cargo" cargo
"npm" npm exec
"npx" npx
"pnpm" pnpm exec
"pnx" pnx
"bun" bun exec
"bunx" bunx
"uv" uv run
"poetry" poetry run
"pipx" pipx run

E.g., this runs cargo fmt --all:

[rs]
enabled = true
formatters = [{ kind = "cargo", cmd = "fmt", args = ["--all"] }]

Presets provide the formatter command and its standard arguments:

kind Default command Supported via values
"oxfmt" oxfmt --no-error-on-unmatched-pattern "npm", "npx", "pnpm", "pnx", "bun", "bunx"
"prettier" prettier --write . "npm", "npx", "pnpm", "pnx", "bun", "bunx"
"ruff" ruff format . "uv", "poetry", "pipx"
"prettyplease" Provided by the formatter environment None

For oxfmt, prettier, and ruff, optional via selects an executor from the table above. When omitted, the executable runs directly. Optional args appends arguments to the preset’s defaults:

[ts]
enabled = true
formatters = [
{ kind = "prettier", via = "pnpm", args = ["--single-quote"] },
]

prettyplease accepts only kind and is available in the playground. For CLI Rust formatting, use cargo fmt as shown above.

Common options configure target generation independently of the target language. Replace <target> with the target section name; examples use [ts].

enabled controls whether the target is generated:

  • false (default): Skip the target.
  • true: Generate the target.
[ts]
enabled = true

package overrides global package generation for this target. When omitted, it inherits the global value:

package = false
[ts]
enabled = true
package = true

dist sets the target output directory relative to the global output directory:

dist = "generated"
[ts]
enabled = true
dist = "typescript"

This writes the example package to generated/typescript. The default directory name depends on the target.

manifest is a table of package metadata. It defaults to an empty table:

[ts.manifest]
name = "@bookstore/types"
version = "0.2.0"
license = "MIT"

Configured metadata overrides generated defaults, except for required runtime dependency versions.

The table follows the target language’s package manifest format.

This option has no effect when package generation is disabled.

[<target>.dependencies] - External Modules

Section titled “[<target>.dependencies] - External Modules”

dependencies maps external modules to import paths in the target language. It defaults to an empty table:

[ts.dependencies]
shared_types = "@bookstore/shared-types"

You can then import from the mapped module in your source files:

use shared_types/UserId
Order: {
userId: UserId,
}

These mappings control generated imports. They don’t install packages or add package versions to the manifest. Declare external package dependencies in the corresponding manifest or in the application consuming the generated code.

formatters adds formatters for this target. It defaults to [] and runs after the global list, without replacing it:

[ts]
enabled = true
formatters = [{ kind = "oxfmt", via = "pnpm" }]

See formatters for configuration fields, supported commands, presets, and execution order.