Making an app for Bohm

Making the app in Bohm itself? You do not need this — Bohm uses it for you. Making it in another AI chat? Paste this text in together with what you want the app to do.

# When you make an app to run in Bohm

> Contract 3 — the edition of this text. When something new becomes possible, the edition goes up and the change is marked "New".

Give this text together with your request, and the app you get will run in Bohm as it is. Bohm is a tool for bringing HTML apps onto a PC and using them there.

- **One file.** Put the screens, styles and scripts all in a single HTML file. Other files placed next to it (images, script files) are not read.
- **Save with `localStorage`.** Bohm keeps `localStorage` safe on this PC (it stays when the app is reopened, and when it is replaced with a new version). `sessionStorage`, IndexedDB and cookies do not stay. Do not save to online databases such as Firebase or Supabase either — apps cannot reach outside servers, so what people enter would not be kept. For several kinds of records, split them across keys as JSON.
- **There is no server.** Do not make server calls such as `/api/...`, or sign-up and sign-in screens. The app is used only by the person at this PC, and a password inside the app protects nothing.
- **Data from the internet cannot be used.** Outside services such as weather or exchange rates cannot be reached (Bohm blocks an app's outside connections, and it is also used where there is no internet) — let people type or paste the values they need (web pages people look at can be received as below). Libraries from a CDN are fetched once when the app is added, but code written directly in the file is safest.
- **To receive web pages, declare a `share_target` in a manifest.** To let people send the page they are looking at in Bohm to this app, put `<link rel="manifest" href='data:application/manifest+json,{"name":"App name","share_target":{"action":"/","params":{"title":"title","url":"url"}}}'>` in the `<head>`. When a page arrives, the app opens with `bohm_page` in its address — read `{ url, title, text, html, lang, byline }` with `fetch('/__bohm/pages/' + id)` (`html` is the readable part as Bohm cleaned it, so it can be shown with `innerHTML`), and every page received with `fetch('/__bohm/pages')`, at any time. Bohm keeps the pages, so keep in `localStorage` only what the app adds (read marks, tags and so on), keyed by the page `id`.
- **If you need AI, call the provider's API as usual.** Call the OpenAI, Anthropic or Gemini API the normal way, but do not put a key in the code or make a field for entering one — Bohm attaches the key (or the AI model on this PC) for you.
- **"New" Do not hold AI calls back on `navigator.onLine`.** The AI can answer when there is no internet connection (it may run on this PC or on the same network). Do not check the connection before calling; handle a failed call instead.
- **Report errors with `console.error`.** Bohm collects the app's errors and shows them. There is no need to keep a log separately.
- **"New" Keep hidden elements hidden.** When a style rule gives an element with the `hidden` attribute a `display` (a dialog's `display: flex`, say), it shows anyway — and if it is a layer over the whole window, it takes every click and the app stops without an error. Put `[hidden] { display: none !important; }` in the stylesheet.
- **Write the screen's elements in the markup.** Later, people point at one part of the screen and say "change this" — elements written in the HTML are changed more reliably than ones generated entirely by script.