diff --git a/frontend/components/template/CheckboxInput.tsx b/frontend/components/template/CheckboxInput.tsx
index dec1138cecda4da53c49e73c8f40df364ae2a65a..364f8373fcdc1e91a835090946e6974413dd8d46 100644
--- a/frontend/components/template/CheckboxInput.tsx
+++ b/frontend/components/template/CheckboxInput.tsx
@@ -6,21 +6,30 @@ type CheckboxInput = {
     field: CutterField;
     flagged?: boolean;
     className?: string;
+
+    truthy?: string | boolean;
+    falsy?: string | boolean;
 };
-const CheckboxInput: FC<CheckboxInput> = ({ field, flagged = false, className }) => {
+const CheckboxInput: FC<CheckboxInput> = ({
+    field,
+    flagged = false,
+    className,
+    truthy = true,
+    falsy = false,
+}) => {
+    const classes = clsx('rounded input mt-0 mb-1 mr-2', flagged && 'border-warning', className);
+
     return (
         <div>
+            <input type="hidden" name={field.name} value={falsy.toString()} />
             <input
-                className={clsx(
-                    'rounded input mt-0 mb-1 mr-2',
-                    flagged && 'border-warning',
-                    className
-                )}
+                className={classes}
                 type="checkbox"
                 name={field.name}
                 id={field.name}
-                // TODO: type assertion due to api typing not being good enough
-                defaultChecked={field.default as boolean}
+                // TODO: type assertion due to generator issues
+                defaultChecked={field.default === truthy}
+                value={truthy.toString()}
             />
             <label htmlFor={field.name}>{field.prompt ?? field.name}</label>
         </div>
diff --git a/frontend/components/template/Form.tsx b/frontend/components/template/Form.tsx
index cd4e8da48b3ecf681f70321d9e89abae31e399ee..21168537ca06661f461dd6b6b0bf5c1e643e3bd6 100644
--- a/frontend/components/template/Form.tsx
+++ b/frontend/components/template/Form.tsx
@@ -1,8 +1,7 @@
-import { BLANK_FIELD, LegalField, SelectField, StringField } from 'lib/template';
+import { BLANK_FIELD } from 'lib/template';
 import React, { FC } from 'react';
 import SelectInput from './SelectInput';
 import TextInput from './TextInput';
-import Badge from 'components/Badge';
 import { CutterField } from 'lib/client';
 import CheckboxInput from 'components/template/CheckboxInput';
 import ErrorBox from 'components/ErrorBox';
@@ -14,8 +13,6 @@ const Formfield: FC<FormFieldProps> = ({ field, flagged }) => {
             {field.default === BLANK_FIELD && <div>{field.prompt ?? field.name}</div>}
             {field.default != BLANK_FIELD && (
                 <>
-                    <label htmlFor={field.name}>{field.prompt ?? field.name}</label>{' '}
-                    {flagged && <Badge type="warning">Missing</Badge>}
                     {field.type === 'text' ? (
                         <TextInput field={field} flagged={flagged} className="mt-1" />
                     ) : field.type === 'select' ? (
diff --git a/frontend/components/template/SelectInput.tsx b/frontend/components/template/SelectInput.tsx
index 4ea8eb50ee6919ec5182afe2408b9722dd9d2a0b..6c20da551d136ece558bcb1a7efb8d9a51a8062e 100644
--- a/frontend/components/template/SelectInput.tsx
+++ b/frontend/components/template/SelectInput.tsx
@@ -1,6 +1,9 @@
 import { FC } from 'react';
 import clsx from 'clsx';
 import { CutterField } from 'lib/client';
+import CheckboxInput from 'components/template/CheckboxInput';
+import { attemptDetermineYesNoOptions } from 'components/template/yesOrNo';
+import Badge from 'components/Badge';
 
 type SelectInputProps = {
     field: CutterField;
@@ -8,18 +11,35 @@ type SelectInputProps = {
     className?: string;
 };
 const SelectInput: FC<SelectInputProps> = ({ field, flagged = false, className }) => {
+    const yesNoOptions = field.options != null && attemptDetermineYesNoOptions(field.options);
+
+    if (yesNoOptions !== false) {
+        return (
+            <CheckboxInput
+                field={field}
+                className="mt-1"
+                truthy={yesNoOptions.truthy}
+                falsy={yesNoOptions.falsy}
+            />
+        );
+    }
+
     return (
-        <select
-            name={field.name}
-            id={field.name}
-            className={clsx('rounded', flagged && 'border-warning', className)}
-        >
-            {field.options?.map((option) => (
-                <option value={option.name} key={option.name}>
-                    {option.prompt ?? option.name}
-                </option>
-            ))}
-        </select>
+        <>
+            <label htmlFor={field.name}>{field.prompt ?? field.name}</label>{' '}
+            {flagged && <Badge type="warning">Missing</Badge>}
+            <select
+                name={field.name}
+                id={field.name}
+                className={clsx('rounded', flagged && 'border-warning', className)}
+            >
+                {field.options?.map((option) => (
+                    <option value={option.name} key={option.name}>
+                        {option.prompt ?? option.name}
+                    </option>
+                ))}
+            </select>
+        </>
     );
 };
 
diff --git a/frontend/components/template/TextInput.tsx b/frontend/components/template/TextInput.tsx
index 06f0901f2e766340d1dc00ad4e5d4fca03fb6f27..12f3f445639e0e9627f1c73316c4d5b6aed4f986 100644
--- a/frontend/components/template/TextInput.tsx
+++ b/frontend/components/template/TextInput.tsx
@@ -1,6 +1,7 @@
 import { FC } from 'react';
 import clsx from 'clsx';
 import { CutterField } from 'lib/client';
+import Badge from 'components/Badge';
 
 type TextInputProps = {
     field: CutterField;
@@ -9,14 +10,18 @@ type TextInputProps = {
 };
 const TextInput: FC<TextInputProps> = ({ field, flagged = false, className }) => {
     return (
-        <input
-            className={clsx('rounded input', flagged && 'border-warning', className)}
-            type="text"
-            name={field.name}
-            id={field.name}
-            // TODO: type assertion due to api typing not being good enough
-            placeholder={field.default as string}
-        />
+        <>
+            <label htmlFor={field.name}>{field.prompt ?? field.name}</label>{' '}
+            {flagged && <Badge type="warning">Missing</Badge>}
+            <input
+                className={clsx('rounded input', flagged && 'border-warning', className)}
+                type="text"
+                name={field.name}
+                id={field.name}
+                // TODO: type assertion due to api typing not being good enough
+                placeholder={field.default as string}
+            />
+        </>
     );
 };
 
diff --git a/frontend/components/template/yesOrNo.ts b/frontend/components/template/yesOrNo.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a25117ae423327b87a0a7f1ed5c9eecef186bf5f
--- /dev/null
+++ b/frontend/components/template/yesOrNo.ts
@@ -0,0 +1,42 @@
+// referencing defaults in https://cookiecutter.readthedocs.io/en/2.3.0/cookiecutter.html#cookiecutter.prompt.YesNoPrompt
+import { CutterOption } from 'lib/client';
+
+export const TRUTHY_DEFAULTS = ['1', 'true', 't', 'yes', 'y', 'on'];
+export const FALSY_DEFAULTS = ['0', 'false', 'f', 'no', 'n', 'off'];
+
+export const attemptDetermineYesNoOptions = (
+    options: CutterOption[]
+):
+    | {
+          truthy: string;
+          falsy: string;
+      }
+    | false => {
+    if (options.length !== 2) {
+        return false;
+    }
+
+    // do not use a checkbox if the select options have a label because context may ge tlost
+    if (options.some((o) => o.prompt != null)) {
+        return false;
+    }
+
+    // ensure alphabetical order in checks!
+    const [first, second] = options.map((o) => o.name).sort();
+
+    if (
+        (first === '0' && second === '1') ||
+        (first === 'false' && second === 'true') ||
+        (first === 'f' && second === 't') ||
+        (first === 'no' && second === 'yes') ||
+        (first === 'n' && second === 'y') ||
+        (first === 'off' && second === 'on')
+    ) {
+        return {
+            truthy: second,
+            falsy: first,
+        };
+    }
+
+    return false;
+};