# ui.input | NiceGUI

[Button: icon:menu]

[](/)

[Installation](/#installation)

[Features](/#features)

[Demos](/#demos)

[Documentation](/documentation)

[Examples](/examples)

[Why?](/#why)

[Button]

[Button]

[](https://github.com/zauberzeug/nicegui/)

[Button: icon:more_vert]

# ui.*input*

## Text Input

This element is based on Quasar's `QInput <https://quasar.dev/vue-components/input>`_ component.

The `on_change` event is called on every keystroke and the value updates accordingly.
If you want to wait until the user confirms the input, you can register a custom event callback, e.g.
`ui.input(...).on('keydown.enter', ...)` or `ui.input(...).on('blur', ...)`.

You can use the `validation` parameter to define a dictionary of validation rules,
e.g. ``{'Too long!': lambda value: len(value) < 3}``.
The key of the first rule that fails will be displayed as an error message.
Alternatively, you can pass a callable that returns an optional error message.
To disable the automatic validation on every value change, you can use the `without_auto_validation` method.

Note about styling the input:
Quasar's `QInput` component is a wrapper around a native `input` element.
This means that you cannot style the input directly,
but you can use the `input-class` and `input-style` props to style the native input element.
See the "Style" props section on the `QInput <https://quasar.dev/vue-components/input>`_ documentation for more details.

:label: displayed label for the text input
:placeholder: text to show if no value is entered
:value: the current value of the text input
:password: whether to hide the input (default: False)
:password_toggle_button: whether to show a button to toggle the password visibility (default: False)
:prefix: a prefix to prepend to the displayed value (*added in version 3.5.0*)
:suffix: a suffix to append to the displayed value (*added in version 3.5.0*)
:on_change: callback to execute when the value changes
:autocomplete: optional list of strings for autocompletion
:validation: dictionary of validation rules or a callable that returns an optional error message (default: None for no validation)

main.py

[Button]

````python
from nicegui import ui

ui.input(label='Text', placeholder='start typing',
         on_change=lambda e: result.set_text('you typed: ' + e.value),
         validation={'Input too long': lambda value: len(value) < 20})
result = ui.label()

ui.run()
````

## Autocompletion

The `autocomplete` feature provides suggestions as you type, making input easier and faster.
The parameter `options` is a list of strings that contains the available options that will appear.

main.py

[Button]

````python
from nicegui import ui

options = ['AutoComplete', 'NiceGUI', 'Awesome']
ui.input(label='Text', placeholder='start typing', autocomplete=options)

ui.run()
````

## Clearable

The `clearable` prop from [Quasar](https://quasar.dev/) adds a button to the input that clears the text.

main.py

[Button]

````python
from nicegui import ui

i = ui.input(value='some text').props('clearable')
ui.label().bind_text_from(i, 'value')

ui.run()
````

## Styling

Quasar has a lot of [props to change the appearance](https://quasar.dev/vue-components/input).
It is even possible to style the underlying input with `input-style` and `input-class` props
and use the provided slots to add custom elements.

main.py

[Button]

````python
from nicegui import ui

ui.input(placeholder='start typing').props('rounded outlined dense')
ui.input('styling', value='some text') \
    .props('input-style="color: blue" input-class="font-mono"')
with ui.input(value='custom clear button').classes('w-64') as i:
    ui.button(color='orange-8', on_click=lambda: i.set_value(None), icon='delete') \
        .props('flat dense').bind_visibility_from(i, 'value')

ui.run()
````

## Input validation

You can validate the input in two ways:

- by passing a callable that returns an error message or `None`, or
- by passing a dictionary that maps error messages to callables that return `True` if the input is valid.

Both of these validations **run on Python-side**,
bringing security against client-side circumventions and flexibility in validation logic.
However they do not correspond to Quasar's validation-related props and methods,
and require server communication and processing.

*Since version 2.7.0:*
The callable validation function can also be an async function.
In this case, the validation is performed asynchronously in the background.

You can use the `validate` method of the input element to trigger the validation manually.
It returns `True` if the input is valid, and an error message otherwise.
For async validation functions, the return value must be explicitly disabled by setting `return_result=False`.

main.py

[Button]

````python
from nicegui import ui

ui.input('Name', validation=lambda value: 'Too short' if len(value) < 5 else None)
ui.input('Name', validation={'Too short': lambda value: len(value) >= 5})

ui.run()
````

## Lazy validation

To run validation lazily, you can consider:

- adding a debounce with the `debounce` prop,
  so that validation is only triggered after the user stops typing for a certain amount of time,
- disabling automatic validation with `without_auto_validation()`
  and calling the `validate` method manually whenever appropriate, e.g., on blur or on form submission,
- or using a combination of both approaches.

main.py

[Button]

````python
from nicegui import ui

ui.input('name (debounce)', validation={'Too short': lambda v: len(v) > 5}) \
    .props('debounce=1000')

name = ui.input('name (on blur)', validation={'Too short': lambda v: len(v) > 5}) \
    .without_auto_validation()
name.on('blur', name.validate)

ui.run()
````

## Client-side validation

Sacrificing security and flexibility for performance, you can also use Quasar's client-side validation
by passing the `rules` prop with Quasar-compatible rules.

This way the Quasar props such as `lazy-rules` and methods such as `resetValidation` can also be used.

Note the use of `:` prefix to denote a JavaScript expression string,
and treating `props` as a dictionary to simplify string-escaping.

main.py

[Button]

````python
from nicegui import ui

name = ui.input('name (client-side)').props('lazy-rules')
name.props[':rules'] = '[ val => val.length > 5 || "Too short" ]'
ui.button('Reset Validation', on_click=lambda: name.run_method('resetValidation'))

ui.run()
````

## Reference

## Initializer

:label: displayed label for the text input
:placeholder: text to show if no value is entered
:value: the current value of the text input
:password: whether to hide the input (default: False)
:password_toggle_button: whether to show a button to toggle the password visibility (default: False)
:prefix: a prefix to prepend to the displayed value (*added in version 3.5.0*)
:suffix: a suffix to append to the displayed value (*added in version 3.5.0*)
:on_change: callback to execute when the value changes
:autocomplete: optional list of strings for autocompletion
:validation: dictionary of validation rules or a callable that returns an optional error message (default: None for no validation)

## Properties

**`prefix`**`: str | None (settable)`

The prefix to prepend to the displayed value.

*Added in version 3.5.0*

**`suffix`**`: str | None (settable)`

The suffix to append to the displayed value.

*Added in version 3.5.0*

**Inherited properties**

**`classes`**`: 'Classes[Self]'`

The classes of the element.

**`client`**`: 'Client'`

The client this element belongs to.

**`enabled`**`: BindableProperty`

**`error`**`: str | None (settable)`

The latest error message from the validation functions.

**`html_id`**`: 'str'`

The ID of the element in the HTML DOM.

*Added in version 2.16.0*

**`is_deleted`**`: 'bool'`

Whether the element has been deleted.

**`is_ignoring_events`**`: bool`

Return whether the element is currently ignoring events.

**`is_ignoring_events`**`: bool`

Return whether the element is currently ignoring events.

**`label`**`: BindableProperty`

**`parent_slot`**`: 'Slot | None' (settable)`

The parent slot of the element.

**`props`**`: 'Props[Self]'`

The props of the element.

**`style`**`: 'Style[Self]'`

The style of the element.

**`validation`**`: collections.abc.Callable[[Any], str | None | collections.abc.Awaitable[str | None]] | dict[str, collections.abc.Callable[[Any], bool]] | None (settable)`

The validation function or dictionary of validation functions.

**`value`**`: BindableProperty`

**`visible`**`: BindableProperty`

## Methods

**`set_autocomplete`**`(autocomplete: list[str] | None) -> Self`

Set the autocomplete list.

**Inherited methods**

**`add_dynamic_resource`**`(name: str, function: Callable) -> None`

Add a dynamic resource to the element which returns the result of a function.

:param name: name of the resource
:param function: function that returns the resource response

**`add_resource`**`(path: str | Path) -> None`

Add a resource to the element.

:param path: path to the resource (e.g. folder with CSS and JavaScript files)

**`add_slot`**`(name: str, template: str | None = None) -> Slot`

Add a slot to the element.

NiceGUI is using the slot concept from Vue:
Elements can have multiple slots, each possibly with a number of children.
Most elements only have one slot, e.g. a `ui.card` (QCard) only has a default slot.
But more complex elements like `ui.table` (QTable) can have more slots like "header", "body" and so on.
If you nest NiceGUI elements via with `ui.row(): ...` you place new elements inside of the row's default slot.
But if you use with `table.add_slot(...): ...`, you enter a different slot.

The slot stack helps NiceGUI to keep track of which slot is currently used for new elements.
The `parent` field holds a reference to its element.
Whenever an element is entered via a `with` expression, its default slot is automatically entered as well.

:param name: name of the slot
:param template: Vue template of the slot
:return: the slot

**`ancestors`**`(include_self: bool = False) -> Iterator[Element]`

Iterate over the ancestors of the element.

:param include_self: whether to include the element itself in the iteration

**`bind_enabled`**`(target_object: Any, target_name: str | tuple[str, ...] = 'enabled', forward: collections.abc.Callable[[Any], Any] | None = None, backward: collections.abc.Callable[[Any], Any] | None = None, strict: bool | None = None) -> Self`

Bind the enabled state of this element to the target object's target_name property.

The binding works both ways, from this element to the target and from the target to this element.
The update happens immediately and whenever a value changes.
The backward binding takes precedence for the initial synchronization.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind to.
:param target_name: The name of the property to bind to.
:param forward: A function to apply to the value before applying it to the target (default: identity).
:param backward: A function to apply to the value before applying it to this element (default: identity).
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`bind_enabled_from`**`(target_object: Any, target_name: str | tuple[str, ...] = 'enabled', backward: collections.abc.Callable[[Any], Any] | None = None, strict: bool | None = None) -> Self`

Bind the enabled state of this element from the target object's target_name property.

The binding works one way only, from the target to this element.
The update happens immediately and whenever a value changes.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind from.
:param target_name: The name of the property to bind from.
:param backward: A function to apply to the value before applying it to this element (default: identity).
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`bind_enabled_to`**`(target_object: Any, target_name: str | tuple[str, ...] = 'enabled', forward: collections.abc.Callable[[Any], Any] | None = None, strict: bool | None = None) -> Self`

Bind the enabled state of this element to the target object's target_name property.

The binding works one way only, from this element to the target.
The update happens immediately and whenever a value changes.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind to.
:param target_name: The name of the property to bind to.
:param forward: A function to apply to the value before applying it to the target (default: identity).
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`bind_label`**`(target_object: Any, target_name: str | tuple[str, ...] = 'label', forward: collections.abc.Callable[[Any], Any] | None = None, backward: collections.abc.Callable[[Any], Any] | None = None, strict: bool | None = None) -> Self`

Bind the label of this element to the target object's target_name property.

The binding works both ways, from this element to the target and from the target to this element.
The update happens immediately and whenever a value changes.
The backward binding takes precedence for the initial synchronization.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind to.
:param target_name: The name of the property to bind to.
:param forward: A function to apply to the value before applying it to the target (default: identity).
:param backward: A function to apply to the value before applying it to this element (default: identity).
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`bind_label_from`**`(target_object: Any, target_name: str | tuple[str, ...] = 'label', backward: collections.abc.Callable[[Any], Any] | None = None, strict: bool | None = None) -> Self`

Bind the label of this element from the target object's target_name property.

The binding works one way only, from the target to this element.
The update happens immediately and whenever a value changes.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind from.
:param target_name: The name of the property to bind from.
:param backward: A function to apply to the value before applying it to this element (default: identity).
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`bind_label_to`**`(target_object: Any, target_name: str | tuple[str, ...] = 'label', forward: collections.abc.Callable[[Any], Any] | None = None, strict: bool | None = None) -> Self`

Bind the label of this element to the target object's target_name property.

The binding works one way only, from this element to the target.
The update happens immediately and whenever a value changes.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind to.
:param target_name: The name of the property to bind to.
:param forward: A function to apply to the value before applying it to the target (default: identity).
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`bind_value`**`(target_object: Any, target_name: str | tuple[str, ...] = 'value', forward: collections.abc.Callable[[~ValueT], Any] | None = None, backward: collections.abc.Callable[[Any], ~ValueT] | None = None, strict: bool | None = None) -> Self`

Bind the value of this element to the target object's target_name property.

The binding works both ways, from this element to the target and from the target to this element.
The update happens immediately and whenever a value changes.
The backward binding takes precedence for the initial synchronization.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind to.
:param target_name: The name of the property to bind to.
:param forward: A function to apply to the value before applying it to the target (default: identity).
:param backward: A function to apply to the value before applying it to this element (default: identity).
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`bind_value_from`**`(target_object: Any, target_name: str | tuple[str, ...] = 'value', backward: collections.abc.Callable[[Any], ~ValueT] | None = None, strict: bool | None = None) -> Self`

Bind the value of this element from the target object's target_name property.

The binding works one way only, from the target to this element.
The update happens immediately and whenever a value changes.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind from.
:param target_name: The name of the property to bind from.
:param backward: A function to apply to the value before applying it to this element (default: identity).
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`bind_value_to`**`(target_object: Any, target_name: str | tuple[str, ...] = 'value', forward: collections.abc.Callable[[~ValueT], Any] | None = None, strict: bool | None = None) -> Self`

Bind the value of this element to the target object's target_name property.

The binding works one way only, from this element to the target.
The update happens immediately and whenever a value changes.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind to.
:param target_name: The name of the property to bind to.
:param forward: A function to apply to the value before applying it to the target (default: identity).
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`bind_visibility`**`(target_object: Any, target_name: str | tuple[str, ...] = 'visible', forward: collections.abc.Callable[[Any], Any] | None = None, backward: collections.abc.Callable[[Any], Any] | None = None, value: Any = None, strict: bool | None = None) -> Self`

Bind the visibility of this element to the target object's target_name property.

The binding works both ways, from this element to the target and from the target to this element.
The update happens immediately and whenever a value changes.
The backward binding takes precedence for the initial synchronization.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind to.
:param target_name: The name of the property to bind to.
:param forward: A function to apply to the value before applying it to the target (default: identity).
:param backward: A function to apply to the value before applying it to this element (default: identity).
:param value: If specified, the element will be visible only when the target value is equal to this value.
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`bind_visibility_from`**`(target_object: Any, target_name: str | tuple[str, ...] = 'visible', backward: collections.abc.Callable[[Any], Any] | None = None, value: Any = None, strict: bool | None = None) -> Self`

Bind the visibility of this element from the target object's target_name property.

The binding works one way only, from the target to this element.
The update happens immediately and whenever a value changes.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind from.
:param target_name: The name of the property to bind from.
:param backward: A function to apply to the value before applying it to this element (default: identity).
:param value: If specified, the element will be visible only when the target value is equal to this value.
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`bind_visibility_to`**`(target_object: Any, target_name: str | tuple[str, ...] = 'visible', forward: collections.abc.Callable[[Any], Any] | None = None, strict: bool | None = None) -> Self`

Bind the visibility of this element to the target object's target_name property.

The binding works one way only, from this element to the target.
The update happens immediately and whenever a value changes.
The ``target_name`` parameter also accepts a tuple of strings for nested keys (*since version 3.10.0*).

:param target_object: The object to bind to.
:param target_name: The name of the property to bind to.
:param forward: A function to apply to the value before applying it to the target (default: identity).
:param strict: Whether to check (and raise) if the target object has the specified property (default: None,
    performs a check if the object is not a dictionary, *added in version 3.0.0*).

**`clear`**`() -> Self`

Remove all child elements.

`@classmethod`<br />**`default_classes`**`(add: str | None = None, remove: str | None = None, toggle: str | None = None, replace: str | None = None) -> type[Self]`

Apply, remove, toggle, or replace default HTML classes.

This allows modifying the look of the element or its layout using `Tailwind <https://tailwindcss.com/>`_ or `Quasar <https://quasar.dev/>`_ classes.

Removing or replacing classes can be helpful if predefined classes are not desired.
All elements of this class will share these HTML classes.
These must be defined before element instantiation.

:param add: whitespace-delimited string of classes
:param remove: whitespace-delimited string of classes to remove from the element
:param toggle: whitespace-delimited string of classes to toggle (*added in version 2.7.0*)
:param replace: whitespace-delimited string of classes to use instead of existing ones

`@classmethod`<br />**`default_props`**`(add: str | None = None, remove: str | None = None) -> type[Self]`

Add or remove default props.

This allows modifying the look of the element or its layout using `Quasar <https://quasar.dev/>`_ props.
Since props are simply applied as HTML attributes, they can be used with any HTML element.
All elements of this class will share these props.
These must be defined before element instantiation.

Boolean properties are assumed ``True`` if no value is specified.

:param add: whitespace-delimited list of either boolean values or key=value pair to add
:param remove: whitespace-delimited list of property keys to remove

`@classmethod`<br />**`default_style`**`(add: str | None = None, remove: str | None = None, replace: str | None = None) -> type[Self]`

Apply, remove, or replace default CSS definitions.

Removing or replacing styles can be helpful if the predefined style is not desired.
All elements of this class will share these CSS definitions.
These must be defined before element instantiation.

:param add: semicolon-separated list of styles to add to the element
:param remove: semicolon-separated list of styles to remove from the element
:param replace: semicolon-separated list of styles to use instead of existing ones

**`delete`**`() -> None`

Delete the element and all its children.

**`descendants`**`(include_self: bool = False) -> Iterator[Element]`

Iterate over the descendants of the element.

:param include_self: whether to include the element itself in the iteration

**`disable`**`() -> Self`

Disable the element.

**`enable`**`() -> Self`

Enable the element.

**`get_computed_prop`**`(prop_name: str, timeout: float = 1) -> AwaitableResponse`

Return a computed property.

This function should be awaited so that the computed property is properly returned.

:param prop_name: name of the computed prop
:param timeout: maximum time to wait for a response (default: 1 second)

**`mark`**`(*markers: str) -> Self`

Replace markers of the element.

Markers are used to identify elements for querying with `ElementFilter </documentation/element_filter>`_
which is heavily used in testing
but can also be used to reduce the number of global variables or passing around dependencies.

:param markers: list of strings or single string with whitespace-delimited markers; replaces existing markers

**`move`**`(target_container: Element | None = None, target_index: int = -1, target_slot: str | None = None) -> Self`

Move the element to another container.

:param target_container: container to move the element to (default: the parent container)
:param target_index: index within the target slot (default: append to the end)
:param target_slot: slot within the target container (default: default slot)

**`on`**`(type: str, handler: events.Handler[events.GenericEventArguments] | None = None, args: None | Sequence[str] | Sequence[Sequence[str] | None] = None, throttle: float = 0.0, leading_events: bool = True, trailing_events: bool = True, js_handler: str = '(...args) => emit(...args)') -> Self`

Subscribe to an event.

The event handler can be a Python function, a JavaScript function or a combination of both:

- If you want to handle the event on the server with all (serializable) event arguments,
  use a Python ``handler``.
- If you want to handle the event on the client side without emitting anything to the server,
  use ``js_handler`` with a JavaScript function handling the event.
- If you want to handle the event on the server with a subset or transformed version of the event arguments,
  use ``js_handler`` with a JavaScript function emitting the transformed arguments using ``emit()``, and
  use a Python ``handler`` to handle these arguments on the server side.
  The ``js_handler`` can also decide to selectively emit arguments to the server,
  in which case the Python ``handler`` will not always be called.

Note that the arguments ``throttle``, ``leading_events``, and ``trailing_events`` are only relevant
when emitting events to the server.

*Updated in version 2.18.0: Both handlers can be specified at the same time.*

:param type: name of the event (e.g. "click", "mousedown", or "update:model-value")
:param handler: callback that is called upon occurrence of the event
:param args: arguments included in the event message sent to the event handler (default: ``None`` meaning all)
:param throttle: minimum time (in seconds) between event occurrences (default: 0.0)
:param leading_events: whether to trigger the event handler immediately upon the first event occurrence (default: ``True``)
:param trailing_events: whether to trigger the event handler after the last event occurrence (default: ``True``)
:param js_handler: JavaScript function that is handling the event on the client (default: "(...args) => emit(...args)")

**`on_value_change`**`(callback: collections.abc.Callable[[nicegui.events.ValueChangeEventArguments[~ValueT]], Any] | collections.abc.Callable[[], Any]) -> Self`

Add a callback to be invoked when the value changes.

**`remove`**`(element: Element | int) -> None`

Remove a child element.

:param element: either the element instance or its ID

**`run_method`**`(name: str, *args: Any, timeout: float = 1) -> AwaitableResponse`

Run a method on the client side.

If the function is awaited, the result of the method call is returned.
Otherwise, the method is executed without waiting for a response.

:param name: name of the method
:param args: arguments to pass to the method
:param timeout: maximum time to wait for a response (default: 1 second)

**`set_enabled`**`(value: bool) -> Self`

Set the enabled state of the element.

**`set_label`**`(label: str | None) -> Self`

Set the label of this element.

:param label: The new label.

**`set_value`**`(value: ~ValueT) -> Self`

Set the value of this element.

:param value: The value to set.

**`set_visibility`**`(visible: bool) -> Self`

Set the visibility of this element.

:param visible: Whether the element should be visible.

**`tooltip`**`(text: str) -> Self`

Add a tooltip to the element.

:param text: text of the tooltip

**`update`**`() -> None`

Update the element on the client side.

**`validate`**`(return_result: bool = True) -> bool`

Validate the current value and set the error message if necessary.

For async validation functions, ``return_result`` must be set to ``False`` and the return value will be ``True``,
independently of the validation result which is evaluated in the background.

*Updated in version 2.7.0: Added support for async validation functions.*

:param return_result: whether to return the result of the validation (default: ``True``)
:return: whether the validation was successful (always ``True`` for async validation functions)

**`without_auto_validation`**`() -> Self`

Disable automatic validation on value change.

## Inheritance

- `LabelElement`
- `ValidationElement`
- `ValueElement`
- `DisableableElement`
- `Element`
- `Visibility`

**Nice**GUI

The Python UI framework that shows up in your browser.

[](https://github.com/zauberzeug/nicegui/)

[](https://discord.gg/TEpFeAaF4f)

[](https://www.reddit.com/r/nicegui/)

Resources

[Documentation](/documentation)

[Examples](/examples)

[LLM reference](/llms.txt)

[GitHub](https://github.com/zauberzeug/nicegui/)

[PyPI](https://pypi.org/project/nicegui/)

Community

[Discussions](https://github.com/zauberzeug/nicegui/discussions)

[Discord](https://discord.gg/TEpFeAaF4f)

[Reddit](https://www.reddit.com/r/nicegui/)

[Contributing](https://github.com/zauberzeug/nicegui/blob/main/CONTRIBUTING.md)

[Sponsors](https://github.com/sponsors/zauberzeug)

Legal

[Imprint](/imprint_privacy#imprint)

[Privacy](/imprint_privacy#privacy)

Made with NiceGUI by [Zauberzeug](https://zauberzeug.com)

© 2026 [Zauberzeug GmbH](https://zauberzeug.com)