# ui.codemirror | 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.*codemirror*

## CodeMirror

An element to create a code editor using `CodeMirror <https://codemirror.net/>`_.

It supports syntax highlighting for over 140 languages, more than 30 themes, line numbers, code folding, (limited) auto-completion, and more.

Supported languages and themes:
    - Languages: A list of supported languages can be found in the `@codemirror/language-data <https://github.com/codemirror/language-data/blob/main/src/language-data.ts>`_ package.
    - Themes: A list can be found in the `@uiw/codemirror-themes-all <https://github.com/uiwjs/react-codemirror/tree/master/themes/all>`_ package.

At runtime, the methods `supported_languages` and `supported_themes` can be used to get supported languages and themes.

*Since version 3.13.0:*
Per-line tooltips can be attached via the ``line_tooltips`` dict.

*Since version 3.14.0:*
The ``keymap`` maps keystrokes (CodeMirror key strings) to Python callbacks.
Pass a bare callable for the default config (prevents the browser default, no per-OS override).
Wrap with ``KeyBinding`` for per-key overrides such as ``prevent_default=False`` or platform-specific shortcuts (``mac=``, ``linux=``, ``win=``).
Use ``map_key`` to add keybindings at runtime and ``unmap_key`` to drop them.
Keybindings do not fire while the editor is disabled.

:value: initial value of the editor (default: "")
:on_change: callback to be executed when the value changes (default: `None`)
:keymap: mapping of CodeMirror key strings (e.g. "Mod-s", "F5") to handlers, optionally wrapped with ``KeyBinding`` (default: ``None``, *added in version 3.14.0*)
:language: initial language of the editor (case-insensitive, default: `None`)
:theme: initial theme of the editor (default: "basicLight")
:indent: string to use for indentation (any string consisting entirely of the same whitespace character, default: "    ")
:line_wrapping: whether to wrap lines (default: `False`)
:highlight_whitespace: whether to highlight whitespace (default: `False`)
:line_tooltips: initial mapping of 1-indexed line numbers to tooltip content (default: ``None``, *added in version 3.13.0*)
:line_tooltip_html: render tooltip content as sanitized HTML rather than plain text (default: ``False``, *added in version 3.13.0*)

main.py

[Button]

````python
from nicegui import ui

editor = ui.codemirror('print("Edit me!")', language='Python').classes('h-32')
ui.select(editor.supported_languages, label='Language', clearable=True) \
    .classes('w-32').bind_value(editor, 'language')
ui.select(editor.supported_themes, label='Theme') \
    .classes('w-32').bind_value(editor, 'theme')
ui.checkbox('Wrap Lines', value=editor.line_wrapping,
            on_change=lambda e: editor.set_line_wrapping(e.value))

ui.run()
````

## Preserving Cursor Position

``set_value`` applies only the modified region, so cursor positions and selections outside the change are preserved.
Try editing the code below while the first line updates automatically.

main.py

[Button]

````python
from datetime import datetime
from nicegui import ui

editor = ui.codemirror(f'# {datetime.now():%H:%M:%S}\n', language='Python')
ui.timer(1, lambda: editor.set_value(
    f'# {datetime.now():%H:%M:%S}\n' + editor.value.split('\n', 1)[-1]
))

ui.run()
````

## Custom Keybindings

Map keystrokes to Python callbacks via the `keymap` constructor parameter or the `map_key` method.
Keys follow CodeMirror's [keymap syntax](https://codemirror.net/docs/ref/#view.KeyBinding) —
use "Mod" for Cmd on macOS and Ctrl elsewhere.

By default, keybindings prevent the browser default action so they can override shortcuts like "Mod-s".
Wrap a callback with `ui.codemirror.KeyBinding(...)` to override that (`prevent_default=False`)
or to provide per-platform shortcut overrides (`mac=`, `linux=`, `win=`).

Use `unmap_key(key)` to remove a mapping at runtime.

*Added in NiceGUI 3.14.0*

main.py

[Button]

````python
from nicegui import ui

editor = ui.codemirror(
    keymap={
        'a': lambda: ui.notify('Pressed a'),
        'Ctrl-c': lambda: ui.notify('Pressed Ctrl-c'),
        'Mod-r': lambda: ui.notify('Pressed Mod-r'),
        'Mod-s': ui.codemirror.KeyBinding(
            lambda: ui.notify('Pressed Mod-s (no prevent_default)'),
            prevent_default=False,
        ),
        'Mod-x Mod-y': lambda: ui.notify('Pressed Mod-x then Mod-y'),
    },
).classes('h-32')
ui.button('Map F5', on_click=lambda: editor.map_key('F5', lambda: ui.notify('Pressed F5')))
ui.button('Unmap F5', on_click=lambda: editor.unmap_key('F5'))

ui.run()
````

## Hover tooltips on lines

`line_tooltips` maps 1-indexed line numbers to hover content.

*Added in NiceGUI 3.13.0*

main.py

[Button]

````python
from nicegui import ui

editor = ui.codemirror(
    'def add(a, b):\n'
    '    """Sum two numbers."""\n'
    '    return a + b\n',
).classes('h-40')
editor.line_tooltips[1] = 'symbol: add, arity: 2'
editor.line_tooltips[3] = 'returns the sum of a and b'

ui.run()
````

## HTML rendering for tooltips

Pass `line_tooltip_html=True` to render tooltip content as HTML,
sanitized via NiceGUI's DOMPurify-backed `setHTML` polyfill.

*Added in NiceGUI 3.13.0*

main.py

[Button]

````python
from nicegui import ui

editor = ui.codemirror(
    'def add(a, b):\n'
    '    return a + b\n',
    line_tooltip_html=True,
).classes('h-32')
editor.line_tooltips[2] = '<b>returns</b> the sum of <code>a</code> and <code>b</code>'

ui.run()
````

## Reference

## Initializer

:value: initial value of the editor (default: "")
:on_change: callback to be executed when the value changes (default: `None`)
:keymap: mapping of CodeMirror key strings (e.g. "Mod-s", "F5") to handlers, optionally wrapped with ``KeyBinding`` (default: ``None``, *added in version 3.14.0*)
:language: initial language of the editor (case-insensitive, default: `None`)
:theme: initial theme of the editor (default: "basicLight")
:indent: string to use for indentation (any string consisting entirely of the same whitespace character, default: "    ")
:line_wrapping: whether to wrap lines (default: `False`)
:highlight_whitespace: whether to highlight whitespace (default: `False`)
:line_tooltips: initial mapping of 1-indexed line numbers to tooltip content (default: ``None``, *added in version 3.13.0*)
:line_tooltip_html: render tooltip content as sanitized HTML rather than plain text (default: ``False``, *added in version 3.13.0*)

## Properties

**`language`**`: 'str' (settable)`

The current language of the editor.

**`line_tooltips`**`: 'dict[int, str]' (settable)`

Mapping of 1-indexed line numbers to tooltip content.

*Added in version 3.13.0*

**`line_wrapping`**`: 'bool' (settable)`

Whether line wrapping is enabled

*Added in version 3.2.0*

**`supported_languages`**`: 'list[str]'`

List of supported languages.

**`supported_themes`**`: 'list[str]'`

List of supported themes.

**`theme`**`: 'str' (settable)`

The current theme of the editor.

**Inherited properties**

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

The classes of the element.

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

The client this element belongs to.

**`enabled`**`: BindableProperty`

**`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.

**`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.

**`value`**`: BindableProperty`

**`visible`**`: BindableProperty`

## Methods

**`set_language`**`(language: SUPPORTED_LANGUAGES | None = None) -> Self`

Sets the language of the editor (case-insensitive).

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

Sets whether line wrapping is enabled.

*Added in version 3.2.0*

**`set_theme`**`(theme: SUPPORTED_THEMES) -> Self`

Sets the theme of the editor.

**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_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)

**`map_key`**`(key: str, handler: Handler[CodeMirrorKeyBindingEventArguments] | KeyBindingElement.KeyBinding) -> Self`

Map a keystroke to a callback.

The ``key`` follows CodeMirror 6's keybinding syntax (e.g. "Mod-s", "F5", "Mod-Shift-d").
"Mod" resolves to "Cmd" on macOS and "Ctrl" elsewhere.

Pass a bare callable for the default config (prevents the browser default, no per-OS override),
or wrap with ``KeyBinding`` for per-key overrides.

Re-registering the same key replaces the prior handler. Keybindings do not fire while the editor is disabled.

*Added in version 3.14.0*

**`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_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

**`unmap_key`**`(key: str) -> Self`

Remove a previously bound keybinding.

No-op if the key is not currently bound.

*Added in version 3.14.0*

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

Update the element on the client side.

## Inheritance

- `KeyBindingElement`
- `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)