I really like using the Hindley Millner Function Signature pattern, which is a byproduct of the functional programming culture.
Your comments end up succinctly representing the flow of data through the functional units of your app.
Take for example the below function that takes an array of functions and returns a single function:
// compose :: [Func] -> Func
const compose = (funcs) => {
// Code here
return megaFunction;
};
You can read more about it here: en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type… and here dev.stephendiehl.com/fun/006_hindley_milner.html
Beyond the above mentioned strategy, I tend to follow the pattern of whatever documentation generator I use. It depends on the language, for example, you can use YardDoc to self-document Ruby code that can be automatically parsed into a static documentation website.
You can try searching on google for "Generate documentation from comments in (Insert language here)". You should be able to find a guide that you can follow to create self-documenting code.