It started as a database of 42 quotes.

Mike and I were on a project that was always on fire, and we found that if you click the xkcd random button enough times, you’ll eventually find a comic that’s somehow relevant to whatever chaos is happening today. That became the Law of xkcd: there is always a relevant xkcd. Our brains were interpreting random comics in light of the current situation — finding lessons that were instantly powerful and easy to share.

Then someone on another project heard about Rubber Duck Debugging and jokingly told the PM they needed some ducks. The PM said they’d be there Monday. I went home and my wife asked the perfectly rational question: “Does the duck talk back?”

Of course it can’t. But what if it could?

So I called Mike. It was 9pm on a Friday. Within 30 minutes we had the design. By Saturday afternoon we had a web service and database running. Sunday morning we deployed. Duckie was live before the physical ducks showed up on Monday.

See Duckie Says: Write down your experiences for the full origin story.

What it is now

Duckie has evolved a lot. It’s no longer a database of quotes — it’s a vision-capable LLM. Stateless. No conversation history, no session memory. You hit the duck, you get one reply, that’s it. It’s the closest thing to a rubber duck that actually talks back.

Here’s what it can do:

  • Text prompts — the original mode. Type something, get a response.
  • Image upload — send duckie an image and it actually sees it. The model is vision-capable. Images get resized client-side before sending, because nobody wants to wait for a 5MB phone photo to upload.
  • URL reading — paste a link and duckie fetches the page, strips the HTML, and reacts to the content. Give it a blog post and it’ll tell you what it thinks.
  • Permalinks — every response gets a shareable URL with the prompt and response encoded in the query string. The parameter is called guru-meditation. No database. When you send an image, duckie generates a text description and encodes that instead. See permalinks from sentences for how that feature came to be.

It’s responsive. Works on a phone. Drag and drop on desktop, tap to upload on mobile. The whole thing is designed to do exactly one thing and get out of the way.

How it’s built

Node.js backend running in Docker, behind Traefik for ingress. When you submit something, it hits a local LLM API endpoint and returns the response. Server-side validation on everything — image format checks, size limits, prompt sanitization. Not perfect, but enough to keep the worst of it out.

How it’s developed

This is the part that’s changed the most. Duckie is now primarily developed through an AI agent on Telegram. I describe what I want in plain English, the agent writes the code, tests it, and deploys via Docker. The git repo is at https://github.com/cadeon/duckiesays.

The permalinks feature was one of the first experiments in this workflow — I tied VS Code to LM Studio using the continue.dev plugin, explained what I wanted in a chat window, and wrote no code. The agent wrote the implementation, the tests, and the documentation. I wouldn’t have written tests or documentation at all.

Since then the workflow shifted to a remote agent that handles everything. It’s fast, it produces working code, and it makes decisions I wouldn’t have made, which is either a feature or a bug depending on the day.

The whole thing is stateless, cheap to run, and does exactly one thing. I think that’s a good design.