Ok, well I don’t think that matters much that you split the html into words or parse it for some subset of strings, my answer still applies I believe. Either you do the same, and pass in a getLinks implementation as an argument (you could even let getLinks dispatch to some implementation that differs based on the environment, which wouldn’t be DI anymore but achieves a similar result). Or you just dissect your logic between pure chunks and impure chunks, and flatten your call stack so that all impure chunks are at the top in your entry function which then becomes a workflow definition for how to weave your pure and impure chunks together in what order and connecting their inputs/outputs to one another.