Templates

Template params

Params are the questions a template asks the user. They are declared in spin.toml under [params].

Param types

[params]
project_name = { type = "text", prompt = "Project name", default = "myproject" }
description  = { type = "textarea", prompt = "Description" }
port         = { type = "number", prompt = "Port", default = 8080, min = 1024, max = 65535 }
license      = { type = "license", prompt = "License", default = "MIT" }
features     = { type = "multiselect", prompt = "Features", options = ["auth", "db", "cache"] }
private      = { type = "bool", prompt = "Private repo?", default = false }
output_dir   = { type = "path", prompt = "Output directory" }
api_key      = { type = "secret", prompt = "API key" }

License params

The license param type is special: it offers a curated list of SPDX license identifiers plus a "None" option, and when a license is selected spin generates a LICENSE file in the user's project at render time, with the copyright year and holder substituted automatically.

[params]
license = { type = "license", prompt = "License", default = "MIT" }
copyright_holder = { type = "text", prompt = "Copyright holder", default = "Acme Corp" }
  • license — options are auto-filled from the supported licenses set. You can restrict the choice by providing your own options; any value outside the set yields no LICENSE file.
  • copyright_holder — a plain text param that populates the copyright line in the generated license. It is optional; default and templated defaults work like any text param. When absent, the ownership placeholder is left as-is in the license text.

See License generation for full details.

Shorthand form

A param with only a default value can be written as a plain string:

[params]
project_name = "myproject"   # equivalent to { type = "text", default = "myproject" }

Using params in templates

Inside a .tmpl file, params are top-level fields:

# {{ .project_name | title }}

{{ .description }}

- License: {{ .license }}
- Port: {{ .port }}
- Features: {{ join .features ", " }}

Non-interactive usage

Users pass params as --param key=value:

spin new myapp --template my-template \
  --param project_name=myapp \
  --param port=8080 \
  --param features=auth,db

Multiselect values are comma-separated. Booleans accept true, false, 1, 0, yes, no, on, off.

Templated prompts and defaults

prompt and default accept Go templates, so they can reference other values with the same spin helpers used in .tmpl files and hooks (upper, snake_case, {{ .project_name }}, ...):

[params]
project_name = { type = "text", prompt = "Project name" }
module       = { type = "text", default = "github.com/me/{{ .project_name }}" }
db_name      = { type = "text", prompt = "Database name for {{ .project_name }}" }

Only values known before the form runs are available when a prompt or default is rendered: the built-ins name and project_name (injected from the project name you pass to spin new) and anything supplied via --param. A prompt or default that references another param's answer will not reflect what the user types into the form, because that answer does not exist yet when the form is built.

If a template string fails to parse or references an unknown value, spin leaves it as-is — it never aborts a scaffold over one bad string. Double check variable names: a typo like {{ .projet_name }} renders to an empty string rather than erroring.

Validation

  • number params enforce min and max.
  • select params reject values not in options (when options are provided). This applies both interactively and to --param values and templated defaults resolved outside the option list.