This is the full developer documentation for Genotype
# Start Here
> How to get started with the Genotype programming language.
Genotype is a programming language designed to help developers synchronize types between TypeScript, Rust, and Python (more languages coming soon).
## Learn the Genotype Language
[Section titled “Learn the Genotype Language”](#learn-the-genotype-language)
To get familiar with the Genotype programming language, see [Quick Genotype Language Tour](/docs/language/). It will lead you through all the language features, show you how to use them, and link to more detailed documentation.
To learn more about the specific Genotype targets, see:
* [TypeScript Overview](/docs/targets/typescript/)
* [Rust Overview](/docs/targets/rust/)
* [Python Overview](/docs/targets/python/)
## Quick Start
[Section titled “Quick Start”](#quick-start)
Follow the steps below to get started with Genotype or, alternatively, to play with Genotype without installing it, try [Genotype Playground](/playground).
### 1. Install the CLI
[Section titled “1. Install the CLI”](#1-install-the-cli)
Install the Genotype CLI to get started:
* Linux/macOS
```sh
curl -fsSL https://genotype-lang.org/install.sh | sh
```
* Windows
```powershell
irm https://genotype-lang.org/install.ps1 | iex
```
See [Genotype Installation](/docs/getting-started/installation/) for more options.
### 2. Bootstrap a New Project
[Section titled “2. Bootstrap a New Project”](#2-bootstrap-a-new-project)
Run `gt init` to bootstrap a new Genotype project. It will ask you a few questions and generate `genotype.toml` and source files for your project:
```sh
gt init
```
See [the CLI reference](/docs/toolchain/cli/) for more information about the Genotype CLI.
#### Manual Set Up
[Section titled “Manual Set Up”](#manual-set-up)
To set up a project manually, create `genotype.toml` in your project directory. This matches the configuration generated by `gt init` for a directory named `my-package`:
```toml
name = "my-package"
version = "0.1.0"
[ts]
enabled = true
[ts.manifest]
name = "my-package"
[py]
manager = "uv"
enabled = true
[py.manifest.project]
name = "my-package"
[rs]
enabled = true
[rs.manifest.package]
name = "my_package"
edition = "2024"
```
See [Configuration Reference](/docs/toolchain/configuration/) for more details.
### 3. Edit Type Files
[Section titled “3. Edit Type Files”](#3-edit-type-files)
Create a new file `.type` in the `src` directory and add your types, for example `src/user.type`:
```type
User: {
name: FullName,
email: string,
}
FullName: {
first: string,
last?: string,
}
```
See [the Quick Tour](/docs/language/) for more information about the language.
### 4. Build
[Section titled “4. Build”](#4-build)
Run `gt build` to generate code for the targets configured in [`genotype.toml`](/docs/toolchain/configuration):
```sh
gt build
```
The generated files go into the output directories selected during initialization. Run the command again after editing your types.
See [the CLI reference](/docs/toolchain/cli/#gt-build) for more build options.
## Working with AI Agents
[Section titled “Working with AI Agents”](#working-with-ai-agents)
Run `gt skill install` to install the Genotype agent skill. `gt init` also has the option to install the skill during project setup. See [Agent Skill](/docs/toolchain/skill/) for more info.
The documentation is also available as [llms.txt](/llms.txt), an index for AI tools, and [llms-full.txt](/llms-full.txt), the full documentation in a single text file. Give your agent these links when it needs documentation without browsing the website.
# Installation
> How to install Genotype CLI.
Genotype is distributed as a single binary executable, which can be installed on Linux, macOS, and Windows.
The quickest way to install Genotype is to use the installation script:
* Linux/macOS
```sh
curl -fsSL https://genotype-lang.org/install.sh | sh
```
* Windows
```powershell
irm https://genotype-lang.org/install.ps1 | iex
```
You can also download the binary from [the latest GitHub release page](https://github.com/kossnocorp/genotype/releases/latest).
## Cargo Binstall
[Section titled “Cargo Binstall”](#cargo-binstall)
Install a prebuilt Genotype CLI binary with [cargo-binstall](https://github.com/cargo-bins/cargo-binstall):
```sh
cargo binstall genotype_cli
```
## Building From Source
[Section titled “Building From Source”](#building-from-source)
To compile Genotype from source code, [install Rust](https://rust-lang.org/learn/get-started/) and install the Genotype using Cargo:
```sh
cargo install genotype_cli
```
## AI Agent Skill
[Section titled “AI Agent Skill”](#ai-agent-skill)
Install Genotype’s skill in your project to give your coding agent language, configuration, and CLI guidance:
```sh
gt skill install
# Or
npx skills@latest add kossnocorp/genotype
```
See [Agent Skill](/docs/toolchain/skill/) for more info, updates, and installation options.
# Quick Genotype Language Tour
> Quick tour of the Genotype Programming Language syntax and features.
Welcome to the Genotype Programming Language guide!
Genotype is a language that allows you to define types and data structures and generate code implementing them in multiple programming languages, such as TypeScript, Rust, Python, and more.
Note
This guide doesn’t cover all the target language features, e.g., how the Zod mode works when generating TypeScript code, or how legacy Python type system support works.
See corresponding target language guides for more details:
* [TypeScript](/docs/targets/typescript)
* [Rust](/docs/targets/rust)
* [Python](/docs/targets/python)
## Source Files
[Section titled “Source Files”](#source-files)
Genotype source files have `.type` extension. Each file is a module that exports all its type definitions.
```type
Category: "fiction"
Book: {
title: string,
subtitle?: string,
}
```
Tip
The convention is to use `snake_case` for source file names.
The generated code will automatically transform into idiomatic names in the target language.
## Type Aliases
[Section titled “Type Aliases”](#type-aliases)
Type aliases assign a type to a name. They are the basic building blocks of Genotype.
```type
Yeah: true
Greeting: {
message: string
}
```
Type aliases are translated to the corresponding type definitions in the target languages:
* TypeScript
```ts
export type Yeah = true;
export interface Greeting {
message: string;
}
```
* Rust
```rust
#[serde_literal(true)]
#[derive(Serialize, Deserialize)]
pub struct Yeah;
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct Greeting {
pub message: String,
}
```
* Python
```python
type Yeah = Literal[True]
class Greeting(Model):
message: str
```
Tip
The convention is to use `PascalCase` for type names.
The generated code will automatically transform into idiomatic names in the target language.
### References
[Section titled “References”](#references)
You can reference type aliases in other type definitions:
```type
User: {
name: string,
address: Address,
}
Address: {
country: string,
city: string,
}
```
The order of type definitions doesn’t matter. You can reference types defined later in the file.
Languages that don’t support forward references, such as Python, will generate code that works around this limitation.
### Inline Type Aliases
[Section titled “Inline Type Aliases”](#inline-type-aliases)
A type alias can also be defined inline, as part of another type definition:
```type
Customer: {
email: string,
billingAddress: BillingAddress: {
street: string,
city: string,
},
}
```
## Modules
[Section titled “Modules”](#modules)
Every Genotype file is a module that exports all type aliases defined in it.
You can import types from other modules via `use` statement.
* shipment.type
```type
use ./destination/Destination
Shipment: {
trackingNumber: string,
destination: Destination,
}
```
* destination.type
```type
Destination: {
country: string,
city: string,
}
```
In this example `./destination` is a relative module path (with `.type` extension omitted). The path might point to nested directories, e.g., `./models/shipment`, as well as `..` for parent directories, e.g., `../../shipment`.
There are multiple ways to import types from other modules:
```type
// Use multiple types from the same module:
use ./location/{Location, PostalCode}
// Re-alias a type from a separate module:
use ./place/{StreetAddress as Place}
// Glob import from another separate module:
use ./coordinates/*
Venue: {
location: Location,
postalCode: PostalCode,
latitude: Latitude,
longitude: Longitude,
// Inline import from its own module:
venueLocation: ./venue/VenueLocation,
}
```
### External Modules
[Section titled “External Modules”](#external-modules)
Genotype currently have no fully-fledged package manager nor external module system (it’s [planned](https://github.com/kossnocorp/genotype/issues/161) [though](https://github.com/kossnocorp/genotype/issues/162)). But you can map certain paths to external modules per target language, e.g. to make `shared_types` available in all targets, configure using `[.dependencies]` section in `genotype.toml`:
```toml
[ts]
enabled = true
[ts.dependencies]
genotype_core = "@genotype-lang/types"
[rs]
enabled = true
[rs.dependencies]
genotype_core = "genotype_core"
[py]
enabled = true
[py.dependencies]
genotype_core = "genotype_core"
```
Then you can import types from `genotype_core` in your Genotype files:
```type
use genotype_core/Node
Diagnostic: {
kind: "error" | "warning",
message: string,
node: Node,
}
```
Caution
Genotype doesn’t guarantee that the external module availability nor type-check the imported types.
Use it with caution, until a proper package manager and external module system is implemented.
## Unions
[Section titled “Unions”](#unions)
One of the most basic yet powerful features of Genotype is the ability to define union types:
```type
Response: ResponseSuccess | ResponseError
ResponseSuccess: {
status: "success",
body: { user: User }
}
ResponseError: {
status: "failure" | "timeout",
error?: string,
}
```
In languages that support union types, such as TypeScript, it will translate into the corresponding syntax. Languages that don’t, i.e., Rust, will generate an enum type with variants for each union member:
* TypeScript
```ts
export type Response = ResponseSuccess | ResponseError;
export interface ResponseSuccess {
status: "success";
body: {
user: User;
};
}
export interface ResponseError {
status: "failure" | "timeout";
error?: string | undefined;
}
```
* Rust
```rust
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct User {}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Response {
Success(ResponseSuccess),
Error(ResponseError),
}
#[serde_literals]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[literals(status = "success")]
pub struct ResponseSuccess {
pub body: ResponseSuccessBody,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ResponseSuccessBody {
pub user: User,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ResponseError {
pub status: ResponseErrorStatus,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error: Option,
}
#[serde_literals]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ResponseErrorStatus {
#[literal("failure")]
Failure,
#[literal("timeout")]
Timeout,
}
```
* Python
```python
class ResponseSuccessBody(Model):
user: User
class ResponseSuccess(Model):
status: Literal["success"]
body: ResponseSuccessBody
class ResponseError(Model):
status: Literal["failure"] | Literal["timeout"]
error: Optional[str] = None
type Response = ResponseSuccess | ResponseError
```
See more details on the union translation to [TypeScript](/docs/targets/typescript#unions), [Rust](/docs/targets/rust#unions), and [Python](/docs/targets/python#unions).
## Comments and Docs
[Section titled “Comments and Docs”](#comments-and-docs)
Genotype supports line and block comments:
```type
// Line comment.
/* A block comment. */
Hello: /* Inline block comment */ "world" // EOL comment.
```
Line and block comments are omitted in generated code.
### Doc Comments
[Section titled “Doc Comments”](#doc-comments)
Unlike regular comments, doc comments are preserved in generated code and translated into the target language’s documentation format.
```type
//! Module documentation.
//!
//! Can span multiple lines.
/// Type documentation.
Member: {
/// Field documentation.
displayName: string,
}
```
* TypeScript
```ts
/** @file Module documentation.
*
* Can span multiple lines. */
/** Type documentation. */
export interface Member {
/** Field documentation. */
displayName: string;
}
```
* Rust
```rust
//! Module documentation.
//!
//! Can span multiple lines.
use serde::{Deserialize, Serialize};
/// Type documentation.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Member {
/// Field documentation.
#[serde(rename = "displayName")]
pub display_name: String,
}
```
* Python
```python
"""Module documentation.
Can span multiple lines."""
from __future__ import annotations
from pydantic import Field
from genotype import Model
class Member(Model):
"""Type documentation."""
display_name: str = Field(alias="displayName")
"""Field documentation."""
```
## Data Types
[Section titled “Data Types”](#data-types)
### Primitives
[Section titled “Primitives”](#primitives)
Genotype has several scalar types available:
* Numeric: `number`, `int`, `float` (as well as sized types, i.e., `i32`, `i64`, `f32` etc)
* Boolean: `boolean`.
* String: `string`.
```type
Player: {
username: string,
score: int,
isOnline: boolean,
}
```
Same as in TypeScript, Genotype also supports literal types:
```type
Answer: 42
Yes: true
No: false
Result: {
status: "ok"
}
```
…as well as `null`:
```type
Employee: {
name: string,
departmentId: int | null,
}
```
Note
While `null` is usually a mistake when it comes to programming languages design, in Genotype `null` allows to express data structures already present in the target languages.
Even JSON has `null`, so we had no choice but to have it.
See more details on the primitive type translation to [TypeScript](/docs/targets/typescript#primitives), [Rust](/docs/targets/rust#primitives), and [Python](/docs/targets/python#primitives).
#### Branded Primitives
[Section titled “Branded Primitives”](#branded-primitives)
You can brand a primitive to create a distinct type that isn’t interchangeable with the original primitive:
```type
UserId: @string
RowId: @int
```
You can brand any primitive, including booleans, sized integers, and floating-point types.
A branded primitive type is translated to the corresponding idiomatic type in the target language:
* TypeScript
```ts
export type UserId = string & { [userIdBrand]: true };
declare const userIdBrand: unique symbol;
export type RowId = number & { [rowIdBrand]: true };
declare const rowIdBrand: unique symbol;
```
* Rust
```rust
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
pub struct UserId(pub String);
#[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
pub struct RowId(pub i64);
```
* Python
```python
UserId = NewType("UserId", str)
RowId = NewType("RowId", int)
```
See more details on the branded primitive translation to [TypeScript](/docs/targets/typescript#branded-primitives), [Rust](/docs/targets/rust#branded-primitives), and [Python](/docs/targets/python#branded-primitives).
### Composite Types
[Section titled “Composite Types”](#composite-types)
#### Objects
[Section titled “Objects”](#objects)
An object type is a collection of named fields, each with its own type:
```type
Resident: {
fullName: string,
yearsAtAddress: int,
address: Address,
}
```
Objects also can be nested:
```type
Event: {
title: string,
capacity: int,
venue: {
country: string,
city: string,
},
}
```
Tip
The convention is to use `camelCase` for field names.
The generated code will automatically transform into idiomatic names in the target language.
See more details on the object translation to [TypeScript](/docs/targets/typescript#objects), [Rust](/docs/targets/rust#objects), and [Python](/docs/targets/python#objects).
##### Optional Object Fields
[Section titled “Optional Object Fields”](#optional-object-fields)
An object field can be optional, which means it may or may not be present in the object:
```type
Delivery: {
recipient: string,
weight: int,
address?: Address,
}
```
See more details on the optional object field translation to [TypeScript](/docs/targets/typescript#optional-object-fields), [Rust](/docs/targets/rust#optional-object-fields), and [Python](/docs/targets/python#optional-object-fields).
##### Object Extensions
[Section titled “Object Extensions”](#object-extensions)
Object fields can be extended with other object types:
```type
MessageBase: {
id: int,
timestamp: int,
}
MessageSuccess: {
...MessageBase,
status: "success",
}
MessageFailure: {
...MessageBase,
status: "failure",
error: string,
}
```
The languages that support extensions, such as TypeScript and Python, it would translate into the corresponding syntax. Languages that don’t, i.e., Rust, will copy the fields from the base type into the extended type:
* TypeScript
```ts
export interface MessageBase {
id: number;
timestamp: number;
}
export interface MessageSuccess extends MessageBase {
status: "success";
}
export interface MessageFailure extends MessageBase {
status: "failure";
error: string;
}
```
* Rust
```rust
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct MessageBase {
pub id: i64,
pub timestamp: i64,
}
#[serde_literals]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[literals(status = "success")]
pub struct MessageSuccess {
pub id: i64,
pub timestamp: i64,
}
#[serde_literals]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[literals(status = "failure")]
pub struct MessageFailure {
pub id: i64,
pub timestamp: i64,
pub error: String,
}
```
* Python
```python
class MessageBase(Model):
id: int
timestamp: int
class MessageSuccess(MessageBase, Model):
status: Literal["success"]
class MessageFailure(MessageBase, Model):
status: Literal["failure"]
error: str
```
You can extend with multiple object types:
```type
AnimalMammal: { warmBlooded: boolean }
AnimalPet: { name: string }
AnimalCat: {
...AnimalMammal,
...AnimalPet,
}
```
See more details on the object extension translation to [TypeScript](/docs/targets/typescript#object-extensions), [Rust](/docs/targets/rust#object-extensions), and [Python](/docs/targets/python#object-extensions).
#### Arrays
[Section titled “Arrays”](#arrays)
An array type represents a list of elements of a given type:
```type
Post: {
title: string,
tags: [string],
}
```
The element type can be a union, i.e., each element can have any type in the union:
```type
Values: [string | int | boolean]
```
In languages that don’t allow mixed types in array-like structures, such as Rust, Genotype will generate a `Vec` of an enum type:
```rust
pub type Values = Vec;
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(untagged)]
pub enum ValuesItem {
String(String),
Int(i64),
Boolean(bool),
}
```
See more details on the array translation to [TypeScript](/docs/targets/typescript#arrays), [Rust](/docs/targets/rust#arrays), and [Python](/docs/targets/python#arrays).
#### Tuples
[Section titled “Tuples”](#tuples)
A tuple type represents a fixed-length list of elements of given types:
```type
Point: (float, float)
```
Tuple elements can be union types, i.e., each element can have any type in the union:
```type
Setting: (string | int, boolean)
```
See more details on the tuple translation to [TypeScript](/docs/targets/typescript#tuples), [Rust](/docs/targets/rust#tuples), and [Python](/docs/targets/python#tuples).
#### Records
[Section titled “Records”](#records)
A record type represents a collection of named fields, each with its own type, but unlike objects, records can have arbitrary field names:
```type
Scores: { [int]: float }
```
A record key can be `string`, `boolean`, a numeric type, or a reference to one of these primitives. You can also use references to branded primitives:
```type
ProductId: @int
ProductNames: { [ProductId]: string }
```
A record with `string` as a key can omit the key type:
```type
AliasMap: { []: string }
```
Caution
Composite type references aren’t supported as record keys ([not yet](https://github.com/kossnocorp/genotype/issues/159)).
See more details on the record translation to [TypeScript](/docs/targets/typescript#records), [Rust](/docs/targets/rust#records), and [Python](/docs/targets/python#records).
### Special Data Types
[Section titled “Special Data Types”](#special-data-types)
There are several special data types available in Genotype:
#### Any Type
[Section titled “Any Type”](#any-type)
When you need to represent a value of any type, similar to TypeScript’s `any`, you can use the `any` type:
```type
ApiResponse: {
status: "ok" | "error",
payload: any,
}
```
Languages that has `any` type, it will translate into the corresponding syntax. Languages that don’t, i.e., Rust, will use Genotype runtime to represent it:
* TypeScript
```ts
export interface ApiResponse {
status: "ok" | "error";
payload: any;
}
```
* Rust
```rust
use genotype_runtime::Any;
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct ApiResponse {
pub status: ApiResponseStatus,
pub payload: Any,
}
#[serde_literals]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub enum ApiResponseStatus {
#[literal("ok")]
Ok,
#[literal("error")]
Error,
}
```
* Python
```python
class ApiResponse(Model):
status: Literal["ok"] | Literal["error"]
payload: Any
```
Don't abuse it!
The `any` type is not meant to be used to silence type errors, like it often utilized in TypeScript. It meant to represent values of any type, such as JSON payloads, or data from untyped sources.
Use it sparingly!
See more details on the any type translation to [TypeScript](/docs/targets/typescript#any-type), [Rust](/docs/targets/rust#any-type), and [Python](/docs/targets/python#any-type).
## Generic Types
[Section titled “Generic Types”](#generic-types)
Genotype supports basic generic types, enabling more of the type composition and reuse.
```type
Message: {
id: int,
timestamp: int,
payload: Payload,
}
```
Generics also can be used in object extensions, allowing to reuse the same base type with different payloads:
```type
Notification: {
notificationId: int,
sentAt: int,
payload: Payload,
}
NotificationText: {
...Notification
}
```
…or even compose generic types with other generic types:
```type
Request: {
requestId: int,
timeout: int,
payload: Payload,
}
RequestReply: {
...Request>
}
Reply: ReplySuccess | ReplyFailure
ReplyBase: {
status: Status
}
ReplySuccess: {
...ReplyBase<"success">,
body: Body
}
ReplyFailure: {
...ReplyBase<"failure">,
error: string
}
```
See more details on the generic type translation to [TypeScript](/docs/targets/typescript#generic-types), [Rust](/docs/targets/rust#generic-types), and [Python](/docs/targets/python#generic-types).
## Recursive Types
[Section titled “Recursive Types”](#recursive-types)
Types can refer to themselves or form cycles across definitions and modules:
```type
LinkedNode: {
value: string,
next?: LinkedNode,
}
Json: null | boolean | number | string | [Json] | { []: Json }
```
Targets add the indirection their type systems need. E.g., Rust boxes direct recursive fields, while TypeScript’s Zod mode uses lazy schemas or object getters:
* TypeScript
```ts
export interface LinkedNode {
value: string;
next?: LinkedNode | undefined;
}
export type Json =
| null
| boolean
| number
| string
| Array
| Record;
```
* Rust
```rust
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct LinkedNode {
pub value: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub next: Option>,
}
#[serde_literals]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Json {
#[literal(null)]
Null,
Boolean(bool),
Number(f64),
String(String),
Vec(Vec),
Map(BTreeMap),
}
```
* Python
```python
type Json = Literal[None] | bool | float | str | list[Json] | dict[str, Json]
class LinkedNode(Model):
value: str
next: Optional[LinkedNode] = None
```
See more details on the recursive type translation to [TypeScript](/docs/targets/typescript#recursive-types), [Rust](/docs/targets/rust#recursive-types), and [Python](/docs/targets/python#recursive-types).
## Annotations
[Section titled “Annotations”](#annotations)
Annotations add structured metadata to types, fields, and union members. Most annotations belong to a specific target.
For example:
```type
#[discriminator = "status"]
JobResult: JobSuccess | JobFailure
JobSuccess: {
status: "success",
body: string,
}
JobFailure: {
status: "failure",
error: string,
}
JobStatus:
| #[variant = "Ok"] "success"
| #[variant = "Nope"] "failure"
```
Here `discriminator` adds Python union schema metadata:
```py
class JobSuccess(Model):
status: Literal["success"]
body: str
class JobFailure(Model):
status: Literal["failure"]
error: str
type JobResult = Annotated[
JobSuccess | JobFailure,
Field(json_schema_extra={"discriminator": "status"}),
]
# ...
```
While `variant` customizes Rust enum variant names:
```rust
// ...
#[serde_literals]
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub enum JobStatus {
#[literal("success")]
Ok,
#[literal("failure")]
Nope,
}
```
Generators ignore annotations they don’t recognize.
See more details on the annotation translation to [TypeScript](/docs/targets/typescript#annotations), [Rust](/docs/targets/rust#annotations), and [Python](/docs/targets/python#annotations).
# Python Target Overview
> Genotype's Python target overview.
Genotype generates idiomatic Python code that can be used directly in the application or published as a package.
This overview shows how Genotype types translate to Python, target-specific features and configuration options.
See the [Quick Genotype Language Tour](/docs/language) for the language overview and [Python Configuration](/docs/targets/python/configuration) for detailed configuration reference.
## Translation
[Section titled “Translation”](#translation)
The following examples give an overview of how Genotype translates into Python.
Note
Latest and Legacy tabs show differences between [Python versions](/docs/targets/python/configuration#pyversion---python-version). Examples without tabs apply to both. Feature examples omit imports. Genotype includes the required standard library, [Pydantic](https://pypi.org/project/pydantic/), and [Genotype runtime](https://pypi.org/project/genotype-runtime/) imports. The [complete module](#complete-module) below shows them together.
### Complete Module
[Section titled “Complete Module”](#complete-module)
This source combines an object, a literal field, an optional field, a record, and `any`:
```type
Book: {
kind: "book",
displayTitle: string,
subtitle?: string,
ratings: { []: int },
extra: any,
}
```
The generated module includes its type definitions and imports:
* Latest
```python
from __future__ import annotations
from typing import Literal, Optional, Any
from pydantic import Field
from genotype import Model
class Book(Model):
kind: Literal["book"]
display_title: str = Field(alias="displayTitle")
subtitle: Optional[str] = None
ratings: dict[str, int]
extra: Any
```
* Legacy
```python
from __future__ import annotations
from typing import Literal, Optional, Dict, Any
from pydantic import Field
from genotype import Model
class Book(Model):
kind: Literal["book"]
display_title: str = Field(alias="displayTitle")
subtitle: Optional[str] = None
ratings: Dict[str, int]
extra: Any
```
### Unions
[Section titled “Unions”](#unions)
Genotype unions translate into Python union types. Legacy output uses `Union[...]`.
```type
Value: string | int
```
* Latest
```python
type Value = str | int
```
* Legacy
```python
Value = Union[str, int]
```
### Primitives
[Section titled “Primitives”](#primitives)
#### Numeric Types
[Section titled “Numeric Types”](#numeric-types)
##### `number`
[Section titled “number”](#number)
Genotype `number` translates into the Python `float` type.
```type
Amount: number
```
* Latest
```python
type Amount = float
```
* Legacy
```python
Amount = float
```
##### `int`
[Section titled “int”](#int)
Genotype `int` translates directly to the Python `int` type.
```type
Count: int
```
* Latest
```python
type Count = int
```
* Legacy
```python
Count = int
```
##### `float`
[Section titled “float”](#float)
Genotype `float` translates directly to the Python `float` type.
```type
Ratio: float
```
* Latest
```python
type Ratio = float
```
* Legacy
```python
Ratio = float
```
##### Sized Numeric Types
[Section titled “Sized Numeric Types”](#sized-numeric-types)
Sized Genotype integers translate into Python `int`, and sized floating-point types translate into `float`.
```type
SmallCount: i16
PreciseRatio: f32
LargeCount: i128
```
* Latest
```python
type SmallCount = int
type PreciseRatio = float
type LargeCount = int
```
* Legacy
```python
SmallCount = int
PreciseRatio = float
LargeCount = int
```
#### Booleans
[Section titled “Booleans”](#booleans)
Genotype `boolean` translates into the Python `bool` type.
```type
Ready: boolean
```
* Latest
```python
type Ready = bool
```
* Legacy
```python
Ready = bool
```
#### Strings
[Section titled “Strings”](#strings)
Genotype `string` translates into the Python `str` type.
```type
Title: string
```
* Latest
```python
type Title = str
```
* Legacy
```python
Title = str
```
#### Literal Types
[Section titled “Literal Types”](#literal-types)
Genotype literal types translate into Python `Literal` types, preserving their exact values.
```type
Category: "fiction"
```
* Latest
```python
type Category = Literal["fiction"]
```
* Legacy
```python
Category = Literal["fiction"]
```
#### Null
[Section titled “Null”](#null)
Genotype `null` translates into Python `Literal[None]`.
```type
Empty: null
```
* Latest
```python
type Empty = Literal[None]
```
* Legacy
```python
Empty = Literal[None]
```
#### Branded Primitives
[Section titled “Branded Primitives”](#branded-primitives)
Genotype branded primitives translate into Python `NewType` definitions. Type checkers distinguish them; runtime values retain the underlying primitive.
```type
BookId: @string
```
```python
BookId = NewType("BookId", str)
```
### Composite Types
[Section titled “Composite Types”](#composite-types)
#### Objects
[Section titled “Objects”](#objects)
Genotype objects translate into classes extending the [Genotype runtime](https://pypi.org/project/genotype-runtime/)’s [Pydantic](https://pypi.org/project/pydantic/)-based `Model`. Nested objects become separate model classes.
```type
Book: { title: string }
```
```python
class Book(Model):
title: str
```
Use `Book.model_validate(data)` to validate incoming data and `book.model_dump()` to serialize it. Field names use `snake_case`, with aliases preserving their original names in serialized data.
##### Optional Object Fields
[Section titled “Optional Object Fields”](#optional-object-fields)
Optional Genotype object fields translate into Python `Optional[T]` fields, defaulting to `None`.
```type
Draft: { subtitle?: string }
```
```python
class Draft(Model):
subtitle: Optional[str] = None
```
##### Object Extensions
[Section titled “Object Extensions”](#object-extensions)
Genotype object extensions translate into Python model inheritance.
```type
Named: { name: string }
NamedBook: { ...Named, pages: int }
```
```python
class Named(Model):
name: str
class NamedBook(Named, Model):
pages: int
```
#### Arrays
[Section titled “Arrays”](#arrays)
Genotype arrays translate into Python `list[T]` types. Legacy output uses `List[T]`.
```type
Titles: [string]
```
* Latest
```python
type Titles = list[str]
```
* Legacy
```python
Titles = List[str]
```
#### Tuples
[Section titled “Tuples”](#tuples)
Genotype tuples translate into Python `tuple` types. Legacy output uses `Tuple[...]`.
```type
Point: (float, float)
```
* Latest
```python
type Point = tuple[float, float]
```
* Legacy
```python
Point = Tuple[float, float]
```
#### Records
[Section titled “Records”](#records)
Genotype records translate into Python `dict[K, V]` types. Legacy output uses `Dict[K, V]`. An omitted key type means string keys.
```type
Scores: { []: int }
```
* Latest
```python
type Scores = dict[str, int]
```
* Legacy
```python
Scores = Dict[str, int]
```
### Special Data Types
[Section titled “Special Data Types”](#special-data-types)
#### Any Type
[Section titled “Any Type”](#any-type)
Genotype `any` translates into Python `typing.Any`.
```type
Payload: any
```
* Latest
```python
type Payload = Any
```
* Legacy
```python
Payload = Any
```
### Generic Types
[Section titled “Generic Types”](#generic-types)
Genotype generic types translate into Python generic models or aliases. You can specialize this model as `Envelope[Book]`.
```type
Envelope: { body: Body }
```
* Latest
```python
class Envelope[Body](Model):
body: Body
```
* Legacy
```python
Body = TypeVar("Body")
class Envelope(Model, Generic[Body]):
body: Body
```
### Recursive Types
[Section titled “Recursive Types”](#recursive-types)
Genotype recursive types translate into Python recursive types with forward references where needed.
```type
LinkedNode: { value: string, next?: LinkedNode }
```
```python
class LinkedNode(Model):
value: str
next: Optional[LinkedNode] = None
```
### Annotations
[Section titled “Annotations”](#annotations)
The `discriminator` annotation adds metadata to a union’s JSON Schema:
```type
#[discriminator = "status"]
Result: Success | Failure
Success: { status: "ok", body: string }
Failure: { status: "error", message: string }
```
The generated union includes Pydantic field metadata identifying `status` as the discriminator. This adds schema metadata; it doesn’t configure Pydantic’s discriminated-union validation.
## Configuration
[Section titled “Configuration”](#configuration)
Use `[py]` in `genotype.toml` to configure Python. See the [Python Configuration Reference](/docs/targets/python/configuration) for more details.
See [Genotype Configuration](/docs/toolchain/configuration) for global settings and [Common Target Options](/docs/toolchain/configuration#common-target-options).
# Python Target Configuration
> Python target configuration for the Genotype programming language.
To configure Python target, use `[py]` in `genotype.toml`.
This configuration reference lists all available Python configuration options.
See the [Genotype Configuration](/docs/toolchain/configuration) for global settings and [Common Target Options](/docs/toolchain/configuration#common-target-options).
## Basic
[Section titled “Basic”](#basic)
### `py.enabled` - Enable Target
[Section titled “py.enabled - Enable Target”](#pyenabled---enable-target)
Set to `true` to generate Python. Defaults to `false`; see [enable target](/docs/toolchain/configuration#targetenabled---enable-target).
```toml
[py]
enabled = true
```
## Generation
[Section titled “Generation”](#generation)
### `py.version` - Python Version
[Section titled “py.version - Python Version”](#pyversion---python-version)
`version` selects the Python syntax generation mode:
* `"latest"` (default): Python 3.13 and later, using modern syntax such as `type` aliases.
* `"legacy"`: Python 3.8 and later, using older typing constructs and [typing-extensions](https://pypi.org/project/typing-extensions/) where needed.
```toml
[py]
enabled = true
version = "latest"
```
Note
`py.version` selects the language mode. To set the Python package’s release version, use the [global version](/docs/toolchain/configuration#version---package-version) or [Python manifest](#pymanifest---pyprojecttoml).
## Package
[Section titled “Package”](#package)
### `py.package` - Package Generation
[Section titled “py.package - Package Generation”](#pypackage---package-generation)
Overrides package generation for Python. Inherits the global setting when omitted; see [target package generation](/docs/toolchain/configuration#targetpackage---package-generation).
### `py.dist` - Output Directory
[Section titled “py.dist - Output Directory”](#pydist---output-directory)
Defaults to `"py"`, relative to the global output directory. See [target output directory](/docs/toolchain/configuration#targetdist---output-directory).
### `py.manager` - Package Manager
[Section titled “py.manager - Package Manager”](#pymanager---package-manager)
`manager` selects the generated [Python manifest](#pymanifest---pyprojecttoml) format:
* `"poetry"` (default): Poetry metadata under `[tool.poetry]`.
* `"uv"`: Package metadata under `[project]`.
```toml
[py]
enabled = true
version = "latest"
manager = "uv"
```
### `py.module` - Module Name
[Section titled “py.module - Module Name”](#pymodule---module-name)
`module` sets the generated Python package’s importable module name. It defaults to `"module"`:
```toml
[py]
enabled = true
version = "latest"
module = "bookstore_types"
```
With [package generation](/docs/toolchain/configuration#targetpackage---package-generation) enabled, source files go into this directory inside the [target output directory](/docs/toolchain/configuration#targetdist---output-directory), e.g., `dist/py/bookstore_types`.
### `[py.manifest]` - pyproject.toml
[Section titled “\[py.manifest\] - pyproject.toml”](#pymanifest---pyprojecttoml)
[Manifest options](/docs/toolchain/configuration#targetmanifest---package-metadata) in `[py.manifest]` follow the `pyproject.toml` structure. The default package name uses `kebab-case`. The location of package name and version overrides depends on [manager](#pymanager---package-manager):
* Poetry
```toml
[py]
enabled = true
version = "latest"
manager = "poetry"
[py.manifest.tool.poetry]
name = "bookstore-types"
version = "0.2.0"
description = "Shared bookstore types"
[py.manifest.tool.poetry.dependencies]
bookstore-shared = "^1.0.0"
```
* uv
```toml
[py]
enabled = true
version = "latest"
manager = "uv"
[py.manifest.project]
name = "bookstore-types"
version = "0.2.0"
description = "Shared bookstore types"
```
With `uv`, Genotype replaces `project.dependencies` with its detected runtime dependencies. Additional dependencies configured in that array aren’t preserved.
## Modules
[Section titled “Modules”](#modules)
### `[py.dependencies]` - External Modules
[Section titled “\[py.dependencies\] - External Modules”](#pydependencies---external-modules)
Values in [dependencies](/docs/toolchain/configuration#targetdependencies---external-modules) are Python module import paths, which may differ from their distribution names:
```toml
[py]
enabled = true
version = "latest"
[py.dependencies]
shared_types = "bookstore_shared"
```
## Formatting
[Section titled “Formatting”](#formatting)
### `py.formatters` - Formatters
[Section titled “py.formatters - Formatters”](#pyformatters---formatters)
Adds formatters for Python; defaults to `[]`. See [target formatters](/docs/toolchain/configuration#targetformatters---formatters) for execution order and [formatter configuration](/docs/toolchain/configuration#formatters---formatters) for commands and presets.
# Rust Target Overview
> Genotype's Rust target overview.
Genotype generates idiomatic Rust code that can be used directly in the application or published as a package.
This overview shows how Genotype types translate to Rust, target-specific features and configuration options.
See the [Quick Genotype Language Tour](/docs/language) for the language overview and [Rust Configuration](/docs/targets/rust/configuration) for detailed configuration reference.
## Translation
[Section titled “Translation”](#translation)
The following examples give an overview of how Genotype translates into Rust.
Note
Feature examples omit imports. Genotype includes the required [Serde](https://crates.io/crates/serde), [Litty](https://crates.io/crates/litty), [Genotype runtime](https://crates.io/crates/genotype_runtime), and standard library imports. The [complete module](#complete-module) below shows them together.
### Complete Module
[Section titled “Complete Module”](#complete-module)
This source combines an object, a literal field, an optional field, a record, and `any`:
```type
Book: {
kind: "book",
displayTitle: string,
subtitle?: string,
ratings: { []: int },
extra: any,
}
```
The generated module includes its type definitions and imports:
```rust
use std::collections::BTreeMap;
use genotype_runtime::Any;
use litty::serde_literals;
use serde::{Deserialize, Serialize};
#[serde_literals]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[literals(kind = "book")]
pub struct Book {
#[serde(rename = "displayTitle")]
pub display_title: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub subtitle: Option,
pub ratings: BTreeMap,
pub extra: Any,
}
```
### Unions
[Section titled “Unions”](#unions)
Genotype unions translate into Rust enums. Non-literal unions use untagged serialization to preserve the original data shape.
```type
Value: string | int
```
```rust
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Value {
String(String),
Int(i64),
}
```
### Primitives
[Section titled “Primitives”](#primitives)
#### Numeric Types
[Section titled “Numeric Types”](#numeric-types)
##### `number`
[Section titled “number”](#number)
Genotype `number` translates into the Rust `f64` type.
```type
Amount: number
```
```rust
pub type Amount = f64;
```
##### `int`
[Section titled “int”](#int)
Genotype `int` translates into the Rust `i64` type.
```type
Count: int
```
```rust
pub type Count = i64;
```
##### `float`
[Section titled “float”](#float)
Genotype `float` translates into the Rust `f64` type.
```type
Ratio: float
```
```rust
pub type Ratio = f64;
```
##### Sized Numeric Types
[Section titled “Sized Numeric Types”](#sized-numeric-types)
Sized Genotype numeric types translate directly to their Rust counterparts.
```type
SmallCount: i16
PreciseRatio: f32
LargeCount: i128
```
```rust
pub type SmallCount = i16;
pub type PreciseRatio = f32;
pub type LargeCount = i128;
```
#### Booleans
[Section titled “Booleans”](#booleans)
Genotype `boolean` translates into the Rust `bool` type.
```type
Ready: boolean
```
```rust
pub type Ready = bool;
```
#### Strings
[Section titled “Strings”](#strings)
Genotype `string` translates into the Rust owned `String` type.
```type
Title: string
```
```rust
pub type Title = String;
```
#### Literal Types
[Section titled “Literal Types”](#literal-types)
Genotype literal types translate into named Rust structs with attributes that preserve the exact serialized value.
```type
Category: "fiction"
```
```rust
#[serde_literal("fiction")]
#[derive(Serialize, Deserialize)]
pub struct Category;
```
#### Null
[Section titled “Null”](#null)
Genotype `null` translates into a Rust type that serializes as null.
```type
Empty: null
```
```rust
#[serde_literal(null)]
#[derive(Serialize, Deserialize)]
pub struct Empty;
```
#### Branded Primitives
[Section titled “Branded Primitives”](#branded-primitives)
Genotype branded primitives translate into Rust newtype structs, distinct from their underlying primitive.
```type
BookId: @string
```
```rust
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BookId(pub String);
```
### Composite Types
[Section titled “Composite Types”](#composite-types)
#### Objects
[Section titled “Objects”](#objects)
Genotype objects translate into public Rust structs with [Serde](https://crates.io/crates/serde) support. Nested objects become separate named structs.
```type
Book: { title: string }
```
```rust
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Book {
pub title: String,
}
```
##### Optional Object Fields
[Section titled “Optional Object Fields”](#optional-object-fields)
Optional Genotype object fields translate into Rust `Option` fields. Absent values are omitted during serialization.
```type
Draft: { subtitle?: string }
```
```rust
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Draft {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub subtitle: Option,
}
```
##### Object Extensions
[Section titled “Object Extensions”](#object-extensions)
Genotype object extensions translate into Rust structs containing the base struct’s fields.
```type
Named: { name: string }
NamedBook: { ...Named, pages: int }
```
```rust
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Named {
pub name: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct NamedBook {
pub name: String,
pub pages: i64,
}
```
#### Arrays
[Section titled “Arrays”](#arrays)
Genotype arrays translate into Rust `Vec` types.
```type
Titles: [string]
```
```rust
pub type Titles = Vec;
```
#### Tuples
[Section titled “Tuples”](#tuples)
Genotype tuples translate directly to Rust tuple types.
```type
Point: (float, float)
```
```rust
pub type Point = (f64, f64);
```
#### Records
[Section titled “Records”](#records)
Genotype records translate into Rust `BTreeMap` types. An omitted key type means string keys.
```type
Scores: { []: int }
```
```rust
pub type Scores = BTreeMap;
```
### Special Data Types
[Section titled “Special Data Types”](#special-data-types)
#### Any Type
[Section titled “Any Type”](#any-type)
Genotype `any` translates into the [Genotype runtime](https://crates.io/crates/genotype_runtime)’s `Any` type.
```type
Payload: any
```
```rust
pub type Payload = Any;
```
### Generic Types
[Section titled “Generic Types”](#generic-types)
Genotype generic types translate into Rust generic types.
```type
Envelope: { body: Body }
```
```rust
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Envelope {
pub body: Body,
}
```
### Recursive Types
[Section titled “Recursive Types”](#recursive-types)
Genotype recursive types translate into Rust types with `Box` indirection where needed to give them a finite size.
```type
LinkedNode: { value: string, next?: LinkedNode }
```
```rust
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct LinkedNode {
pub value: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub next: Option>,
}
```
### Annotations
[Section titled “Annotations”](#annotations)
Annotations let you customize enum variants directly in Genotype:
```type
Status:
| #[variant = "Available"] "in_stock"
| "sold_out"
```
Here `variant` names the Rust variant `Available`. Its serialized value remains `"in_stock"`.
## Configuration
[Section titled “Configuration”](#configuration)
Use `[rs]` in `genotype.toml` to configure Rust. See the [Rust Configuration Reference](/docs/targets/rust/configuration) for more details.
See [Genotype Configuration](/docs/toolchain/configuration) for global settings and [Common Target Options](/docs/toolchain/configuration#common-target-options).
# Rust Target Configuration
> Rust target configuration for the Genotype programming language.
To configure Rust target, use `[rs]` in `genotype.toml`.
This configuration reference lists all available Rust configuration options.
See the [Genotype Configuration](/docs/toolchain/configuration) for global settings and [Common Target Options](/docs/toolchain/configuration#common-target-options).
## Basic
[Section titled “Basic”](#basic)
### `rs.enabled` - Enable Target
[Section titled “rs.enabled - Enable Target”](#rsenabled---enable-target)
Set to `true` to generate Rust. Defaults to `false`; see [enable target](/docs/toolchain/configuration#targetenabled---enable-target).
```toml
[rs]
enabled = true
```
## Generation
[Section titled “Generation”](#generation)
### `rs.derive` - Derive Traits
[Section titled “rs.derive - Derive Traits”](#rsderive---derive-traits)
`derive` sets the base list of traits derived for generated structs and enums. It defaults to `["Debug", "Clone", "PartialEq"]`:
```toml
[rs]
enabled = true
derive = ["Debug", "Clone", "PartialEq", "Eq", "Hash"]
```
The configured list replaces the default list. Genotype also adds traits required by generated types, including [Serde](https://crates.io/crates/serde) serialization and deserialization derives. `Default` is currently omitted from union enum derives.
Including `Eq`, `Hash`, or `Ord` makes Genotype use ordered float wrappers for floating-point values so they can support those traits.
## Package
[Section titled “Package”](#package)
### `rs.package` - Package Generation
[Section titled “rs.package - Package Generation”](#rspackage---package-generation)
Overrides package generation for Rust. Inherits the global setting when omitted; see [target package generation](/docs/toolchain/configuration#targetpackage---package-generation).
### `rs.dist` - Output Directory
[Section titled “rs.dist - Output Directory”](#rsdist---output-directory)
Defaults to `"rs"`, relative to the global output directory. See [target output directory](/docs/toolchain/configuration#targetdist---output-directory).
### `[rs.manifest]` - Cargo.toml
[Section titled “\[rs.manifest\] - Cargo.toml”](#rsmanifest---cargotoml)
[Manifest options](/docs/toolchain/configuration#targetmanifest---package-metadata) in `[rs.manifest]` follow the `Cargo.toml` structure. Set package metadata under `[rs.manifest.package]`:
```toml
[rs.manifest.package]
name = "bookstore_types"
version = "0.2.0"
edition = "2024"
license = "MIT"
[rs.manifest.dependencies]
shared_types = "1"
```
The generated crate has a `src/lib.rs` entry point and defaults to edition `"2024"`. Its default name uses `snake_case`. See [package generation](/docs/toolchain/configuration#targetpackage---package-generation) for layout controls.
Tip
Set `rs.manifest.package.edition` explicitly to lock the edition. Genotype warns when it is omitted and Rust package generation is enabled.
## Modules
[Section titled “Modules”](#modules)
### `[rs.dependencies]` - External Modules
[Section titled “\[rs.dependencies\] - External Modules”](#rsdependencies---external-modules)
Values in [dependencies](/docs/toolchain/configuration#targetdependencies---external-modules) are Rust crate paths used in generated imports:
```toml
[rs.dependencies]
shared_types = "bookstore_shared"
```
## Formatting
[Section titled “Formatting”](#formatting)
### `rs.formatters` - Formatters
[Section titled “rs.formatters - Formatters”](#rsformatters---formatters)
Adds formatters for Rust; defaults to `[]`. See [target formatters](/docs/toolchain/configuration#targetformatters---formatters) for execution order and [formatter configuration](/docs/toolchain/configuration#formatters---formatters) for commands and presets.
# TypeScript Target Overview
> Genotype's TypeScript target overview.
Genotype generates idiomatic TypeScript code that can be used directly in the application or published as a package.
This overview shows how Genotype types translate to TypeScript, target-specific features and configuration options.
See the [Quick Genotype Language Tour](/docs/language) for the language overview and [TypeScript Configuration](/docs/targets/typescript/configuration) for detailed configuration reference.
## Translation
[Section titled “Translation”](#translation)
The following examples give an overview of how Genotype translates into TypeScript.
Note
Object examples show [Interfaces and Aliases](/docs/targets/typescript/configuration#tsprefer---interfaces-or-type-aliases); other examples use Types. All include [Zod output](/docs/targets/typescript/configuration#tsmode---generation-mode). Feature examples omit imports; Zod examples use `z` from [Zod](https://www.npmjs.com/package/zod). The [Complete Module](#complete-module) includes imports.
### Complete Module
[Section titled “Complete Module”](#complete-module)
This source combines an object, a literal field, an optional field, a record, and `any`:
```type
Book: {
kind: "book",
displayTitle: string,
subtitle?: string,
ratings: { []: int },
extra: any,
}
```
The generated module includes its definitions and any required imports:
* Interfaces
```ts
export interface Book {
kind: "book";
displayTitle: string;
subtitle?: string | undefined;
ratings: Record;
extra: any;
}
```
* Aliases
```ts
export type Book = {
kind: "book";
displayTitle: string;
subtitle?: string | undefined;
ratings: Record;
extra: any;
};
```
* Zod
```ts
import { z } from "zod";
export const Book = z.object({
kind: z.literal("book"),
displayTitle: z.string(),
subtitle: z.union([z.string(), z.undefined()]).optional(),
ratings: z.record(z.string(), z.number()),
extra: z.any()
});
export type Book = z.infer;
```
### Unions
[Section titled “Unions”](#unions)
Genotype unions translate directly to TypeScript union types.
```type
Value: string | int
```
* Types
```ts
export type Value = string | number;
```
* Zod
```ts
export const Value = z.union([z.string(), z.number()]);
export type Value = z.infer;
```
### Primitives
[Section titled “Primitives”](#primitives)
#### Numeric Types
[Section titled “Numeric Types”](#numeric-types)
##### `number`
[Section titled “number”](#number)
Genotype `number` translates directly to the TypeScript `number` type.
```type
Amount: number
```
* Types
```ts
export type Amount = number;
```
* Zod
```ts
export const Amount = z.number();
export type Amount = z.infer;
```
##### `int`
[Section titled “int”](#int)
Genotype `int` translates into the TypeScript umbrella `number` type.
```type
Count: int
```
* Types
```ts
export type Count = number;
```
* Zod
```ts
export const Count = z.number();
export type Count = z.infer;
```
##### `float`
[Section titled “float”](#float)
Genotype `float` translates into the TypeScript umbrella `number` type.
```type
Ratio: float
```
* Types
```ts
export type Ratio = number;
```
* Zod
```ts
export const Ratio = z.number();
export type Ratio = z.infer;
```
##### Sized Numeric Types
[Section titled “Sized Numeric Types”](#sized-numeric-types)
Sized Genotype numeric types translate into the TypeScript umbrella `number` type, except for `i128` and `u128`, which translate into `bigint`.
```type
SmallCount: i16
PreciseRatio: f32
LargeCount: i128
```
* Types
```ts
export type SmallCount = number;
export type PreciseRatio = number;
export type LargeCount = bigint;
```
* Zod
```ts
export const SmallCount = z.number();
export type SmallCount = z.infer;
export const PreciseRatio = z.number();
export type PreciseRatio = z.infer;
export const LargeCount = z.bigint();
export type LargeCount = z.infer;
```
#### Booleans
[Section titled “Booleans”](#booleans)
Genotype `boolean` translates directly to the TypeScript `boolean` type.
```type
Ready: boolean
```
* Types
```ts
export type Ready = boolean;
```
* Zod
```ts
export const Ready = z.boolean();
export type Ready = z.infer;
```
#### Strings
[Section titled “Strings”](#strings)
Genotype `string` translates directly to the TypeScript `string` type.
```type
Title: string
```
* Types
```ts
export type Title = string;
```
* Zod
```ts
export const Title = z.string();
export type Title = z.infer;
```
#### Literal Types
[Section titled “Literal Types”](#literal-types)
Genotype literal types translate directly to TypeScript literal types.
```type
Category: "fiction"
```
* Types
```ts
export type Category = "fiction";
```
* Zod
```ts
export const Category = z.literal("fiction");
export type Category = z.infer;
```
#### Null
[Section titled “Null”](#null)
Genotype `null` translates directly to the TypeScript `null` type.
```type
Empty: null
```
* Types
```ts
export type Empty = null;
```
* Zod
```ts
export const Empty = z.literal(null);
export type Empty = z.infer;
```
#### Branded Primitives
[Section titled “Branded Primitives”](#branded-primitives)
Genotype branded primitives translate into branded TypeScript types. Their runtime values remain unchanged.
```type
BookId: @string
```
* Types
```ts
export type BookId = string & { [bookIdBrand]: true };
declare const bookIdBrand: unique symbol;
```
* Zod
```ts
export const BookId = z.string().brand<"BookId">();
export type BookId = z.infer;
```
### Composite Types
[Section titled “Composite Types”](#composite-types)
#### Objects
[Section titled “Objects”](#objects)
Genotype objects translate into TypeScript interfaces or type aliases. Choose the output style with [ts.prefer](/docs/targets/typescript/configuration#tsprefer---interfaces-or-type-aliases).
```type
Book: { title: string }
```
* Interfaces
```ts
export interface Book {
title: string;
}
```
* Aliases
```ts
export type Book = {
title: string;
};
```
* Zod
```ts
export const Book = z.object({
title: z.string()
});
export type Book = z.infer;
```
##### Optional Object Fields
[Section titled “Optional Object Fields”](#optional-object-fields)
Optional Genotype object fields translate into optional TypeScript properties.
```type
Draft: { subtitle?: string }
```
* Interfaces
```ts
export interface Draft {
subtitle?: string | undefined;
}
```
* Aliases
```ts
export type Draft = {
subtitle?: string | undefined;
};
```
* Zod
```ts
export const Draft = z.object({
subtitle: z.union([z.string(), z.undefined()]).optional()
});
export type Draft = z.infer;
```
##### Object Extensions
[Section titled “Object Extensions”](#object-extensions)
Genotype object extensions translate into interface inheritance or type intersections.
```type
Named: { name: string }
NamedBook: { ...Named, pages: int }
```
* Interfaces
```ts
export interface Named {
name: string;
}
export interface NamedBook extends Named {
pages: number;
}
```
* Aliases
```ts
export type Named = {
name: string;
};
export type NamedBook = Named & {
pages: number;
};
```
* Zod
```ts
export const Named = z.object({
name: z.string()
});
export type Named = z.infer;
export const NamedBook = Named.extend({
pages: z.number()
});
export type NamedBook = z.infer;
```
#### Arrays
[Section titled “Arrays”](#arrays)
Genotype arrays translate into TypeScript `Array` types.
```type
Titles: [string]
```
* Types
```ts
export type Titles = Array;
```
* Zod
```ts
export const Titles = z.array(z.string());
export type Titles = z.infer;
```
#### Tuples
[Section titled “Tuples”](#tuples)
Genotype tuples translate directly to TypeScript tuple types.
```type
Point: (float, float)
```
* Types
```ts
export type Point = [number, number];
```
* Zod
```ts
export const Point = z.tuple([z.number(), z.number()]);
export type Point = z.infer;
```
#### Records
[Section titled “Records”](#records)
Genotype records translate into TypeScript `Record` types. An omitted key type means string keys.
```type
Scores: { []: int }
```
* Types
```ts
export type Scores = Record;
```
* Zod
```ts
export const Scores = z.record(z.string(), z.number());
export type Scores = z.infer;
```
### Special Data Types
[Section titled “Special Data Types”](#special-data-types)
#### Any Type
[Section titled “Any Type”](#any-type)
Genotype `any` translates directly to the TypeScript `any` type.
```type
Payload: any
```
* Types
```ts
export type Payload = any;
```
* Zod
```ts
export const Payload = z.any();
export type Payload = z.infer;
```
### Generic Types
[Section titled “Generic Types”](#generic-types)
Genotype generic types translate into TypeScript generic types. Zod output uses functions accepting schemas, e.g., `Envelope(Book)`.
```type
Envelope: { body: Body }
```
* Interfaces
```ts
export interface Envelope {
body: Body;
}
```
* Aliases
```ts
export type Envelope = {
body: Body;
};
```
* Zod
```ts
export const Envelope = (Body: Body) => z.object({
body: Body
});
export type Envelope = z.infer>>;
```
### Recursive Types
[Section titled “Recursive Types”](#recursive-types)
Genotype recursive types translate directly to TypeScript recursive types. Zod output uses getters or lazy schemas.
```type
LinkedNode: { value: string, next?: LinkedNode }
```
* Interfaces
```ts
export interface LinkedNode {
value: string;
next?: LinkedNode | undefined;
}
```
* Aliases
```ts
export type LinkedNode = {
value: string;
next?: LinkedNode | undefined;
};
```
* Zod
```ts
export const LinkedNode = z.object({
value: z.string(),
get next() {
return z.union([LinkedNode, z.undefined()]).optional()
}
});
export type LinkedNode = z.infer;
```
### Annotations
[Section titled “Annotations”](#annotations)
Annotations intended for other targets, such as Rust enum variant names, don’t affect TypeScript output.
## Configuration
[Section titled “Configuration”](#configuration)
Use `[ts]` in `genotype.toml` to configure TypeScript. See the [TypeScript Configuration Reference](/docs/targets/typescript/configuration) for more details.
See [Genotype Configuration](/docs/toolchain/configuration) for global settings and [Common Target Options](/docs/toolchain/configuration#common-target-options).
# TypeScript Target Configuration
> TypeScript target configuration for the Genotype programming language.
To configure TypeScript target, use `[ts]` in `genotype.toml`.
This configuration reference lists all available TypeScript configuration options.
See the [Genotype Configuration](/docs/toolchain/configuration) for global settings and [Common Target Options](/docs/toolchain/configuration#common-target-options).
## Basic
[Section titled “Basic”](#basic)
### `ts.enabled` - Enable Target
[Section titled “ts.enabled - Enable Target”](#tsenabled---enable-target)
Set to `true` to generate TypeScript. Defaults to `false`; see [enable target](/docs/toolchain/configuration#targetenabled---enable-target).
```toml
[ts]
enabled = true
```
## Generation
[Section titled “Generation”](#generation)
### `ts.mode` - Generation Mode
[Section titled “ts.mode - Generation Mode”](#tsmode---generation-mode)
`mode` selects what Genotype generates:
* `"types"` (default): TypeScript type definitions.
* `"zod"`: [Zod](https://www.npmjs.com/package/zod) schemas and inferred types for runtime validation. Adds Zod to the generated package’s dependencies.
```toml
[ts]
enabled = true
mode = "zod"
```
See the [TypeScript guide](/docs/targets/typescript) for generated code examples.
### `ts.prefer` - Interfaces or Type Aliases
[Section titled “ts.prefer - Interfaces or Type Aliases”](#tsprefer---interfaces-or-type-aliases)
`prefer` selects how object type definitions are rendered in `types` mode:
* `"interface"` (default): Generate interfaces, e.g., `interface Book { ... }`.
* `"alias"`: Generate type aliases, e.g., `type Book = { ... }`.
```toml
[ts]
enabled = true
prefer = "alias"
```
### `ts.ext` - Import Extensions
[Section titled “ts.ext - Import Extensions”](#tsext---import-extensions)
`ext` selects the extension used in generated local imports and re-exports:
* `"js"` (default): JavaScript extensions, e.g., `"./book.js"`.
* `"ts"`: TypeScript extensions, e.g., `"./book.ts"`.
* `"none"`: No extension, e.g., `"./book"`.
```toml
[ts]
enabled = true
ext = "none"
```
Generated source files always have the `.ts` extension.
### `[ts.naming]` - Source File and Directory Names
[Section titled “\[ts.naming\] - Source File and Directory Names”](#tsnaming---source-file-and-directory-names)
`naming.source_file` controls generated file names. It defaults to `"camelCase"`.
`naming.source_dir` controls generated directory names. When omitted, it follows `naming.source_file`.
Both accept:
* `"camelCase"`
* `"PascalCase"`
* `"snake_case"`
* `"kebab-case"`
```toml
[ts.naming]
source_file = "camelCase"
source_dir = "kebab-case"
```
This turns `shop_goods/order_item.type` into `shop-goods/orderItem.ts`. Generated local import paths use the same naming rules.
## Package
[Section titled “Package”](#package)
### `ts.package` - Package Generation
[Section titled “ts.package - Package Generation”](#tspackage---package-generation)
Overrides package generation for TypeScript. Inherits the global setting when omitted; see [target package generation](/docs/toolchain/configuration#targetpackage---package-generation).
### `ts.dist` - Output Directory
[Section titled “ts.dist - Output Directory”](#tsdist---output-directory)
Defaults to `"ts"`, relative to the global output directory. See [target output directory](/docs/toolchain/configuration#targetdist---output-directory).
### `[ts.manifest]` - package.json
[Section titled “\[ts.manifest\] - package.json”](#tsmanifest---packagejson)
[Manifest options](/docs/toolchain/configuration#targetmanifest---package-metadata) in `[ts.manifest]` become fields in `package.json`. Package name and version overrides go directly in that table:
```toml
[ts.manifest]
name = "@bookstore/types"
version = "0.2.0"
private = true
[ts.manifest.dependencies]
"@bookstore/shared-types" = "^1.0.0"
```
The generated package uses ES modules, with source files under `src` and an `index.ts` entry point. Its default name uses `kebab-case`. See [package generation](/docs/toolchain/configuration#targetpackage---package-generation) for layout controls.
### `[ts.tsconfig]` - tsconfig.json
[Section titled “\[ts.tsconfig\] - tsconfig.json”](#tstsconfig---tsconfigjson)
`tsconfig` is an optional table written as `tsconfig.json` in the TypeScript package directory. When omitted, no `tsconfig.json` is generated:
```toml
[ts.tsconfig]
include = ["src/**/*.ts"]
[ts.tsconfig.compilerOptions]
strict = true
noEmit = true
module = "NodeNext"
moduleResolution = "NodeNext"
```
The table is converted directly to JSON, without adding compiler option defaults. It has no effect when [package generation](/docs/toolchain/configuration#targetpackage---package-generation) is disabled.
## Modules
[Section titled “Modules”](#modules)
### `[ts.dependencies]` - External Modules
[Section titled “\[ts.dependencies\] - External Modules”](#tsdependencies---external-modules)
Values in [external modules](/docs/toolchain/configuration#targetdependencies---external-modules) are JavaScript package import paths:
```toml
[ts.dependencies]
shared_types = "@bookstore/shared-types"
```
## Formatting
[Section titled “Formatting”](#formatting)
### `ts.formatters` - Formatters
[Section titled “ts.formatters - Formatters”](#tsformatters---formatters)
Adds formatters for TypeScript; defaults to `[]`. See [target formatters](/docs/toolchain/configuration#targetformatters---formatters) for execution order and [formatter configuration](/docs/toolchain/configuration#formatters---formatters) for commands and presets.
# Genotype CLI
> Genotype's command-line interface.
[The Genotype installation](/docs/getting-started/installation) includes the `gt` binary, which you can use to run Genotype commands.
## Project Paths
[Section titled “Project Paths”](#project-paths)
Genotype resolves a project by searching for `genotype.toml` in a starting directory and then its parents. The first configuration file found defines the project. An explicit configuration path bypasses this search.
Paths can be absolute or relative to the working directory. The resolved [configuration](/docs/toolchain/configuration#root---project-root) determines the project root, source files, and output directories.
## `gt init`
[Section titled “gt init”](#gt-init)
`gt init` starts an interactive wizard that creates `genotype.toml` and a `src` directory, with optional example types:
```sh
gt init [PATH]
```
`PATH` is the directory to create the project in. It defaults to the current directory:
```sh
gt init ./bookstore-types
```
The wizard helps you choose target languages, generate standalone packages or integrate into existing ones, optionally add example types, and install the Genotype agent skill as the final step. You can adjust these choices later in [genotype.toml](/docs/toolchain/configuration).
## `gt skill`
[Section titled “gt skill”](#gt-skill)
### `gt skill install`
[Section titled “gt skill install”](#gt-skill-install)
Install the bundled Genotype agent skill or update existing installations:
```sh
gt skill install [PATH] [--agent AGENT]
gt skill update [PATH]
```
`PATH` defaults to the current directory. Installation prompts for an agent unless `--agent` is specified. Update discovers installed skills in known agent directories under `PATH` and replaces their bundled files with the content from your installed CLI.
See [Agent Skill](/docs/toolchain/skill/) for more info and installation instructions.
### `gt skill update`
[Section titled “gt skill update”](#gt-skill-update)
## `gt build`
[Section titled “gt build”](#gt-build)
`gt build` builds the project using the configuration in `genotype.toml` or a specified configuration file or directory.
```sh
gt build [PATH] [--config CONFIG]
```
`PATH` is the starting directory for [project resolution](#project-paths). It defaults to the current directory:
```sh
gt build
```
Source selection and target options come from [genotype.toml](/docs/toolchain/configuration).
### Configuration File
[Section titled “Configuration File”](#configuration-file)
`--config` selects a configuration file explicitly, instead of searching for `genotype.toml`:
```sh
gt build --config ./genotype.release.toml
```
The path is relative to the working directory, even when you also pass a project path. Paths inside the configuration are resolved from its directory; see [project root](/docs/toolchain/configuration#root---project-root).
Note
`gt build` generates target code. Use the target language’s tools to install dependencies, compile the generated package, or run its tests.
### Exit Status
[Section titled “Exit Status”](#exit-status)
For scripts and CI, a successful build exits with status `0`. Build errors exit with status `1`. Warnings alone don’t cause a build failure.
## `gt version`
[Section titled “gt version”](#gt-version)
`gt version` updates package versions in `genotype.toml`. It has two subcommands: `set` and `bump`.
Changes are saved to the configuration. Run `gt build` afterward to update generated package manifests.
### Version Fields
[Section titled “Version Fields”](#version-fields)
Package versions come from the [global version](/docs/toolchain/configuration#version---package-version) and any overrides in [target manifests](/docs/toolchain/configuration#targetmanifest---package-metadata). Existing overrides are updated even when their targets are disabled.
### `gt version set`
[Section titled “gt version set”](#gt-version-set)
`gt version set` assigns a version to the existing [version fields](#version-fields):
```sh
gt version set VERSION [PATH] [--ts VERSION] [--py VERSION] [--rs VERSION]
```
`PATH` selects the starting directory for [project resolution](#project-paths) and defaults to the current directory.
`VERSION` is required and accepts a semantic version string, e.g., `0.2.0`:
```sh
gt version set 0.2.0
```
If no version fields exist, this adds a global `version`. Otherwise, it updates the fields already present without adding missing global or target fields.
#### Target Version Overrides
[Section titled “Target Version Overrides”](#target-version-overrides)
Use `--ts`, `--py`, or `--rs` to assign a different version to an existing target override. `--rust` is an alias for `--rs`:
```sh
gt version set 0.3.0 --ts 0.4.0 --py 0.5.0 --rs 0.6.0
```
These flags require an existing version in the target manifest. Targets without an override inherit the global version.
The positional `VERSION` must be at least as high as every existing version field, including targets with an override flag.
### `gt version bump`
[Section titled “gt version bump”](#gt-version-bump)
`gt version bump` increments a version component in every existing [version field](#version-fields):
```sh
gt version bump [PART] [PATH]
```
`PATH` selects the starting directory for [project resolution](#project-paths) and defaults to the current directory.
`PART` accepts `major`, `minor`, or `patch` and defaults to `minor`:
```sh
gt version bump
```
Starting from `1.2.3`, each choice produces:
| Command | Result |
| ----------------------- | ------- |
| `gt version bump major` | `2.0.0` |
| `gt version bump minor` | `1.3.0` |
| `gt version bump patch` | `1.2.4` |
Each version is bumped independently. E.g., a patch bump changes a global version of `0.2.0` to `0.2.1` and a TypeScript override of `0.3.4` to `0.3.5`.
To bump another project, specify the part before its path:
```sh
gt version bump patch ./bookstore-types
```
If no version fields exist, the command reports an error. Use `gt version set` to assign an initial version first.
## Help and CLI Version
[Section titled “Help and CLI Version”](#help-and-cli-version)
Run `gt` without arguments to show the available commands. You can also use `--help` or `-h`:
```sh
gt --help
```
Use `--help` with a command to see its arguments and options:
```sh
gt build --help
```
To print the installed CLI version, use `--version` or `-V`:
```sh
gt --version
```
The [`gt version`](#gt-version) command manages your project’s package versions.
# Genotype Configuration
> Genotype's configuration reference.
Genotype uses `genotype.toml` to configure source files, generated packages, and target languages.
Note
This reference covers global settings and common target options. See the target configuration guides for language-specific options:
* [TypeScript](/docs/targets/typescript/configuration)
* [Rust](/docs/targets/rust/configuration)
* [Python](/docs/targets/python/configuration)
Put global options at the top of the file and target options in their corresponding sections:
```toml
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.
## Global Options
[Section titled “Global Options”](#global-options)
### Package Defaults
[Section titled “Package Defaults”](#package-defaults)
#### `package` - Package Generation
[Section titled “package - Package Generation”](#package---package-generation)
`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.
```toml
package = false
```
You can override this setting for individual targets using their [package option](#targetpackage---package-generation).
#### `name` - Project Name
[Section titled “name - Project Name”](#name---project-name)
`name` sets the project name used when generating package manifests:
```toml
name = "bookstore-types"
```
If omitted, Genotype derives the name from the project directory. Use the target’s [manifest](#targetmanifest---package-metadata) to set a different package name.
#### `version` - Package Version
[Section titled “version - Package Version”](#version---package-version)
`version` sets the default package version for all targets. It accepts a semantic version string and has no default:
```toml
version = "0.1.0"
```
A version set in a target’s [manifest](#targetmanifest---package-metadata) overrides this value. If neither is set, the generated manifest omits the version.
### Paths
[Section titled “Paths”](#paths)
#### `root` - Project Root
[Section titled “root - Project Root”](#root---project-root)
`root` sets the project root directory relative to the directory containing `genotype.toml`. It defaults to `"."`:
```toml
root = "./types"
```
#### `src` - Source Directory
[Section titled “src - Source Directory”](#src---source-directory)
`src` sets the source directory relative to [root](#root---project-root). It defaults to `"src"`:
```toml
src = "schemas"
```
#### `entry` - Source Files
[Section titled “entry - Source Files”](#entry---source-files)
`entry` selects source files using a glob pattern relative to [src](#src---source-directory). It defaults to `"**/*.type"`, which includes `.type` files in the source directory and its subdirectories:
```toml
entry = "api/**/*.type"
```
You can also select a single entry file:
```toml
entry = "api.type"
```
Genotype resolves modules imported by the selected files as well.
#### `dist` - Output Directory
[Section titled “dist - Output Directory”](#dist---output-directory)
`dist` sets the output directory relative to [root](#root---project-root). It defaults to `"dist"`:
```toml
dist = "generated"
```
Each target has its own directory inside it. See [target output directory](#targetdist---output-directory) to customize these paths.
### Generation
[Section titled “Generation”](#generation)
#### `build.file` - Build Tracking
[Section titled “build.file - Build Tracking”](#buildfile---build-tracking)
`build.file` controls generated file tracking:
* `true` (default): Read and update `genotype.build.toml` next to the configuration file for [cleanup](#buildcleanup---build-cleanup).
* `false`: Disable build tracking and cleanup.
```toml
[build]
file = true
```
#### `build.cleanup` - Build Cleanup
[Section titled “build.cleanup - Build Cleanup”](#buildcleanup---build-cleanup)
`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.
```toml
[build]
cleanup = false
```
`build.cleanup` has no effect when `build.file = false`. To disable both:
```toml
[build]
file = false
cleanup = false
```
#### `warning_comment` - Generated File Comment
[Section titled “warning\_comment - Generated File Comment”](#warning_comment---generated-file-comment)
`warning_comment` controls the generated file comment:
* `true` (default): Identify generated source files with a comment warning against editing them.
* `false`: Omit the comment.
```toml
warning_comment = false
```
### Formatting
[Section titled “Formatting”](#formatting)
#### `formatters` - Formatters
[Section titled “formatters - Formatters”](#formatters---formatters)
`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](#targetformatters---formatters). Commands run from the target’s output directory.
```toml
formatters = [
{ kind = "shell", cmd = "format-generated", args = ["."] },
]
```
Use target formatters for commands that apply to just one language.
##### Commands
[Section titled “Commands”](#commands)
Use `kind = "shell"` to run an executable directly. `cmd` is required; `args` is an optional array of strings, defaulting to `[]`:
```toml
[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`:
```toml
[rs]
enabled = true
formatters = [{ kind = "cargo", cmd = "fmt", args = ["--all"] }]
```
##### Presets
[Section titled “Presets”](#presets)
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:
```toml
[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 Target Options
[Section titled “Common Target Options”](#common-target-options)
Common options configure target generation independently of the target language. Replace `` with the target section name; examples use `[ts]`.
### Basic
[Section titled “Basic”](#basic)
#### `.enabled` - Enable Target
[Section titled “\.enabled - Enable Target”](#targetenabled---enable-target)
`enabled` controls whether the target is generated:
* `false` (default): Skip the target.
* `true`: Generate the target.
```toml
[ts]
enabled = true
```
### Package
[Section titled “Package”](#package)
#### `.package` - Package Generation
[Section titled “\.package - Package Generation”](#targetpackage---package-generation)
`package` overrides [global package generation](#package---package-generation) for this target. When omitted, it inherits the global value:
```toml
package = false
[ts]
enabled = true
package = true
```
#### `.dist` - Output Directory
[Section titled “\.dist - Output Directory”](#targetdist---output-directory)
`dist` sets the target output directory relative to the [global output directory](#dist---output-directory):
```toml
dist = "generated"
[ts]
enabled = true
dist = "typescript"
```
This writes the example package to `generated/typescript`. The default directory name depends on the target.
#### `[.manifest]` - Package Metadata
[Section titled “\[\.manifest\] - Package Metadata”](#targetmanifest---package-metadata)
`manifest` is a table of package metadata. It defaults to an empty table:
```toml
[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.
### Modules
[Section titled “Modules”](#modules)
#### `[.dependencies]` - External Modules
[Section titled “\[\.dependencies\] - External Modules”](#targetdependencies---external-modules)
`dependencies` maps [external modules](/docs/language#external-modules) to import paths in the target language. It defaults to an empty table:
```toml
[ts.dependencies]
shared_types = "@bookstore/shared-types"
```
You can then import from the mapped module in your source files:
```type
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.
Caution
Genotype doesn’t check that external modules are available or type-check their imported types.
### Formatting
[Section titled “Formatting”](#formatting-1)
#### `.formatters` - Formatters
[Section titled “\.formatters - Formatters”](#targetformatters---formatters)
`formatters` adds formatters for this target. It defaults to `[]` and runs after the global list, without replacing it:
```toml
[ts]
enabled = true
formatters = [{ kind = "oxfmt", via = "pnpm" }]
```
See [formatters](#formatters---formatters) for configuration fields, supported commands, presets, and execution order.
# Genotype Agent Skill
> Install and update Genotype guidance for AI coding agents.
The Genotype skill gives coding agents a brief introduction to `.type` schemas, `genotype.toml`, and the `gt` CLI, with linked references they can read as needed.
## Installing
[Section titled “Installing”](#installing)
### Installing via CLI
[Section titled “Installing via CLI”](#installing-via-cli)
From your project directory, run:
```sh
gt skill install
```
See [`gt skill` in the CLI Reference](/docs/toolchain/cli#gt-skill) for more info about the `skill` subcommand.
Tip
[`gt init`](/docs/toolchain/cli/#gt-init) also offers skill installation.
#### Updating via CLI
[Section titled “Updating via CLI”](#updating-via-cli)
Run `gt skill update` to update the skill to the bundled version:
```sh
gt skill update
```
### Install with Skills CLI
[Section titled “Install with Skills CLI”](#install-with-skills-cli)
You can also install from the GitHub repository:
```sh
npx skills@latest add kossnocorp/genotype
```
The repository exposes a `genotype` skill with the same references as the CLI bundle. The Skills CLI handles agent selection and installation scope.
## Discovery
[Section titled “Discovery”](#discovery)
Tools can discover the published skill through the [Agent Skills discovery index](/.well-known/agent-skills/index.json). The index follows the [Agent Skills Discovery RFC](https://github.com/cloudflare/agent-skills-discovery-rfc) and links to a ZIP archive containing `SKILL.md` and its references.
The website serves the skill from the latest stable [GitHub release](https://github.com/kossnocorp/genotype/releases).
## `llms.txt`
[Section titled “llms.txt”](#llmstxt)
For general LLMs documentation access, use [llms.txt](/llms.txt) or [llms-full.txt](/llms-full.txt).
# Genotype VS Code Extension
> Genotype's VS Code extension.
The Genotype extension adds syntax highlighting for `.type` files, bracket matching and auto-closing, indentation, comment commands, and region folding.
Install it from:
* [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=nocorp.genotype)
* [Open VSX](https://open-vsx.org/extension/nocorp/genotype)