gradio Checkbox — the boolean switch every demo needs

One boolean, wired through .change(), gives your demo a feature switch — no JS, no state mgmt.

The humble checkbox is Gradio's smallest input — and the cheapest way to make a demo feel configurable instead of frozen.

What it does

gr.Checkbox() renders a single HTML checkbox with its label to the right. Its value is a Python bool: True when checked, False when not. As an input it hands that bool straight to your function — no parsing, no coercion. As an output it displays whatever bool you return. Preprocess returns the bool verbatim; postprocess passes bools through untouched. It also carries the standard component toolkit: label, info (a smaller markdown line under the label), scale, visible, interactive, elem_id, and the event listeners .change, .input and .select.

Why it matters

Every ML demo eventually needs a toggle: cache results, redact names, verbose logging, agree to terms before running. A Checkbox plus one .change() listener is the shortest path from 'static demo' to 'demo that responds to the user'. Because the value is a real bool, your function reads like the logic it implements — if agree: — instead of comparing strings like "on" or "yes". And because it's a component, it participates in everything else: put it in a Row, gate other components' visibility, carry it in gr.State.

Examples

import gradio as gr

with gr.Blocks() as demo:
    agree = gr.Checkbox(label="I agree to the terms", info="Required before running")
    status = gr.Textbox(label="status")

    agree.change(lambda c: "ready" if c else "waiting for consent...",
                 inputs=agree, outputs=status)

demo.launch(prevent_thread_lock=True)
* Running on local URL:  http://127.0.0.1:7861
* To create a public link, set `share=True` in `launch()`.

Rendered UI: a checkbox labeled "I agree to the terms" with smaller gray helper text "Required before running", above a single-line Textbox labeled "status" showing "waiting for consent...". Checking the box flips the Textbox to "ready" without a page reload — the bool arrives in Python as True, the lambda returns "ready", Gradio pushes it back to the Textbox.

The canonical agree-gate. Run and verified with gradio 6.28.0: the demo built and launched, printing exactly the 'Running on local URL' line shown here.

import gradio as gr

with gr.Blocks() as demo:
    steps = gr.CheckboxGroup(
        choices=["retrieval", "summarize", "translate"],
        value=["retrieval"],
        label="Pipeline steps",
        show_select_all=True)
    picked = gr.Textbox(label="selected")

    steps.change(lambda xs: " -> ".join(xs) or "(none)",
                 inputs=steps, outputs=picked)

demo.launch(prevent_thread_lock=True)
* Running on local URL:  http://127.0.0.1:7862
* To create a public link, set `share=True` in `launch()`.

Rendered UI: three checkboxes "retrieval" (pre-checked), "summarize", "translate", with a select-all control next to the "Pipeline steps" label. The "selected" Textbox below shows "retrieval"; checking summarize turns it into "retrieval -> summarize"; unchecking everything shows "(none)".

CheckboxGroup is Checkbox's plural sibling: value is a list of the selected choice strings (or indices with type="index"). show_select_all=True adds a master toggle in the group header — verified present on gr.CheckboxGroup's signature in gradio 6.28.0.

import gradio as gr

with gr.Blocks() as demo:
    adv = gr.Checkbox(label="Show advanced options", value=False)
    temp = gr.Slider(0, 2, value=0.7, label="temperature", visible=False)

    adv.change(lambda v: gr.update(visible=v), inputs=adv, outputs=temp)

demo.launch(prevent_thread_lock=True)
* Running on local URL:  http://127.0.0.1:7863
* To create a public link, set `share=True` in `launch()`.

Rendered UI: a single checkbox "Show advanced options" and, hidden, a temperature slider. Tick the box and the slider appears in the same slot; untick and it's gone. Your function never touches the Slider's value — the Checkbox only flips its visibility.

The show/hide pattern: one Checkbox drives gr.update(visible=...) on another component. Verified launch on port 7863. Cheap progressive disclosure without custom JS.

import gradio as gr

CORPUS = {
    "docs": ["QMS manual rev 4", "audit checklist"],
    "tickets": ["printer offline x3", "VPN drops"],
    "wiki": ["on-call rota", "deploy runbook"],
}

def search(query, sources):
    hits = [h for s in sources for h in CORPUS.get(s, [])]
    return f"{len(hits)} hits: " + ", ".join(hits) if hits else "no hits"

with gr.Blocks() as demo:
    query = gr.Textbox(label="query")
    sources = gr.CheckboxGroup(choices=["docs", "tickets", "wiki"], value=["docs"], label="sources")
    btn = gr.Button("Search")
    results = gr.Textbox(label="results")
    btn.click(search, inputs=[query, sources], outputs=results)

demo.launch(prevent_thread_lock=True)
* Running on local URL:  http://127.0.0.1:7864
* To create a public link, set `share=True` in `launch()`.

Rendered UI: a Textbox "query", a three-checkbox row "sources" with "docs" pre-checked, a "Search" button, and a "results" Textbox. Query "deploy" with docs+wiki checked prints "4 hits: QMS manual rev 4, audit checklist, on-call rota, deploy runbook" in results; with no sources checked it prints "no hits" — empty list in, your empty-case branch out.

CheckboxGroup as a filter panel in a working mini-search demo — the function receives the selected source names as a list, which is why the search logic stays three lines. All four demos verified by executing them with gradio 6.28.0.

Flags

FlagMeaning
value=TrueSet the initial state; checked on load. Pass a function and Gradio calls it each time the app loads to compute the initial value.
label=...Text shown to the RIGHT of the box (most Gradio inputs put the label on top) — a signature quirk worth knowing before you restyle.
info=...Smaller helper line under the label, supports markdown; use for the 'why' while label stays the 'what'.
interactive=FalseDisplay-only checkbox for read-only panels; otherwise inferred — Gradio decides from whether the component is used as input or output.
visible=False | "hidden"False removes it but keeps its layout slot; "hidden" keeps it in the DOM but invisible — handy for state-carrier checkboxes.
show_select_all=True (CheckboxGroup)Adds a select/deselect-all master checkbox next to the group label; only available when show_label is True.
type="index" (CheckboxGroup)Makes the listener receive the indices of the selected choices instead of their strings — preprocess(["a"]) returned [0] when verified.

There since the beginning

Checkbox ships in Gradio from the earliest releases — it's part of the core input set documented alongside Textbox, Number, Radio and Dropdown in the 1.x era, and it has survived every major rewrite (2.x to 6.x) with its bool-in/bool-out contract unchanged.

Labels went right, customization went deep

In the 3.x/4.x redesign the Checkbox label moved to the right of the box (with info text under it), while elem_id/elem_classes/key/preserved_by_key grew around it — today you can target its DOM node with CSS or re-bind it across gr.render re-renders.

Fun facts

Pros

Cons

Takeaways