Skip to main content
The template.* file configures metadata and variables for a template, used by the generator, and must exist at the root of a named template folder.

File Location

  • Path: template.yml or template.json (in template root)
  • Format: YAML or JSON
  • Required: Yes (for templates)

Overview

Templates are used with moon generate to scaffold new code, projects, or files. Each template folder must contain a template.* configuration file.

Configuration Options

id

Overrides the name (identifier) of the template, instead of inferring the name from the template folder.
template.yml
id: 'npm-package'
Template names must be unique across the workspace and across all template locations.

title (required)

A human readable title displayed during the moon generate process.
template.yml
title: 'npm package'

description (required)

A description of why the template exists, what its purpose is, and any other relevant information.
template.yml
description: |
  Scaffolds the initial structure for an npm package,
  including source and test folders, a package.json, and more.

destination

An optional file path in which this template should be generated into. If prefixed with /, it will be relative from the workspace root, otherwise relative from the current working directory.
template.yml
destination: 'packages/[name]'
This setting supports template variables through [varName] syntax.

extends

One or many other templates that this template should extend. Will deeply inherit all template files and variables.
template.yml
extends: ['base', 'configs']

variables

A mapping of variables that will be interpolated into all template files and file system paths when rendering with Tera.
template.yml
variables:
  name:
    type: 'string'
    default: ''
    required: true
    prompt: 'Package name?'

Variable Types

Each variable requires a type field and supports additional configuration.

String

template.yml
variables:
  name:
    type: 'string'
    prompt: 'Name?'
    required: true
    default: ''

Boolean

template.yml
variables:
  private:
    type: 'boolean'
    prompt: 'Private?'
    default: false

Number

template.yml
variables:
  age:
    type: 'number'
    prompt: 'Age?'
    default: 0
    required: true

Array

template.yml
variables:
  type:
    type: 'array'
    prompt: 'Type?'
    default: ['app', 'lib']
For arrays and objects, a valid JSON string must be provided when prompted.

Object

template.yml
variables:
  metadata:
    type: 'object'
    prompt: 'Metadata?'
    default:
      type: 'lib'
      dev: true

Enum

An explicit list of string values that a user can choose from.
template.yml
variables:
  color:
    type: 'enum'
    values: ['red', 'green', 'blue', 'purple']
    default: 'purple'
    prompt: 'Favorite color?'

Multiple Selection

template.yml
variables:
  colors:
    type: 'enum'
    values: ['red', 'green', 'blue', 'purple']
    default: ['red', 'purple']
    multiple: true
    prompt: 'Favorite colors?'

With Labels

template.yml
variables:
  color:
    type: 'enum'
    values:
      - value: 'red'
        label: 'Red 🔴'
      - value: 'green'
        label: 'Green 🟢'
      - value: 'blue'
        label: 'Blue 🔵'
    default: 'red'
    prompt: 'Favorite color?'

Variable Options

The default value of the variable. Used when --defaults is passed to moon generate or when prompt is not defined.
variables:
  name:
    type: 'string'
    default: 'my-package'
When defined, prompts the user with a message to input a custom value.
variables:
  name:
    type: 'string'
    prompt: 'What is the package name?'
Marks the variable as required during prompting. Will error for empty values.
variables:
  name:
    type: 'string'
    required: true
Marks a variable as internal only, avoiding the value being overwritten by command line arguments.
variables:
  internal_config:
    type: 'string'
    internal: true
The order in which the variable will be prompted to the user. By default, variables are prompted in the order they are defined.
variables:
  name:
    type: 'string'
    order: 1
  description:
    type: 'string'
    order: 2

Frontmatter

The following settings can be defined as frontmatter at the top of a template file.

force

When enabled, will always overwrite a file of the same name at the destination path.
---
force: true
---

Some template content!

to

Defines a custom file path, relative from the destination root, in which to create the file.
{% set component_name = name | pascal_case %}

---
to: components/{{ component_name }}.tsx
---

export function {{ component_name }}() {
  return <div />;
}

skip

When enabled, the template file will be skipped while writing to the destination path.
---
skip: {{ name == "someCondition" }}
---

Some template content!

Examples

React Component Template

template.yml
title: 'React Component'
description: 'Scaffolds a new React component with tests and styles'
destination: 'src/components/[name]'

variables:
  name:
    type: 'string'
    required: true
    prompt: 'Component name?'
  
  type:
    type: 'enum'
    values: ['functional', 'class']
    default: 'functional'
    prompt: 'Component type?'
  
  withTests:
    type: 'boolean'
    default: true
    prompt: 'Include tests?'
  
  withStyles:
    type: 'boolean'
    default: true
    prompt: 'Include styles?'

npm Package Template

template.yml
title: 'npm Package'
description: 'Scaffolds a publishable npm package'
destination: 'packages/[name]'

variables:
  name:
    type: 'string'
    required: true
    prompt: 'Package name?'
  
  description:
    type: 'string'
    required: true
    prompt: 'Package description?'
  
  scope:
    type: 'string'
    default: '@myorg'
    prompt: 'npm scope?'
  
  private:
    type: 'boolean'
    default: false
    prompt: 'Is this a private package?'
  
  license:
    type: 'enum'
    values: ['MIT', 'Apache-2.0', 'BSD-3-Clause', 'ISC']
    default: 'MIT'
    prompt: 'License?'

Next.js App Template

template.yml
title: 'Next.js Application'
description: 'Scaffolds a new Next.js application with TypeScript'
destination: 'apps/[name]'
extends: ['base-app']

variables:
  name:
    type: 'string'
    required: true
    prompt: 'App name?'
  
  features:
    type: 'enum'
    multiple: true
    values:
      - value: 'auth'
        label: 'Authentication'
      - value: 'db'
        label: 'Database (Prisma)'
      - value: 'api'
        label: 'API Routes'
      - value: 'testing'
        label: 'Testing (Jest + RTL)'
    default: ['auth', 'api']
    prompt: 'Select features to include:'
  
  styling:
    type: 'enum'
    values: ['tailwind', 'css-modules', 'styled-components', 'emotion']
    default: 'tailwind'
    prompt: 'Styling approach?'

Library Template with Metadata

template.yml
title: 'TypeScript Library'
description: 'Scaffolds a reusable TypeScript library'
destination: 'packages/[name]'

variables:
  name:
    type: 'string'
    required: true
    prompt: 'Library name?'
    order: 1
  
  description:
    type: 'string'
    required: true
    prompt: 'Description?'
    order: 2
  
  author:
    type: 'string'
    default: 'Engineering Team'
    prompt: 'Author?'
    order: 3
  
  metadata:
    type: 'object'
    default:
      publishable: true
      monorepo: true
    internal: true

Complete Example

template.yml
id: 'fullstack-service'
title: 'Full-Stack Service'
description: |
  Scaffolds a complete full-stack service with frontend,
  backend, shared types, and configuration.

destination: 'services/[name]'

extends: ['base-service', 'docker-config']

variables:
  name:
    type: 'string'
    required: true
    prompt: 'Service name?'
    order: 1
  
  description:
    type: 'string'
    required: true
    prompt: 'Service description?'
    order: 2
  
  stack:
    type: 'enum'
    values:
      - value: 'next-node'
        label: 'Next.js + Node.js'
      - value: 'react-fastify'
        label: 'React + Fastify'
      - value: 'vue-express'
        label: 'Vue + Express'
    default: 'next-node'
    prompt: 'Technology stack?'
    order: 3
  
  database:
    type: 'enum'
    values: ['postgresql', 'mysql', 'mongodb', 'none']
    default: 'postgresql'
    prompt: 'Database?'
    order: 4
  
  features:
    type: 'enum'
    multiple: true
    values:
      - 'authentication'
      - 'authorization'
      - 'api-docs'
      - 'monitoring'
      - 'testing'
    default: ['authentication', 'testing']
    prompt: 'Select features:'
    order: 5
  
  port:
    type: 'number'
    default: 3000
    prompt: 'Port number?'
    order: 6
  
  enableDocker:
    type: 'boolean'
    default: true
    prompt: 'Enable Docker support?'
    order: 7

Build docs developers (and LLMs) love