Start
Installing is the middle of this page, not the end of it. What you are here to do is write something — a small program that stores durable state, reacts to it, and calls a model, without a framework, an SDK or a running server anywhere in the picture. That is the second half.
Two acts
The first act brings bentos itself. The second brings the rest of the userland.
$ bentos install
$ bentos install
The bootstrap installs into ~/.bentos/bin — not ~/.local/bin — and if that directory is not on your PATH it says so, loudly, and prints the line to fix it:
$ curl -fsSL https://github.com/cafe01/bentos-userland/releases/latest/download/bootstrap.sh | sh
bentos: v0.1.5 · macos-arm64 · bentos-macos-arm64
bentos: installed /home/you/.bentos/bin/bentos
bentos: /home/you/.bentos/bin is not on your PATH — add it with:
export PATH="/home/you/.bentos/bin:$PATH"
bentos: next — bentos install
Then the userland:
$ bentos install
bentos-userland 0.1.5 → /home/you/.bentos/bin
installed : bentos chat-codec chat-render entity llm mem place stt tts websearch
note : bentos replaced itself — the next `bentos` you run is 0.1.5
The whole userland in one act, and the installer replaced itself while it worked. What arrives is whatever the release declares: the manifest is the registry, so there is no second list anywhere that could disagree with it. macOS and Linux install from published releases today. Windows executables are built and published for every one of those coreutils, but no bootstrap script ships in a release, so there is no installation path to copy on that platform. No date is being promised — see status.
What you have
$ bentos list
prefix: /home/you/.bentos/bin host: macos-arm64
bentos-userland 0.1.5
· bentos · chat-codec · chat-render · entity · llm
· mem · place · stt · tts · websearch
bentos list is also the drift check: it exits non-zero if what is on disk disagrees with what the release declares, if another program on your PATH shadows one of these names, or if the prefix is not on your PATH at all.
bentos update, bentos rollback and bentos self-update each take a release stream, defaulting to bentos-userland. They are published surface and their behaviour across releases is open, so this page will not tell you what they do in the indicative.
Everything below runs on a machine that has never seen an API key.
A first program
Not a hello-world and not a command reference: a journal that reindexes itself when an entry lands. It uses three of the four primitives — a place to stand in, an entity to hold durable state, an event to react to — and an ordinary pipe through an inference device to produce the content. Nine lines of shell, no daemon, no server, nothing resident.
Start in an empty directory:
$ mkdir journal && cd journal
$ place init -n journal
initialized place journal → /home/you/journal
$ entity create acme.journal
155f839b176b349416216a0e5be2490f49c18430
$ entity new acme.journal today
155f839b176b349416216a0e5be2490f49c18430
You now have a place, a class, and one instance of it — and the two shas are equal because a new instance begins at genesis. acme.journal is a Git repository the platform installed for you; today is a branch of it.
Two small scripts. The first writes an entry, by piping a prompt through a fixture device:
#!/bin/sh
# write-entry
echo 'what does a filter compose with?' | llm -d /dev/llm/fixture/echo > entry
The second is the reaction — it runs after an entry lands, and counts what is there:
#!/bin/sh
# reindex
entity read acme.journal:today:entry | wc -l > index.txt
Make both executable, arm the reaction, and take the act:
$ chmod +x write-entry reindex
$ entity on acme.journal:today entry.landed -- "$PWD/reindex"
r1
$ entity act acme.journal:today entry --say 'first entry' -- "$PWD/write-entry"
01a6e56bf7327f09e2e16b127a7e13fe72ba22a2
That sha is the act. Read the state back, and then read the file that only the reaction could have written:
$ entity read acme.journal:today:entry
echo: what does a filter compose with?
$ cat index.txt
1
$ entity log acme.journal:today
01a6e56bf7327f09e2e16b127a7e13fe72ba22a2 entry unknown 2026-08-05T12:06:17.000Z first entry
Nothing was running when you armed the reaction, and nothing is running now. The act landed, the occurrence published, a process was born to answer it, it wrote its file and exited. The log line carries the act’s sha, the noun it deposited, its author — unknown, because we did not pass --actor — the instant, and the sentence from --say, stored and never interpreted.
Point -d at /dev/llm/openai/gpt-4o-mini and write-entry does not change; the vendor is a driver, which is the kernel’s chapter. Put a while around it instead of a single act and you have an agent, which is the model’s.
Two rules that save you an afternoon
Both come from the same fact: a body does not run where you typed.
Name every command by absolute path. An act’s body runs in a private area belonging to that act:
$ entity act acme.journal:today entry -- /bin/pwd
/home/you/journal/.place/entity/acme.journal/acts/act-rylWr9
That is the design — the act writes in isolation, and the write becomes true only when it lands — and it is why write-entry above simply writes entry into its own working directory, and why the command is given as "$PWD/write-entry". A reaction’s body runs elsewhere again, in the root of the place, so a relative command in entity on resolves against the place and not against the directory you typed in. Absolute paths make the whole question disappear.
Arm a script, never a shell line. What the listener table stores is a command line, so quoting does not survive being armed: sh -c 'echo X >> flat.txt' arrives as separate arguments with the redirection among them. Put the shell work inside a file, make it executable, and arm the file — which is what the two scripts above already do.
Where to go from here
The primitives say what each of these four things is, and — the half that matters — what each one is not. The model is how whole applications are built out of them. Status is the honest table of what runs, what is designed, and what is still open.
The source is at github.com/cafe01/bentos-userland, MIT, and contributing says where an outsider has the most leverage.