diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f75c4cd83e14ed926c87ed58ca89a88fc6d13776
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*env/
+.env
diff --git a/Dockerfile b/Dockerfile
index 8786a758900390cc3fd685c6dad024be8a9ffd89..e5fa5617104e60caab17506036ff1b0982cdd33a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,15 +1,17 @@
 FROM jupyter/datascience-notebook:hub-3.1.1
 
-# Install from APT repository
 USER root
-RUN apt-get update -y
-RUN apt-get install -y git
 
-# Install basics
-USER jovyan
-RUN pip3 install --upgrade pip
+COPY requirements.txt environment.yml /tmp/
+RUN conda env update -q -f /tmp/environment.yml && \
+    /opt/conda/bin/pip install -r /tmp/requirements.txt && \
+    conda clean -y --all && \
+    conda env export -n "root" && \
+    jupyter lab build 
+
+COPY jupyter_notebook_config.py ${HOME}/.jupyter/
+
+# copy dash app
+COPY app ${HOME}/app/
+RUN chown -R jovyan ${HOME}/app/
 
-# RUN pip3 install --upgrade pip
-RUN pip install jupyter-server-proxy==4.0.0
-RUN pip install jupyterlab-git==0.42.0
-RUN pip install jupyterlab-gitlab==3.0.0
diff --git a/README.md b/README.md
index 38011d6a37fc8d8cec424c34a4e464afbffda1cd..0afc659489002fca20af391308f6f1756f456bac 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,2 @@
-# bücker
+# A Jupyterlab for LLM
 
diff --git a/app/app.py b/app/app.py
new file mode 100644
index 0000000000000000000000000000000000000000..4975d674ba0a1f11b0bc9f79d0ec5f40b9855e3b
--- /dev/null
+++ b/app/app.py
@@ -0,0 +1,44 @@
+import sys 
+sys.path.append("/home/jovyan")
+
+import argparse
+import logging
+
+from dash import Dash
+
+from layout import layout
+from callbacks import register_callbacks
+
+logging.basicConfig(level=logging.INFO)
+
+
+# get the correct port from proxy
+parser = argparse.ArgumentParser()
+parser.add_argument("--port", type=int)
+args = parser.parse_args()
+port: int = args.port
+
+if not port:
+    raise ValueError(f"Port of proxy server for Dash not found in {args}.")
+else: 
+    logging.debug(f"Dash app running on port {port}.")
+
+# define Dash app
+app = Dash(
+    name=__name__, 
+    requests_pathname_prefix="/dash/"
+)
+
+# define layout
+app.layout = layout
+
+# register all callback functions
+register_callbacks(app=app)
+
+# Run Dash app in the notebook
+app.run(
+    jupyter_mode="jupyterlab", 
+    port=port, 
+    host="localhost",
+    debug=True
+)
diff --git a/app/callbacks.py b/app/callbacks.py
new file mode 100644
index 0000000000000000000000000000000000000000..9d22226c2194586ef572f89df93d984cdbb45b46
--- /dev/null
+++ b/app/callbacks.py
@@ -0,0 +1,23 @@
+from dash import (
+    html, 
+    Dash
+)
+from dash.dependencies import (
+    Input, 
+    Output, 
+    State
+)
+
+
+def register_callbacks(app: Dash):
+    @app.callback(
+        Output("output-container", "children"),
+        [Input("send-button", "n_clicks")],
+        [State("input-text", "value")]
+    )
+    def generate_response(n_clicks, input_text):
+        if n_clicks > 0:
+            response = "You said: " + input_text
+            return html.Div(response)
+        else:
+            return ""
diff --git a/app/layout.py b/app/layout.py
new file mode 100644
index 0000000000000000000000000000000000000000..fbc93fabc4da27a70e5de4e5a87cd4d8e7a7de0b
--- /dev/null
+++ b/app/layout.py
@@ -0,0 +1,14 @@
+from dash import (
+    html, 
+    dcc
+)
+
+layout = html.Div(
+    className="container",
+    children=[
+        html.H1("GPT Chat", className="mt-5 mb-4"),
+        dcc.Textarea(id="input-text", placeholder="Enter your message:", className="form-control mb-3"),
+        html.Button("Send", id="send-button", n_clicks=0, className="btn btn-primary mb-3"),
+        html.Div(id="output-container")
+    ]
+)
diff --git a/environment.yml b/environment.yml
new file mode 100644
index 0000000000000000000000000000000000000000..eef32e175e1f18d058cee69d1e5baf91d7bdca45
--- /dev/null
+++ b/environment.yml
@@ -0,0 +1,7 @@
+name: "base"
+channels:
+  - defaults
+# dependencies:
+# - add packages here
+# - one per line
+prefix: "/opt/conda"
diff --git a/jupyter_notebook_config.py b/jupyter_notebook_config.py
new file mode 100644
index 0000000000000000000000000000000000000000..22208d38066f4dd7b1271c4df093530370bf3943
--- /dev/null
+++ b/jupyter_notebook_config.py
@@ -0,0 +1,13 @@
+# Configuration file for jupyter-notebook.
+c.ServerProxy.servers = {
+    'dash': {
+        'command': [
+            'python',
+            'app/app.py',
+            '--port',
+            '{port}'
+        ],
+        'absolute_url': False,
+        'new_browser_tab': False
+    }
+}
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cf2d38745b7fdd77160de57b069714e8d73411e7
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,12 @@
+jupyter-server-proxy==4.0.0
+jupyterlab-git==0.42.0
+jupyter_server>=2.0
+
+dash
+dash-bootstrap-components
+plotly
+
+openai
+rapidfuzz
+
+python-dotenv