Bitterbot Desktop: a local-first agent with a memory that decays and a P2P skills market
A local-first AI agent with persistent memory, emotional intelligence, and a peer-to-peer skills economy.
At a glance
- What is it?
- Bitterbot Desktop is an MIT-licensed TypeScript agent that runs on your own machine, keeps memory in a cognitive architecture rather than a vector store, and trades proven skills with other agents over a P2P marketplace. It is ambitious, and the README is honest about less than you would hope.
- Who is it for?
- Adopt Bitterbot Desktop if you want an agent whose memory model you can read in the source and whose skills can be exported as plain directories, and if you are comfortable with a project whose first stable release landed on 2026-08-28. Do not adopt it if you need a hosted service, a documented rollback path, or a memory system you can reason about without reading TypeScript.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Bitterbot Desktop actually is, and who it is built for
The README opens with the problem it wants to solve: most agents are stateless wrappers around an LLM API, and when you close the terminal they forget you. Bitterbot Desktop is the response to that. It is a TypeScript application that runs on macOS, Linux or Windows, keeps its state on your machine, and exposes a WebSocket gateway plus a browser Control UI. The package declares Node 22 or newer and pnpm as the package manager, and the repository ships a Dockerfile, a docker-compose.yml and a desktop/ workspace for the UI.
The audience is narrower than the tagline suggests. You need to be willing to run a gateway process, hold API keys for at least one model provider, and read configuration files under ~/.bitterbot. The README lists Anthropic, OpenAI, Gemini, OpenRouter and others in .env.example, so there is no single required vendor, but there is no hosted tier either. This is software you operate. If you want an agent you sign into, this is the wrong shape of product.
Knowledge Crystals, hormonal state and the dream engine
The memory design is the part worth reading closely. The README states plainly that this is not a vector database with a retrieval step. Memories decay along Ebbinghaus forgetting curves, and a consolidation pipeline runs every 30 minutes doing hormonal decay, chunk merging, low-importance forgetting and governance enforcement. Frequently accessed facts are meant to become permanent while unused ones fade. The repository carries a separate how-the-memory-works.md, which is where you should go before trusting any of this.
On top of that sits a neuromodulator layer. Dopamine, cortisol and oxytocin shift the agent's behaviour, and eight response dimensions (warmth, energy, focus, playfulness, verbosity, curiosity, assertiveness, empathy) are computed from the blend each turn. A curiosity engine scores gaps, contradictions and semantic frontiers through what the README calls a five-component GCCRF reward function, with an alpha parameter that shifts from density-seeking to frontier-seeking as the agent matures. The dream engine runs while you are idle: it consolidates memory, distils skills that provably worked, and the README says it grades its own dreaming by whether the results get used. That last claim is the one to hold it to. A self-graded consolidation loop is only as good as the usage signal feeding it, and the README does not describe what happens when the signal is sparse.
Installing Bitterbot Desktop and running the onboarding wizard
The quick start assumes Node 22 or newer. If pnpm is missing, the README points at corepack, which ships with Node:
corepack enable pnpm || npm install -g pnpmClone the repository, run the system dependency script, install packages, and pull the Chromium build Playwright needs for browser automation:
git clone https://github.com/Bitterbot-AI/bitterbot-desktop.git && cd bitterbot-desktop
bash scripts/setup-deps.sh
pnpm install
pnpm exec playwright install --with-deps chromiumThe setup-deps.sh script installs ffmpeg, ripgrep, jq and similar system tools. On Windows the README is specific: use WSL2 and clone into the Linux filesystem, for example ~/bitterbot-desktop, rather than /mnt/c, because the 9p mount makes boots dramatically slower. That is a measured claim in the README, not one I can verify.
Then run the wizard:
pnpm bitterbot onboardAccording to the README, the wizard walks through model auth, memory embeddings, web search, channels, wallet and workspace setup, then starts the gateway and the Control UI and opens the browser for you. When it finishes, the agent is already running. The Control UI lives at http://127.0.0.1:19001, served by the gateway itself, and the P2P orchestrator starts automatically as a sidecar. To start things later without the wizard:
pnpm start:allThat command builds dist/entry.js and stages the Control UI on first run, so a separate build step is not required. For source development the README offers pnpm dev:all, or pnpm gateway:watch in one terminal and cd desktop && pnpm dev in another. There is also a terminal path to the agent:
pnpm bitterbot agent --agent main --message "What have you learned about me so far?"Reaching the gateway from another machine, and the auth token
The Control UI needs no wiring on the machine running the gateway, because the gateway serves the UI and hands it the auth token over a same-origin loopback endpoint. From another machine, the README gives two options. The first is an SSH tunnel:
ssh -N -L 19001:127.0.0.1:19001 user@hostThe second is the first-run screen, where you point the UI at a remote gateway using the token stored at ~/.bitterbot/bitterbot.json under gateway.auth.token. The docker-compose.yml is more explicit about exposure than the README is. It notes that the container must bind 0.0.0.0 for the port mapping to work, so exposure is governed on the host side, and it defaults the published port to 127.0.0.1. Setting BITTERBOT_BIND_HOST=0.0.0.0, as the comment says, should come with a strong token. The .env.example recommends BITTERBOT_GATEWAY_TOKEN and suggests openssl rand -hex 32 as a generator. It also documents an alternative password mode, BITTERBOT_GATEWAY_PASSWORD, used instead of the token rather than alongside it.
Docker, the sandbox images and what the compose file leaves out
The compose file defines two services from the same image: bitterbot-gateway, which runs node bitterbot.mjs gateway --bind lan --port 19001, and bitterbot-cli, an interactive container with stdin_open and tty set. Both mount BITTERBOT_CONFIG_DIR at /home/node/.bitterbot and BITTERBOT_WORKSPACE_DIR at /home/node/.bitterbot/workspace. The gateway service sets init: true and restart: unless-stopped.
The Dockerfile carries a comment worth reading before you file an issue. It says the file could not build from the initial commit until 2026-08-26, because it copied a ui/ directory and patches/ that never existed, ran an undefined pnpm ui:build, and installed Bun for nothing. It is now verified by a docker-build job in CI. The comment also explains why each extension package.json is copied on its own line: COPY --parents needs a newer BuildKit than CI's classic builder and many self-hosters' Docker provide, and a missed extension makes --frozen-lockfile fail. That is a deliberate trade-off against build convenience, and it means adding an extension with a package.json requires editing the Dockerfile.
Where Bitterbot Desktop is the wrong tool
The repository ships a LIMITATIONS.md, which is a good sign, and the README's own framing is honest about cost. The dream engine, the 30-minute consolidation pipeline and the hormonal layer all run locally, but the model calls behind them do not. You still pay a provider per token, and an agent that consolidates memory every half hour and distils skills while idle is doing background work on your account. The README does not publish a token budget or a cost estimate, so you should measure it yourself before leaving it running unattended.
The second boundary is operational. There is no documented rollback for a bad consolidation, and the README does not describe how to restore memory to an earlier state. The .env.example documents environment precedence (process env, ./.env, ~/.bitterbot/.env, then the bitterbot.json env block) and notes that direct config keys such as gateway.auth.token often take precedence over env fallbacks. That is a real footgun: a token set in bitterbot.json can silently win over the one you exported in your shell.
Third, the P2P skills economy assumes you want it. The orchestrator starts automatically with the gateway, and the marketplace settles in USDC over x402. If you want a single-user local agent with no network counterparties, that sidecar is running whether or not you use it.
How it differs from Letta and Open WebUI
Letta (formerly MemGPT) is the closest comparison, because it also treats memory as an explicit, editable layer rather than a retrieval index. The difference is the mechanism. Letta's approach is paged memory the model manages through tool calls: the agent decides what to write to a core memory block or an archival store. Bitterbot's Knowledge Crystals decay on a schedule without the model asking, and the hormonal layer changes the agent's tone and verbosity as a side effect of consolidation. Letta gives you a memory you can inspect and rewrite; Bitterbot gives you a memory that changes while you are not looking. Which is better depends on whether you want the agent's self-model to be legible or lifelike.
Open WebUI is the other common reference point, and the contrast is sharper. It is a chat front end over local or remote models with retrieval, not an agent with a scheduler, a dream loop and a wallet. If your actual need is a private chat interface to a local model, Open WebUI is far less machinery for the same outcome. Bitterbot earns its complexity only if you want the persistent, self-modifying parts.
Maintenance, licence and what the release history shows
The repository is not archived, and the last push was on 2026-09-10, so it is being worked on right now. The release history is short and recent: v1.0.0 on 2026-08-28, preceded by orchestrator-v0.2.2 and orchestrator-v0.2.1 on 2026-08-14. The presence of release-please-config.json and .release-please-manifest.json suggests releases are cut from conventional commits, which usually means a readable CHANGELOG. The README badge shows version 2026.2.15 while package.json declares 1.0.0, so do not assume the badge and the manifest agree.
The licence is MIT, stated in both the README badge and package.json. That is permissive: you can fork, modify and redistribute, and there is an ATTRIBUTION.md in the repository root that you should read if you plan to. MIT says nothing about the model providers you connect, the channel extensions you enable, or the marketplace transactions the orchestrator performs, and it says nothing about whether trading skills for USDC is lawful or taxable where you live. That is a question for your own counsel, not for the licence text.
Upgrade cost is the open question. The README documents pnpm start:all rebuilding dist/entry.js and staging the UI on first run, and the compose file pins the image tag through BITTERBOT_IMAGE, defaulting to ghcr.io/bitterbot-ai/bitterbot-desktop:latest. There is no documented migration step for the memory store between releases, and the README does not describe what happens to existing crystals when the consolidation pipeline changes.
Editorial conclusion
Adopt Bitterbot Desktop if you want an agent whose memory model you can read in the source and whose skills can be exported as plain directories, and if you are comfortable with a project whose first stable release landed on 2026-08-28. Do not adopt it if you need a hosted service, a documented rollback path, or a memory system you can reason about without reading TypeScript. Before you commit, read LIMITATIONS.md and how-the-memory-works.md in the repository, and check the CHANGELOG for what changed between v1.0.0 and the current main branch.
Frequently asked questions
What is Bitterbot Desktop?
It is an MIT-licensed, local-first personal AI agent written in TypeScript. The README describes it as having biological memory, a dream engine and a P2P skills economy, and it runs a gateway plus a browser Control UI on your own machine.
How do I install Bitterbot Desktop?
You need Node 22 or newer and pnpm. The README's quick start is to clone the repository, run bash scripts/setup-deps.sh, run pnpm install, install Chromium with pnpm exec playwright install --with-deps chromium, and then run pnpm bitterbot onboard.
Does Bitterbot Desktop run on Windows?
The README lists Windows as a supported platform but says to use WSL2 and clone into the Linux filesystem, such as ~/bitterbot-desktop, rather than /mnt/c, because the 9p mount makes boots dramatically slower.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/bitterbot-ai-bitterbot-desktop)