Contents

Ollama Clojure Frontend - Breeze

Introduction

Breeze is a small ollama frontend, with few features, expect that it just works. It allows to talk to ollama in realtime, with a really small memory/disk footprint.

../13_01.png

Prerequisites are:

  • Ollama, to run the models
  • Docker, to run this image from dockerhub.

Start the docker image

docker run -it --rm -p 3000:3000 hellonico/breeze

Breeze UI

The setup screen includes:

  • ollama url
  • ollama model
  • system prompt

../13_02.png

Then, the chat screen allows to chat just like your usual web chat.

Works for

../13_03.png

Just like other chat frontends, the tokens are rendered in real time.

Code Internals

The application has:

  • a frontend in ClojureScript/Reagent
  • a backend in Clojure/Ring
  • the two are connected via websockets.

Pyjama is doing the streaming logic between ollama and the Clojure backend.

Basically the core of the Clojure ring server is:

(let [state (atom (assoc ?data :processing true))
      client-chan (fn [_ text] (chsk-send! uid [:chat/token text]))]
   (p/ollama-chat state (partial client-chan nil))
   (future
    (loop []
     (if (:processing @state)
      (do (Thread/sleep 500) (recur))
      (chsk-send! uid [:chat/done nil])))))

We create a core.async client-chan and then this is passed a parameter to ollama-chat which does the streaming for us.

Docker Internals

The docker build phase:

  • compiles the clojurescript to javascript, and
  • creates an uber-ed jar file, containing all the clojure code and the dependencies
# ---- Build stage ----
FROM eclipse-temurin:21-jdk AS builder

# ... install build deps

WORKDIR /app

# Copy configs and deps
COPY deps.edn package.json shadow-cljs.edn build.clj ./
COPY src ./src
COPY public ./public

# Install JS deps
RUN npm install

# customized ollama url to refer to the host ip
RUN sed -i 's|http://localhost:11434|http://host.docker.internal:11434|g' ./src/myapp/core.cljs

# Compile ClojureScript
RUN npx shadow-cljs release app

# Build backend uberjar
RUN clojure -T:build uber

The docker run image:

  • includes the compiled clojurescript
  • includes the jar file from the build phase
FROM eclipse-temurin:21-jre

WORKDIR /app

COPY --from=builder /app/target/*.jar app.jar
COPY --from=builder /app/public ./public

EXPOSE 3000

ENTRYPOINT ["java", "-jar", "app.jar"]

New features

Right now, low hanging fruits are:

  1. Chat History Persistence

Why: Right now, messages disappear on reload. Persisting chats would let users revisit past sessions.

  1. Multiple Conversations

Why: Let users manage different threads of thought (like tabs or threads in ChatGPT).

  1. Export Chat (Markdown/PDF)

Why: Super helpful for saving valuable exchanges.

  1. Prompt Templates

Why: Let power users quickly apply useful system prompts (e.g. “Act like a proofreader”).

  1. Typing Indicators & Streaming Delay Simulation

Why: For realism and UX polish.

  1. Auth (optional)

Why: To unlock saved history, custom settings per user, etc.

Git project

If you need a feature urgently, get in touch on the project at: https://github.com/hellonico/breeze