In GitHub, what does a YAML issue form give you that a Markdown issue template does not?
answer
- Both live under one .github directory
- One is a suggestion, one is enforced
- Typed widgets, not pasted headings
- validations: required blocks submission
- config.yml removes the blank-issue escape hatch
basics
~20 sA GitHub issue form renders real input widgets — required text boxes, dropdowns and checkboxes — so the reporter cannot submit an empty or half-filled report. A Markdown template only pre-fills editable text that anyone can delete.
solid answer
~40 sBoth live in `.github/ISSUE_TEMPLATE/` on the **default branch**. A Markdown template (`bug_report.md`) has YAML front matter for `name`, `about`, `title`, `labels`, `assignees`, and a body that is simply pasted into the editor — the reporter can wipe every heading before submitting. An **issue form** (`bug_report.yml`) instead declares a `body:` list of typed elements — `markdown`, `input`, `textarea`, `dropdown`, `checkboxes` — each with `validations: required: true` if you want it enforced. GitHub renders a real web form, blocks submission when a required field is empty, and then serialises the answers into the issue body as headings. That gives you structured, parseable reports: a version `input` is always present, so an automation can read it. Add `.github/ISSUE_TEMPLATE/config.yml` with `blank_issues_enabled: false` and `contact_links` to force the choice.
code
yaml · 37 linesname: Bug report
description: Something behaves differently than documented
title: "[Bug]: "
labels: ["bug", "needs-triage"]
body:
- type: markdown
attributes:
value: Please search existing issues before opening a new one.
- type: input
id: version
attributes:
label: Affected version
placeholder: 2.4.1
validations:
required: true
- type: dropdown
id: severity
attributes:
label: Severity
options:
- Blocks release
- Workaround exists
- Cosmetic
validations:
required: true
- type: textarea
id: logs
attributes:
label: Relevant log output
render: shell
- type: checkboxes
id: checks
attributes:
label: Pre-flight
options:
- label: I searched existing issues
required: truego deeper
Know that GitHub issue templates live in .github/ISSUE_TEMPLATE/ and that the YAML form variant renders real inputs a reporter must fill in, while the Markdown variant is only pre-filled text.
Explain the element types — input, textarea, dropdown, checkboxes — what validations: required does, and how answers are serialised back into a Markdown issue body.
Show judgment about friction: which fields genuinely block triage, why over-requiring produces 'n/a' noise, and why enforcement you depend on belongs in automation as well as in the form.
Frame the tracker as a funnel: templates plus config.yml contact links decide what becomes an issue at all, and that routing decision costs more engineering time than any individual field.
## The two formats GitHub supports two mechanisms for shaping new issues, both stored in `.github/ISSUE_TEMPLATE/` and both read from the repository's **default branch** — a template on a feature branch does nothing until it merges. **Markdown templates** are `.md` files with YAML front matter: - `name` — the label shown on the template chooser - `about` — the one-line description under it - `title` — a pre-filled issue title - `labels`, `assignees` — applied automatically Everything below the front matter is dumped into the issue editor as ordinary Markdown. It is a suggestion. The reporter can select all and delete it, and many do. **Issue forms** are `.yml` files describing a real form. Top-level keys mirror the Markdown ones (`name`, `description`, `title`, `labels`, `assignees`, `projects`), plus `body:` — an ordered list of elements. Each element has a `type` and an `attributes` block, and most accept `validations`. ## The element types - `markdown` — static prose shown to the reporter; it is *not* copied into the resulting issue. Use it for "please search existing issues first". - `input` — a single-line box. Ideal for a version, a URL, an environment name. - `textarea` — a multi-line box. Its `render:` attribute (for example `render: shell`) wraps the answer in a fenced code block automatically, which is how you get readable stack traces without asking people to format them. - `dropdown` — a fixed `options` list; `multiple: true` allows several. This is where you kill free-text chaos in fields like severity or affected component. - `checkboxes` — a list of `options`, each of which can itself be `required: true`. The standard use is a pre-flight acknowledgement ("I searched existing issues"). Each element normally carries an `id`, and `validations: required: true` makes it mandatory. Required fields are the whole point: GitHub refuses to submit the form until they are filled. ## What lands in the issue After submission GitHub converts the answers into a Markdown body: each field's `label` becomes a heading and the answer becomes the text beneath it. So the *stored* issue is still plain Markdown — but it is now predictably shaped, because every issue of that type has the same headings in the same order. That predictability is what makes downstream automation viable: a workflow or a bot can find the version heading with confidence, which is impossible when half the reports are free prose. ## The chooser and config.yml `.github/ISSUE_TEMPLATE/config.yml` controls the template picker itself: - `blank_issues_enabled: false` removes the "open a blank issue" escape hatch, so every issue goes through a form. - `contact_links:` lists external destinations — each with `name`, `url`, and `about` — for traffic that should not become an issue at all: a discussion forum, a security disclosure page, a support desk. That combination is what turns an issue tracker from an inbox into a funnel. ## Tradeoffs Forms are stricter, which is the benefit and the cost. Too many required fields and people abandon the form or type "n/a" everywhere, which is worse than free text because it looks structured and is not. Keep the required set to the fields you would otherwise have to ask for in a comment — version, reproduction steps, expected vs actual — and leave the rest optional. Markdown templates still have a place: for internal repos where the reporter is a colleague who genuinely will fill in the headings, the lower friction is worth it. Forms earn their keep on public repos and on any queue where the reporter and the triager are different people. ## Scope of application Both mechanisms only shape issues opened through the web UI's *New issue* flow. An issue created through the API or by a bot bypasses templates entirely, so validation you truly depend on belongs in an automation that reacts to the opened issue, not only in the form.
- You added an issue form on a feature branch and the picker does not show it — why?Issue templates and forms are read from the repository's default branch only. Until the file merges, the picker is unchanged. The same rule catches people editing a template in a fork: the upstream repository serves its own default branch, not yours.
- Does an issue form stop a bot from opening a malformed issue?No. Templates and forms shape only the web *New issue* flow. Anything created through the API or by an integration bypasses them entirely. If the structure is load-bearing, validate it in an automation that reacts to the opened issue and comments or labels when a required section is missing.
- How do you steer support questions away from the issue tracker entirely?Set `blank_issues_enabled: false` in `.github/ISSUE_TEMPLATE/config.yml` and add `contact_links` entries pointing at a discussion board or support page. The picker then offers those destinations alongside your forms, and there is no blank-issue path around them.
saying these in an interview costs you the question
- Says Markdown templates can make a field required
- Puts the template on a feature branch and expects it live
- Believes forms store data as structured fields, not Markdown
- Thinks templates also constrain issues created via the API
- Adds twenty required fields and calls it triage hygiene