# Using Jupyter to write FastHTML Writing FastHTML applications in Jupyter notebooks requires a slightly different process than normal Python applications.
> **Download this notebook and try it yourself** > > The source code for this page is a [Jupyter > notebook](https://github.com/AnswerDotAI/fasthtml/blob/main/nbs/tutorials/jupyter_and_fasthtml.ipynb). > That makes it easy to directly experiment with it. However, as this is > working code that means we have to comment out a few things in order > for the documentation to build.
The first step is to import necessary libraries. As using FastHTML inside a Jupyter notebook is a special case, it remains a special import. ``` python from fasthtml.common import * from fasthtml.jupyter import JupyUvi, HTMX ``` Let’s create an app with `fast_app`. ``` python app, rt = fast_app(pico=True) ``` Define a route to test the application. ``` python @rt def index(): return Titled('Hello, Jupyter', P('Welcome to the FastHTML + Jupyter example'), Button('Click', hx_get='/click', hx_target='#dest'), Div(id='dest') ) ``` Create a `server` object using [`JupyUvi`](https://www.fastht.ml/docs/api/jupyter.html#jupyuvi), which also starts Uvicorn. The `server` runs in a separate thread from Jupyter, so it can use normal HTTP client functions in a notebook. ``` python server = JupyUvi(app) ``` The [`HTMX`](https://www.fastht.ml/docs/api/jupyter.html#htmx) callable displays the server’s HTMX application in an iframe which can be displayed by Jupyter notebook. Pass in the same `port` variable used in the [`JupyUvi`](https://www.fastht.ml/docs/api/jupyter.html#jupyuvi) callable above or leave it blank to use the default (8000). ``` python # This doesn't display in the docs - uncomment and run it to see it in action # HTMX() ``` We didn’t define the `/click` route, but that’s fine - we can define (or change) it any time, and it’s dynamically inserted into the running app. No need to restart or reload anything! ``` python @rt def click(): return P('You clicked me!') ``` ## Full screen view You can view your app outside of Jupyter by going to `localhost:PORT`, where `PORT` is usually the default 8000, so in most cases just click [this link](localhost:8000/). ## Graceful shutdowns Use the `server.stop()` function displayed below. If you restart Jupyter without calling this line the thread may not be released and the [`HTMX`](https://www.fastht.ml/docs/api/jupyter.html#htmx) callable above may throw errors. If that happens, a quick temporary fix is to specify a different port number in JupyUvi and HTMX with the `port` parameter. Cleaner solutions to the dangling thread are to kill the dangling thread (dependant on each operating system) or restart the computer. ``` python server.stop() ```