GitIssue Templates

Issue Templates

An issue template is a structured form that appears when someone clicks New issue. Instead of staring at a blank markdown box, they get a guided experience: fields to fill in, checkboxes to tick, a labelled and assigned issue at the end. Good templates dramatically reduce triage cost and the “could you provide more details?” reply you write five times a week.

Two flavours of templates

Type

Format

When to use

Markdown templates

A .md file with prompts in comments

Simple cases, max flexibility

Issue Forms

A YAML file describing inputs

Modern, structured, easier to triage at scale

Where templates live

Folder structure

Text
.github/
└── ISSUE_TEMPLATE/
    ├── bug_report.md          ← markdown style
    ├── feature_request.yml    ← issue forms style
    ├── question.md
    └── config.yml             ← optional: customise the chooser
The chooser page

When more than one template exists, clicking New issue shows a menu of all available templates plus a link to “Open a blank issue” (unless you’ve disabled it).

Example: Markdown template

.github/ISSUE_TEMPLATE/bug_report.md

MD
---
name: Bug report
about: Something is broken in the app
title: "[Bug] "
labels: ["bug", "needs-triage"]
assignees:
  - alice
---

### What happened

### What you expected

### Steps to reproduce
1.
2.
3.

### Environment
- App version:
- Browser:
- OS:

### Screenshots
  • YAML front-matter at the top configures the template metadata.

  • title: pre-fills the title; the user appends to it.

  • labels: and assignees: apply automatically when the issue is opened.

  • Comments and prompts in the body guide the reporter.

Example: Issue Form (YAML)

.github/ISSUE_TEMPLATE/bug_report.yml

YAML
name: Bug report
description: File a bug report
title: "[Bug] "
labels: ["bug", "needs-triage"]
assignees:
  - alice
body:
  - type: markdown
    attributes:
      value: |
        Thanks for reporting a bug! Please fill out the fields below.

  - type: input
    id: version
    attributes:
      label: App version
      placeholder: e.g. 2.3.1
    validations:
      required: true

  - type: textarea
    id: what-happened
    attributes:
      label: What happened?
      description: Be as specific as you can.
    validations:
      required: true

  - type: textarea
    id: steps
    attributes:
      label: Steps to reproduce
      value: |
        1.
        2.
        3.
    validations:
      required: true

  - type: dropdown
    id: browser
    attributes:
      label: Browser
      options:
        - Chrome
        - Firefox
        - Safari
        - Edge
        - Other
    validations:
      required: true

  - type: checkboxes
    id: terms
    attributes:
      label: Code of Conduct
      options:
        - label: I agree to follow this project’s Code of Conduct
          required: true
Available input types
  • markdown — static text, instructions, not submitted.

  • input — single-line text field.

  • textarea — multi-line text, optionally rendered as a code block.

  • dropdown — pick one (or multiple with multiple: true).

  • checkboxes — list of boxes the reporter ticks.

config.yml — control the chooser

.github/ISSUE_TEMPLATE/config.yml

YAML
blank_issues_enabled: false      # force people to pick a template
contact_links:
  - name: Community Discussions
    url: https://github.com/acme-co/widget/discussions
    about: Ask questions, share ideas, get help from the community
  - name: Security vulnerabilities
    url: https://acme-co.com/security
    about: Report security issues privately, NOT on GitHub Issues
  • blank_issues_enabled: false — removes the “open a blank issue” escape hatch.

  • contact_links — route specific kinds of feedback elsewhere (Discussions, security disclosure, support email).

Required fields, default labels, default assignees
  • Add validations: required: true on a form input to block submission until it’s filled.

  • Add labels: to the template metadata for auto-labelling.

  • Add assignees: to auto-route to specific people or teams.

  • GitHub strips invalid usernames silently — sanity-check after committing.

Markdown vs Issue Forms

Feature

Markdown

Issue Forms

Required fields

No (can’t enforce)

Yes (per-field)

Structured data

No (free text)

Yes (each field separate)

Dropdowns / checkboxes

Only as markdown checkboxes

Native widgets

Easier triage

Harder — parse free text

Easier — predictable structure

Older repos

Universal

Modern (since 2021)

Tip
Use Issue Forms for new repos. The required-field validation alone is worth the migration — reporters can’t accidentally skip the “what version are you on?” question.
Real-world workflow

Add a bug-report form to a repo

Bash
mkdir -p .github/ISSUE_TEMPLATE
$EDITOR .github/ISSUE_TEMPLATE/bug_report.yml
$EDITOR .github/ISSUE_TEMPLATE/config.yml
git add .github/ISSUE_TEMPLATE
git commit -m "Add bug report issue form"
git push

# Open https://github.com/acme-co/widget/issues/new/choose to verify
Common pitfalls
  • YAML indentation errors — GitHub silently falls back to the blank issue page. Validate with a YAML linter.

  • Default assignee doesn’t exist — typo in assignees: means nobody is assigned.

  • Templates only apply to this repo — they don’t inherit from a profile or org repo.

  • Too many fields — reporters give up. Aim for fewer than 6 required fields.

Templates pay for themselves in week one
The instant a reporter is forced to include the app version, the OS, and the steps to reproduce, your triage cost drops by half. The first bug you reproduce immediately without a back-and-forth has already paid for the template.
Tip
Add a `needs-triage` label to every template by default. Your triager runs `is:issue label:needs-triage`, processes the queue, and removes the label as they go. Cheap, explicit, works.