Open this notebook in Jupyterlite | Download this notebook from GitHub (right-click to download).

import panel as pn
import param


The CodeEditor widget allows embedding a code editor based on Ace.

Only a small subset of Ace functionality is currently enabled:

  • syntax highlighting for several languages

  • themes

  • basic completion support via ctrl+space (using only static analysis of the code)

  • annotations

  • readonly mode


For details on other options for customizing the component see the layout and styling how-to guides.

  • annotations (list): list of annotations. An annotation is a dict with the following keys:

    • 'row': row in the editor of the annotation

    • 'column': column of the annotation

    • 'text': text displayed when hovering over the annotation

    • 'type': type of annotation and the icon displayed {warning | error}

  • filename (str): If filename is provided the file extension will be used to determine the language

  • language (str): A string declaring which language to use for code syntax highlighting (default: ‘text’)

  • print_margin (boolean): Whether to show a print margin in the editor

  • theme (str): theme of the editor (default: ‘chrome’)

  • readonly (boolean): Whether the editor should be opened in read-only mode

  • value (str): A string with (initial) code to set in the editor

To construct an Ace widget we must define it explicitly using pn.widgets.Ace. We can add some text as initial code. Code inserted in the editor is automatically reflected in the value.

py_code = "import sys"
editor = pn.widgets.CodeEditor(value=py_code, sizing_mode='stretch_width', language='python', height=300)

we can add some code in it

editor.value += """
import Math

x = Math.cos(x)**2 + Math.cos(y)**2

We can change language and theme of the editor

html_code = r"""<!DOCTYPE html>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <title>`substitute(Filename('', 'Page Title'), '^.', '\u&', '')`</title>
editor.language = "html"
editor.theme = "monokai"
editor.value = html_code

We can add some annotations to the editor

editor.annotations = [
    dict(row=1, column=0, text='an error', type='error'),
    dict(row=2, column=0, text='a warning', type='warning')

If we want just to display editor content but not edit it we can set the readonly property to True

#editor.readonly = True

If instead of setting the language explicitly we want to set the filename and automatically detect the language based on the file extension we can do that too:

editor.filename = 'test.html'

Including the CodeEditor editor in a parameterized class#

You can view the Ace widget as part of a param.Parameterized class:

from panel.viewable import Viewer

class CodeEditorTest(Viewer):
    editor = param.String('Hello World')
    def __panel__(self):
        """ Map the string to appear as an Ace editor. """
        return pn.Param(
edit = CodeEditorTest()



The CodeEditor widget exposes a number of options which can be changed from both Python and Javascript. Try out the effect of these parameters interactively:

widget = pn.widgets.CodeEditor(name='CodeEditor', value=py_code, language='python', sizing_mode='stretch_both', min_height=300)

pn.Row(widget.controls(jslink=True), widget, sizing_mode='stretch_both')

Try changing the filename including a file extension and watch the language automatically update.

Open this notebook in Jupyterlite | Download this notebook from GitHub (right-click to download).