Understanding when to use environment variables (particularly for talking to other services in a system) vs. options or feature flags isn't always the most clear separation even for some experienced developers.
I can say on the config changing... for myself, usually only load at startup in a containerized service, or loaded via script from config/api service at startup for web-client.
What I'm using is pretty much wrapped around this: https://www.npmjs.com/package/@tracker1/config-merge
Supports rollup merging a configuration project including support for multiple language/strings variations. I no longer use it out of the box cli, but am using the library directly either in the api or a dedicated config service. Mostly configuration options as the software I work on gets deployed to different clients with slightly varying configurations.
I also inject CLIENT_* environment variables as part of a script output, that is the first script loaded into the web page, with a `__BASE__` global variable... in the application, I have a base.js that will do some normalization for access/testing, and also a language context in react that will set the current language/localization strings for use in the application.
I wish I could share more than the base library... trying to convince work to let me publish the config service and a docker image for said service...