☕ Today I Learned

Small things, worth knowing.

One idea, a little code, no preamble. The kind of thing you wish someone had told you before you spent an afternoon on it. New ones get added to the top.

AI

Estimate tokens without calling an API

Token counts drive cost, context limits, and truncation. You can ballpark them with arithmetic.

For English text, one token is roughly four characters, or about three quarters of a word. That is close enough to answer the only question that usually matters before you send a request: will this fit?

const estTokens = (s) => Math.ceil(s.length / 4);

Use it to guard a request, trim context, or warn a user before they paste a novel. When you need the exact number, run the model's real tokenizer, which our Token Counter does in your browser.

AI

Make a model return JSON you can actually trust

Asking for JSON in the prompt works until one stray sentence breaks your parser. There is a better way.

Telling a model to "reply in JSON" is a hope, not a guarantee. The reliable approach is structured outputs: you hand the API a JSON Schema and the model is constrained to match it, field for field.

response_format: {
  type: "json_schema",
  json_schema: { name: "extract", schema: { /* your schema */ } }
}

That is the difference between parsing whatever came back and getting exactly the shape you asked for. Build a schema for OpenAI, Anthropic, or Gemini with the Structured Output Builder.

Coding

Stream a model response in the browser

Streaming feels instant because you render tokens as they arrive instead of waiting for the whole reply.

The pattern is a fetch whose body you read in a loop, decoding chunks as they land:

const res = await fetch(url, { method: "POST", body });
const reader = res.body.getReader();
const dec = new TextDecoder();
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  render(dec.decode(value));
}

Most LLM APIs stream as Server-Sent Events, so each chunk is one or more data: lines you split on newlines and parse. The user sees the first words in well under a second, which is most of why streaming feels fast.

Coding

Stop leaking your API key

The two fastest ways to leak a key: put it in front-end code, or commit it. Both are avoidable.

An API key in client-side JavaScript is visible to anyone who opens dev tools, so calls that need a secret key belong on a server. For everything else, two habits keep keys out of git:

# .gitignore
.env
.env.local

Keep keys in a .env file your code reads at runtime, and make sure .env is ignored before the first commit. If a key ever reaches a public repo, rotate it right away. Already committed? .gitignore will not untrack it; run git rm --cached .env first.

More depth in the field notes and the dictionary, or drill the terms with flashcards.