Writing a template

How to structure a Terox template, write the manifest, and reference variables.

A Terox template is just a directory. It can live on your machine, in a GitHub repository, or both. The only file Terox treats specially is terox.json at the root, which declares the variables your template needs.

Anatomy

A minimal template:

my-template/
├── terox.json
└── {{.project_name}}/
    ├── README.md
    └── .gitignore

When scaffolded with project_name=portfolio, the output is:

output/
└── portfolio/
    ├── README.md
    └── .gitignore
  • The manifest terox.json is consumed by Terox and is not copied into the output.
  • Directory and file names are rendered as Go templates. The directory {{.project_name}}/ becomes portfolio/.
  • Text file contents are rendered the same way.
  • Binary files (detected by content sniffing) are copied byte-for-byte and are never run through the template engine.

Variable syntax

Variables are referenced using standard Go text/template syntax:

# {{.project_name}}

By {{.author}}

Licensed under {{.license}}.

The keys you reference (project_name, author, license) must match the name field of the corresponding entries in terox.json.

Conditional file paths

If a rendered file or directory name evaluates to an empty string, the file is skipped entirely. This lets you conditionally include files by gating them on a variable.

{{if eq .use_typescript "true"}}tsconfig.json{{end}}

When use_typescript is "true", the file is written as tsconfig.json. When it is anything else, the rendered name is empty and the file is skipped.

Files that contain {{ }} natively

Some file formats use {{ }} syntax for their own purposes — Vue interpolations, GitHub Actions ${{ ... }} expressions, Helm charts. If your template contains such files, escape the braces using Go template's own escape:

- run: echo {{"${{"}} github.sha {{"}}"}}

This renders to:

- run: echo ${{ github.sha }}

A future release will add a "copy without rendering" list so this dance becomes optional.

Templates without a manifest

You do not have to write a terox.json at all. Any directory or public GitHub repository can be scaffolded — Terox will copy the files as-is. This is useful for snapshotting a repository without its git history, or for turning an existing codebase into a "template" before you have time to add variables.