One-Shot Any Web App with Gradio's gr.HTML
Source: Hugging Face Blog
Contributors
Navigation
Gradio 6’s New gr.HTML Component
Gradio 6 quietly shipped a very powerful feature: gr.HTML now supports custom templates, scoped CSS, and JavaScript interactivity.
You can build virtually any web component—and a frontier LLM (Claude, GPT‑4, etc.) can generate the whole thing in one shot: frontend, backend, and state management, all in a single Python file.
We tested this by building different types of apps. Each one is a single Python file, has no build step, and can be deployed to Hugging Face Spaces in seconds.
Productivity Apps
Pomodoro Timer
A focus timer where a pixel‑art tree grows as you work.
- Starts as a seed, sprouts branches, and grows leaves.
- Complete a session and the tree joins your forest.
- Session tracking, theme switching, break modes — all interactive, all in one file.
The tree animation alone would normally require a separate React component. Here it’s just CSS keyframes in css_template and state updates in js_on_load.
Business Apps
GitHub Contribution Heatmap
- Click any cell to toggle contributions.
- Multiple colour themes.
- Pattern generators (streaks, seasonal, random).
- Live stats that update as you edit.
Kanban Board
- Full drag‑and‑drop between columns.
- Inline editing (double‑click any card).
- Real‑time search filter.
- Collapsible columns.
Drag‑and‑drop usually means pulling in a library. Here it’s native HTML5 drag events wired up in js_on_load, with state synced back to Python via trigger('change').
Creative Apps
Spin‑to‑Win Wheel
- Smooth CSS animation with rotation state that persists across re‑renders.
- Preset configurations for yes/no decisions, restaurant picking, team selection.
- Add custom spinning segments on the fly.
ML Apps
gr.HTML shines for ML work because you can build specialised components that handle exactly the output format you need, then use them like any built‑in Gradio component.
Detection Viewer
A custom viewer for object detection, instance segmentation, and pose‑estimation results.
- Renders bounding boxes, segmentation masks, keypoints, and skeleton connections.
- Implemented as a reusable
gr.HTMLsubclass that plugs directly into a model pipeline.
Community‑Built Components
-
3D Camera Control for Image Editing – A full Three.js viewport inside a Gradio app. Drag handles control azimuth, elevation, and distance; the uploaded image appears in the 3D scene, and the camera parameters feed directly into Qwen’s latest image‑editing model.
-
Real‑time Speech Transcription – Live transcription with Mistral’s Voxtral model. The transcript display is a custom
gr.HTMLcomponent with animated status badges, a live WPM counter, and styled output that updates as you speak. Real‑time UI feedback without React!
How It Works
Every gr.HTML component takes three (optional) templates:
gr.HTML(
value={"count": 0},
html_template="Clicked ${value.count} times",
css_template="button { background: #667eea; color: white; }",
js_on_load="""
element.querySelector('button').onclick = () => {
props.value = { count: props.value.count + 1 };
trigger('change');
};
"""
)
${value}injects Python state into the HTML.props.valueupdates that state from JavaScript.trigger('change')syncs the new state back to Python.
That’s the whole API.
Reusable Components
Subclass gr.HTML to create reusable widgets:
class Heatmap(gr.HTML):
def __init__(self, value=None, theme="green", **kwargs):
super().__init__(
value=value,
theme=theme,
html_template=TEMPLATE,
css_template=STYLES,
js_on_load=SCRIPT,
**kwargs,
)
Now Heatmap() behaves like gr.Image() or gr.Slider()—you can drop it into a Blocks layout, wire up event handlers, etc.
Why This Matters for Vibe Coding
When you ask an LLM to build a custom component, a single‑file output is everything. No “create a separate styles file” or “wire this into your build config.” Just one Python file that runs immediately.
The feedback loop becomes:
- Describe what you want.
- Get the generated code.
- Run
gradio app.py(orgradio run app.py). - See it working.
- Iterate with new prompts.
Each cycle takes seconds thanks to Gradio’s reload mode.
Deploy
- Deploy to Spaces with
gradio deploy. - Or share a temporary link with
gradio share.
You can also share your demo with demo.launch(share=True). Within a few seconds, turn an idea into a live app.
Gradio ships with 32 interactive components, but sometimes your perfect AI web app needs something special. That’s where gr.HTML comes in.
If you’ve got an idea, try building it with gr.HTML: describe what you want to your LLM, generate the code, and run it. You might be surprised what you can ship in 5 minutes.
Suggested reading
- Gradio guide: Custom Components with
gr.HTML - API docs:
gr.HTML