Bento Puts Slides in One HTML File

Bento is a Show HN project from its creator that turns a slide editor and deck into one HTML file. Developers were making web-based decks with Claude Code then needing the agent or a manual code edit for every small slide tweak. Bento is a self-contained HTML slide deck: the editor, viewer, data, animations, and shared editing live in one file. Don't make every deck an app. Keep agent-editable data obvious, and use Claude Code hooks only as a small boundary when the file also contains code.
Open the file, edit the deck, keep the app
Bento’s pitch is wonderfully literal. You open one HTML file in a browser, edit the deck there, present from the same file, and keep working without an install or cloud login.
The creator described the default deck as roughly 560 KB and able to work offline after you have the file. That matters because a deck becomes something you can email, commit, grep, diff, and archive without a service account hanging off the side.
The clever part is the split inside the file. Near the top, Bento keeps a plain JSON block for slide data. The app itself is bundled separately, reportedly as a base64 blob loaded by a small shim.
That split is why developers paid attention. The JSON gives Claude Code or a human a sane edit target. The bundled app keeps the deck portable.
Watch for pretending the blob does not matter. Base64 makes people nervous, and fairly so. If your repo requires every shipped line to be reviewed as normal source, a bundled app blob is a policy decision, not just a packaging trick.
Notice why developers liked it
The story landed because many engineering decks have quietly become frontend projects. A design review deck might use React components, Mermaid diagrams, screenshots, motion, and a tiny amount of state. That is great until changing one bullet means reopening the harness and asking an agent to patch JSX.
Bento removes that loop for small edits. The agent can help build the initial material, but the presenter can still fix a typo, move a slide, or change a label in the browser.
There is also a mood here. Developers are tired of renting every artifact they create. A deck that is “just a file” feels boring in the best way.
The honest objection was animations. Someone wanted one switch to turn all motion off, and that is the right kind of complaint. Slide tools used in real rooms need accessibility and calm-mode controls, not just impressive transitions.
Try Bento when the deck is a document
Bento is a good fit when the deck itself is the thing you want to preserve. Think architecture notes, a demo script, an investor update, a workshop handout, or a design walkthrough that should still open in five years.
It is less compelling when the deck is really a product surface. If you need auth, analytics, complex embeds, private data access, or strict supply-chain review, a single bundled file may be more cute than useful.
A practical test is simple: could you commit the file under docs/ and feel okay if someone opened it on a plane? If yes, Bento is worth a try. If no, keep the deck closer to your normal app stack.
| Fit | Not fit |
|---|---|
| A repo-owned deck with public or non-sensitive content | A deck that must fetch private data at runtime |
| A presenter needs browser editing without a build step | A compliance process must review every bundled byte as source |
| Claude Code can safely patch slide JSON | The agent would need to rewrite the embedded app blob |
| Offline viewing matters | Centralized permissions and audit logs matter more |
Put a hook boundary around agent edits
In a Claude Code workflow, the safe experiment is narrow: let the agent edit Bento’s slide data, not the embedded application. That keeps the workflow pleasant without asking a coding agent to rewrite a portable app container by accident.
The official Claude Code hooks documentation is the place to check exact event behavior before you wire this into a real repo. In practice, the relevant idea is a PreToolUse boundary for file-editing tools: if the target is a Bento HTML file and the proposed edit appears to touch the app blob, stop the edit and tell the agent to work in the JSON block instead.
This is a convention, not a security system. It pairs well with a short repo note, a small review habit, and whatever MCP permissions you already use for private systems. For broader patterns, keep a lightweight page of Claude Code team conventions instead of hiding these rules in chat history.
One useful pattern is to review the file diff like a receipt. If the JSON changed and the app blob did not, the change is probably what you asked for. If a huge base64 region changed, pause and inspect before merging.
That same “make the boundary visible” habit shows up in Claude Code release work around explicit reviews; see Claude Code 2.1.215 Makes Reviews Explicit for the related review angle.
Copy this hook boundary before agent edits
Use this as a starting point, not as a universal rule. The marker patterns are intentionally conservative. Inspect a real Bento file first, then tune the grep pattern to the actual boundary between slide JSON and bundled app code.
# .claude/hooks/bento-slide-data-only.sh
#!/usr/bin/env bash
set -euo pipefail
payload="$(cat)"
file="$(jq -r '.tool_input.file_path // empty' <<<"$payload")"
# Only guard checked-in Bento decks.
[[ "$file" == *.bento.html ]] || exit 0
proposed_text="$(jq -r '
[
.tool_input.new_string?,
.tool_input.content?,
(.tool_input.edits[]?.new_string?)
] | map(select(. != null)) | join("\n")
' <<<"$payload")"
# Block edits that look like they rewrite the embedded app payload.
if grep -Eiq 'base64,|atob\(|BENTO_APP_BLOB|application/octet-stream' <<<"$proposed_text"; then
echo "Bento deck edits should change slide JSON only. Do not rewrite the embedded app blob." >&2
exit 2
fi
exit 0
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/bento-slide-data-only.sh"
}
]
}
]
}
}
Before using it, install jq, make the script executable, and test it on a throwaway deck. Ask Claude Code to change one slide title, then ask it to “minify the whole HTML file” and confirm the second edit is blocked.
Don't make the hook too clever. A hook should enforce a boring boundary. Put the detailed instruction in your prompt or repo memory; put the hard stop in the hook.