It’s not possible, and yes it’s by design. A Typst document can not choose to write to any files; it’s only the compiler writing content to the output file(s). The closest you can get is separately invoking typst query to get data other than your actual rendered document out of your code.
You could then do something like this:
- create a file
doc-state.jsonwith content{"count":0} - create your document
main.typwith content like#let doc-state = json("doc-state.json") #(doc-state.count += 1) #metadata(doc-state) <doc-state> #doc-state.count - whenever you compile your document, use this script
# don't write directly to `doc-state.json` because the # file would be truncated before compilation! typst query main.typ '<doc-state>' --one --field value > doc-state.json.tmp # replace the json file with the temporary one mv doc-state.json.tmp doc-state.json # compile after incrementing typst compile main.typ
… obviously, with all the work and already having to use a script, it’s easier to do the scripting not in Typst, but that’s what you could do with Typst.