If you don’t want to go with classes, not exporting a value or a function from a module is almost the same. The rest can be done with closures.
When looking through npm modules, there still seems to be a variety of approaches.
Deno has some ideas though:
> Don’t import any symbol with an underscore prefix: export function _baz() {}.
> Don’t link to / import any module whose path […] Has a name or parent with an underscore prefix: _foo.ts, _util/bar.ts.
https://deno.land/std@0.204.0
When looking through npm modules, there still seems to be a variety of approaches.