variation.json
variation.json defines which content options Divekit may choose from during individualization.
This file is optional, but required if you want per-UUID variation selection.
Format
{
"objects": [
{
"ids": "Vehicle",
"objectVariations": [
{
"id": "car",
"type": "class",
"name": "Car",
"variables": {
"Vehicle": "Car"
}
},
{
"id": "truck",
"type": "class",
"name": "Truck",
"variables": {
"Vehicle": "Truck"
}
}
]
}
],
"relations": [
{
"id": "ownership",
"type": "association",
"source": "Vehicle",
"target": "Owner",
"options": ["one-to-one", "one-to-many"],
"variables": {}
}
],
"logic": [
{
"id": "algorithm",
"type": "implementation",
"location": "src/logic",
"options": ["simple", "complex"],
"variables": {}
}
]
}
Top-Level Sections
| Key | Type | Notes |
|---|---|---|
objects | array | Object-level choices keyed by ids. |
relations | array | Relation-level choices keyed by id. |
logic | array | Logic-level choices keyed by id. |
Variation Fields and Token Overrides
Each object variation can contain more than just id, type, name, and variables.
Additional fields become tokens by combining the object key with the field name.
Example:
{
"objects": [
{
"ids": "Plz",
"objectVariations": [
{
"id": "ZipCode",
"": "Zip code",
"Class": "ZipCode",
"Parameter": "zipCode",
"DocLabel": "ZIP code"
}
]
}
]
}
This produces tokens such as:
$Plz$/$plz$from the empty-string field""$PlzClass$/$plzClass$fromClass$PlzParameter$/$plzParameter$fromParameter$PlzDocLabel$/$plzDocLabel$fromDocLabel
Notes:
"": "..."is the explicit override for the base display token.- Named fields such as
ClassorParameteroverride the corresponding generated transformer output. - Lowercase object aliases such as
$plzClass$are generated automatically. - If you do not provide an explicit override, Divekit falls back to the built-in transformer behavior.
This is the preferred way to control exact wording for display labels, acronyms, or project-specific names.
If a variation id is an external identifier, prefer an explicit empty-string field.
The base token without a suffix, for example $RestSupplier$, is display-oriented when no "" value is provided. UUID-like IDs are preserved, but other opaque IDs such as asd-012, YouTube-style IDs, slugs, or external keys may be changed by the display fallback.
Use "": "..." to keep such values exact:
{
"id": "asd-012",
"": "asd-012",
"name": "Example supplier"
}
Built-In Token Suffixes
When an object variation is selected, Divekit generates tokens from the object key and the selected variation ID. The token without a suffix uses the display transformer.
Example selection:
{
"objects": {
"Basket": "ShoppingBasket"
}
}
This produces a base token such as $Basket$ and suffix tokens such as $BasketClass$.
Divekit also creates lowercase object aliases such as $basket$ and $basketClass$.
The following built-in suffixes are available by default:
| Suffix | Aliases | Example for ShoppingBasket | Notes |
|---|---|---|---|
| none | - | Shopping basket | Base display token, for example $Basket$. |
s | S | Shopping baskets | Plural display token. |
Class | CLASS | ShoppingBasket | Class/type-style identifier. |
Parameter | PARAMETER | shoppingBasket | Parameter or variable-style identifier. |
Package | package, PACKAGE | shoppingbasket | Lowercase package-style identifier. |
Plural | PLURAL | ShoppingBaskets | Identifier pluralized with s. |
Lower | LowerCase, LOWER, LOWER_CASE | shoppingbasket | Full lowercase sanitized identifier. |
Upper | UpperCase, UPPER, UPPER_CASE | SHOPPINGBASKET | Full uppercase sanitized identifier. |
FirstLower | FirstLowerCase, FIRST_LOWER | shoppingBasket | Only lowercases the first character of the sanitized identifier. |
FirstUpper | FirstUpperCase, Capitalize, FIRST_UPPER | ShoppingBasket | Only uppercases the first character of the sanitized identifier. |
Pascal | PascalCase, PASCAL, PASCAL_CASE | ShoppingBasket | PascalCase identifier. |
Camel | CamelCase, CAMEL, CAMEL_CASE | shoppingBasket | camelCase identifier. |
Kebab | KebabCase, KEBAB, KEBAB_CASE | shopping-basket | kebab-case identifier. |
Snake | SnakeCase, SNAKE, SNAKE_CASE | shopping_basket | snake_case identifier. |
Repository | REPOSITORY | ShoppingBasketRepository | Repository class-style identifier. |
Dto | DTO | ShoppingBasketDto | DTO class-style identifier. |
Rest | REST | shoppingBaskets | REST collection path segment. |
RestId | REST_ID | {shoppingBasket-id} | REST path parameter. |
IndefArticle | UndefArticle, INDEF_ARTICLE | a | English indefinite article for the selected variation ID. |
If a variation entry defines a field with the same suffix name, that explicit value wins over the generated value.
For example, "Class": "ShoppingCart" makes $BasketClass$ resolve to ShoppingCart.
Resolution Order
Divekit accepts variation.json as a legacy source within the unified variation
lookup order:
- distribution
individualization.json - distribution
variation.json - project
.divekit/individualization.json - project
.divekit/variation.json - user
~/.divekit/individualization.json - built-in defaults with no variations
An explicitly empty legacy variation file disables variations at its level.
The old ~/.divekit/templates/variation.json fallback is no longer read. Run
divekit inject --scope variation to create an example file explicitly.
Output
Concrete selections are persisted to individuals.json, and selected variation metadata may also be persisted into remotes.json.
Related pages: