I used to also avoid leaking mutation in public APIs, but at one point I realized my literal job was to write APIs that mutate state or do side effects, just over HTTP.
Imperative core, functional shell is my favorite design principle. Many algorithms are dramatically simpler to implement with mutable state (for example, depth first search in graphs with cycles). Just don’t leak the mutation into your public API