Rheo

Migrating projects

The migrate command upgrades an existing Rheo project to the current version. It reads the version field from rheo.toml, determines what migrations apply for the gap between that version and the current CLI, and reports or applies them.

Usage

rheo migrate path/to/project          # dry run — reports changes, writes nothing
rheo migrate path/to/project --apply  # applies changes and bumps rheo.toml version

Always run the dry run first to review what will be rewritten, then pass --apply to write the changes.

migrate is best-effort: it applies the mechanical rewrites it knows about, but it does not guarantee that your project will build or behave correctly on the new version. After migrating, rebuild and check the output yourself, and consult the changelog for breaking changes that require manual attention.

What migrate rewrites

migrate groups its rewrites by the project version it’s migrating from:

From versionWhat migrate rewrites
< 0.4.0
  • Link syntax: cross-file links written as file paths are rewritten to the current handle form:

    // before
    #link("./another-section.typ")[Another section]
    // after
    #link(<another-section>)[Another section]
< 0.5.0
  • Output format: direct rheo-target references are rewritten onto rheo-context.target:

    // before
    #if "rheo-context" in sys.inputs and "target" in sys.inputs.rheo-context { sys.inputs.rheo-context.target }
    // after
    #if "rheo-context" in sys.inputs and "target" in sys.inputs.rheo-context { sys.inputs.rheo-context.target }

    It also rewrites the old target() helper to Typst’s target(). Files already using target() need no change.

  • Spine config: a [spine] vertebrae inclusion-filter glob list is converted to an equivalent [spine] exclude, so files the old list never named don’t silently start being published under the directory-scan default.
< 0.5.1
  • rheo-context binding: the injected per-vertebra binding changed from a bare dictionary to a zero-arg function rheo-context(). So existing rheo-context.field code keeps working, migrate prepends a one-line compatibility shim to each file that reads the binding:

    #let rheo-context = rheo-context()

    The shim calls the injected function once and rebinds the name to its dictionary. migrate does not rewrite individual rheo-context.field references — the shim leaves them working untouched.

any outdated versionBumps the version field in rheo.toml to match the current CLI version (--apply only).

What you’ll still fix by hand