Add a simple individualization

Build Your First Origin Repository

Add a simple individualization

Make the example assignment variable by connecting one placeholder to a minimal individualization.json.

So far, your template contains a placeholder:

$Vehicle$

Now you will use the divekit dev scan to inspect that placeholder and then let --write-individualization scaffold the matching individualization.json.

Run divekit dev first

Before anything gets written, look at what the scanner finds:

divekit dev

This is a read-only scan: it inspects the project as it currently exists and lists every token that is still unresolved — without touching any file.

Before you have any matching individualization yet, the output looks like this:

$ divekit dev
Scan source: origin project
Scanned 2 files, unresolved tokens: 4, invalid template tokens: 0, possible variable residues: 0, broken template fragments: 0, suggestions: 0

  UNRESOLVED TOKENS

$Vehicle$
  README.md:
    3: This assignment contains one placeholder: `$Vehicle$`.
  src/$Vehicle$.java:
    filepath contains token
    1: public class $Vehicle$ {
    3: return "$Vehicle$";

Read the list carefully before you continue: the scan reports everything that looks like a placeholder — including text that only happens to look like one. If the list contains a token you never intended as a placeholder (a false positive), fix the source files first.

That check matters even more in larger projects:

  • one placeholder can easily be missed
  • one file may use a token you forgot to define
  • one stray $...$ in some text can show up even though it should not vary at all

For this beginner example, the check is quick: the only unresolved token is $Vehicle$, and that is exactly the one you want.

Scaffold the file with --write-individualization

Once the list contains only tokens you actually want to individualize, let Divekit write the scaffold:

divekit dev --write-individualization

This runs the same scan and additionally creates or extends .divekit/individualization.json with one entry per unresolved token:

$ divekit dev --write-individualization
Scan source: origin project
Scanned 2 files, unresolved tokens: 4, invalid template tokens: 0, possible variable residues: 0, broken template fragments: 0, suggestions: 0

  UNRESOLVED TOKENS

$Vehicle$
  ...

Updated individualization scaffold at /home/your-name/vehicle-workshop/.divekit/individualization.json (1 new object entries)

You could also write individualization.json by hand — the flag just saves you that step, which is why this course uses it. It is also why the read-only check comes first: with the flag, every unresolved token ends up in the file, false positives included.

Where individualization.json lives

For this course, the file lives at project level:

.divekit/individualization.json

Review the generated scaffold

The scaffold registers the missing object, but it does not invent options for you.
Right after the scan, .divekit/individualization.json looks like this:

{
  "version": "2.0",
  "variations": {
    "objects": [
      {
        "id": "Vehicle",
        "kinds": []
      }
    ]
  }
}

Add the possible kinds

Now fill in the options that Divekit may choose from:

{
  "version": "2.0",
  "variations": {
    "objects": [
      {
        "id": "Vehicle",
        "kinds": [
          {
            "id": "Car"
          },
          {
            "id": "Bike"
          },
          {
            "id": "Plane"
          }
        ]
      }
    ]
  }
}

Read the file

The important part is this mapping:

  • the variation object is identified by Vehicle
  • Divekit may choose one of the listed kinds
  • the concrete result is only known later during distribution

That means:

  • one repository may get Car
  • another may get Bike
  • another may get Plane

Connect placeholder and variation

Your source file contains:

public class $Vehicle$ {
    public String kind() {
        return "$Vehicle$";
    }
}

Your individualization file defines how Vehicle may be replaced.

The core beginner pattern is:

  • placeholder in template
  • matching object ID in individualization.json
  • concrete selection recorded later in individuals.json

What happens later

After a real distribution, Divekit will generate individuals.json.

That file records which concrete choice was actually used for each UUID.

So the distinction is:

  • individualization.json = possible options
  • individuals.json = actual selected options

Re-run the scan after you refine the file

After you check or refine the generated file, run the read-only scan again:

divekit dev

Now the scan should no longer complain about Vehicle as unresolved.

This is the practical beginner pattern:

  • run divekit dev and check the unresolved tokens for false positives
  • scaffold them with divekit dev --write-individualization
  • add or refine the kinds in individualization.json
  • re-run divekit dev until no unresolved tokens remain

A clean result after you added the kinds looks like this:

$ divekit dev
Scan source: origin project
Scanned 2 files, unresolved tokens: 0, invalid template tokens: 0, possible variable residues: 0, broken template fragments: 0, suggestions: 0

What to compare

Re-open these two things side by side:

  1. src/$Vehicle$.java
  2. .divekit/individualization.json

Ask yourself:

  • does the placeholder use Vehicle consistently?
  • does individualization.json define exactly that same ID?
  • do you have three options available?

If the names do not match exactly, individualization will not work.

Common failures

What to try

The flag writes every unresolved token into the scaffold — false positives included. Run the read-only divekit dev first and confirm that the list only contains tokens you actually want to individualize.

Skipping the scan entirely and writing individualization.json blindly is the same mistake in reverse: in larger projects it is a common source of omissions.

What to try

If the file contains $Vehicle$, then the variation data in individualization.json must define Vehicle, not vehicle and not VEHICLE.

Case and spelling matter.

What to try
individuals.json is generated during distribution.
Do not create it manually.
What to try

First make this tiny setup work:

  • one placeholder
  • one individualization file
  • one first distribution

Check

Run the scan, scaffold the file, review .divekit/individualization.json, and then answer:

Suggested answer
It showed the unresolved token $Vehicle$, including every file and line where it appears. The matching object ID in individualization.json is Vehicle.
Suggested answer
Three: Car, Bike, and Plane — the kinds you added to the scaffold. The concrete choice per repository is only made during distribution and recorded in individuals.json.
Suggested answer
After every change to the template or individualization.json. When everything is defined, it reports zero unresolved tokens.