AUTOMATIC1111/stable-diffusion-webui
UI
Active contributors: AUTOMATIC1111, w-e-w, missionfloyd, light-and-ray
Purpose
Builds the Gradio Blocks web interface — the txt2img / img2img / Extras / Train / Settings / Extensions tabs — and wires every component to the right server-side handler. This subsystem is the largest in the repo: roughly 6,000 lines across modules/ui*.py.
Directory layout
modules/
├── ui.py # top-level create_ui() — assembles every tab
├── ui_common.py # generation gallery, save buttons, infotext fields
├── ui_components.py # FormRow, FormColumn, InputAccordion, ToolButton
├── ui_toprow.py # the prompt + Generate area shared by tabs
├── ui_extra_networks.py # the Lora/embedding/hypernet browser
├── ui_extra_networks_*.py # per-type browser pages
├── ui_extensions.py # the Extensions tab (install/update/restart)
├── ui_settings.py # the Settings tab (per-section forms)
├── ui_loadsave.py # ui-config.json read/write
├── ui_postprocessing.py # the Extras tab
├── ui_prompt_styles.py # prompt styles dropdown
├── ui_checkpoint_merger.py # the Checkpoint Merger tab
├── ui_gradio_extensions.py # script_path / mtime-based static asset injection
├── ui_tempdir.py # cleanup of /tmp Gradio uploads
└── infotext_utils.py # round-tripping generation params <-> components
javascript/ # browser-side helpers loaded by ui_gradio_extensions
style.css # all UI stylingKey abstractions
| Type | File | Description |
|---|---|---|
create_ui() |
modules/ui.py |
Top-level builder; returns the gr.Blocks instance assigned to shared.demo. |
Toprow |
modules/ui_toprow.py |
The shared prompt textarea + Generate / Skip / Interrupt buttons. |
FormRow, FormColumn, FormGroup, InputAccordion, ToolButton, DropdownMulti, DropdownEditable |
modules/ui_components.py |
Custom Gradio elements; InputAccordion lets the open/closed state be a parameter. |
create_output_panel() |
modules/ui_common.py |
Builds the gallery + Save / Send to img2img / Open folder cluster used by every tab. |
UiSettings |
modules/ui_settings.py |
Iterates shared.opts.data_labels to render the Settings tab; one section per category. |
ExtraNetworksPage and subclasses |
modules/ui_extra_networks.py |
Renders the per-type model browser cards. |
UiLoadsave |
modules/ui_loadsave.py |
Persists slider/dropdown defaults to ui-config.json. |
connect_paste() and paste_fields |
modules/infotext_utils.py |
The "Read generation parameters" and PNG-info round-trip plumbing. |
How it works
create_ui() is the single place that builds the Gradio Blocks tree. It's a long, mostly imperative function:
graph TD
A[create_ui] --> B[script_callbacks.before_ui_callback]
A --> C[ui_extra_networks.initialize]
A --> D[ScriptRunner.initialize_scripts<br/>per tab]
A --> E[Toprow + paste_fields per tab]
A --> F[script_runners[tab].setup_ui<br/>builds custom-script UI]
A --> G[connect Generate / Skip / Interrupt]
A --> H[settings_interface.create_ui<br/>build Settings tab]
A --> I[ui_extensions.create_ui<br/>Extensions tab]
A --> J[script_callbacks.ui_tabs_callback<br/>extension-supplied tabs]
A --> K[gr.Blocks(shared.demo)]Each "tab build" follows a recipe:
- Create a
Toprowfor the prompt area. - Build the parameters column (sampler, steps, CFG, seed, dimensions, batch).
- Hand control to the tab's
ScriptRunner.setup_ui()— this is where alwayson scripts and the Script dropdown render their controls. - Build the output gallery via
create_output_panel. - Wire the Generate button to a handler in
modules/txt2img.pyormodules/img2img.py, wrapped withwrap_gradio_gpu_call()frommodules/call_queue.py. - Register
paste_fieldsso the "Read generation parameters" flow can fill the controls back in.
The Settings tab is the only "data-driven" section: it iterates shared.opts.data_labels and creates a Gradio component per option. Because new settings can be registered by extensions through script_callbacks.on_ui_settings, the Settings tab is rebuilt every time create_ui() is called.
Extra networks UI
modules/ui_extra_networks.py registers a FastAPI route per type (/sd_extra_networks/thumb, /sd_extra_networks/page, /sd_extra_networks/cards) so that the JavaScript browser (javascript/extraNetworks.js) can lazy-load thumbnails. The Python side is responsible for:
- Listing model files for each type (Lora, hypernet, embedding, checkpoint).
- Reading per-card metadata from
<filename>.jsonand<filename>.preview.png. - Generating the HTML for each card.
Extensions add new browser tabs by subclassing ExtraNetworksPage and registering it in ui_extra_networks.register_page().
Settings page
The Settings tab works through data_labels — a dict of {key: OptionInfo} populated at boot in modules/shared_options.py. Each OptionInfo carries metadata (label, component class, default value, validation, refresh function) that UiSettings uses to render the right Gradio control. Extensions add their settings via the on_ui_settings callback. The "Show all pages" toggle just expands collapsed sections.
The "Apply settings" button POSTs to /sdapi/v1/options, which delegates to modules/api/api.py set_config(). Some setting changes trigger onchange callbacks declared in OptionInfo.onchange; for example, sd_model_checkpoint triggers a model reload.
JavaScript bridge
script.js is loaded once and provides gradioApp(), the helper that unwraps Gradio's shadow DOM. Every file in javascript/ is then auto-loaded by ui_gradio_extensions.javascript_html(). Modules can request a server function be invoked from JavaScript with the _js="myFn" parameter on a Gradio event:
button.click(
fn=actual_handler,
inputs=[a, b],
outputs=[c],
_js="myJsFunction", # called first; can transform inputs or open dialogs
)Most "open folder", "context menu", "drag and drop image to UI", "live preview" features are implemented this way.
Integration points
- Settings registration —
script_callbacks.on_ui_settings. See script-callbacks.md. - Custom tabs —
script_callbacks.on_ui_tabs; return a list of(component, label, elem_id)tuples. - Custom train tabs —
script_callbacks.on_ui_train_tabs. - Adding/replacing components —
script_callbacks.on_after_component(most common). Inspectkwargs["elem_id"]and react. - Localisation — the JSON file dropped into
localizations/(or shipped by an extension) is consumed byjavascript/localization.js. - Themes —
shared_gradio_themes.pyexposes the theme dropdown; users can also set--gradio-themeand--gradio-theme-cache.
Entry points for modification
To add a new tab, register it via on_ui_tabs:
def on_ui_tabs():
with gr.Blocks() as ui:
gr.HTML("<h2>Hello</h2>")
return [(ui, "My tab", "my_tab")]
script_callbacks.on_ui_tabs(on_ui_tabs)To change something in an existing tab, prefer on_after_component(elem_id="...") over editing ui.py directly. To restyle, edit style.css; selectors are based on the elem_id and elem_classes attributes set in ui.py.
For a holistic refactor of ui.py, the natural slice points are the per-tab with gr.Tab(...) blocks; each tab's setup is roughly self-contained. See scripts-and-extensions.md for how ScriptRunner plugs into the build.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.
Previous
Systems
Next
Processing pipeline