In fact from a peek at the source, the NgbModal class is built on a NgbModalWindow class which acts much like react-bootstrap's modal. So, ng-bootstrap builds the service based version on a component based version. If either library can be accused of bloat it ng-bootstrap for including the serviced based version when I might just want to use the NgbModalWindow directly. (Its not in the documentation, so I wouldn't actually use NgbModalWidnow directly in practice, even if I'd want to.)
Now, I've drunk the react cool-aid, so take my opionion with salt. But in my assesment while modals can be somewhat awkward in the declarative style, they aren't awkward enough to make me break my rule of avoiding imperative apis.
With component-based modals, you end up with bad APIs for these use cases, as well as less control over your state.
Yes, if you build a component based api that supports multiple modals, resuing backdrops, lifecycle hooks, that api would suck and be a real pain to build a service version on top of.
A React component should not be trying to do all that, but merely produce the appropriate HTML for a modal dialog. That produced HTML can equally be used to build one-off "are you sure?" dialogs, a modal service, or what have you.
ng-bootstrap avoids problematic apis such as component-based modals, and makes use of the much more natural service-based approach to allow developers maximum flexibility. If a developer prefers a component-based modal, a developer can very easily build a lightweight component on top of it. However, having poor design built into such a third party library that is meant to be used for a large variety of cases is a terrible experience for developers, speaking as a consumer and as a library maintainer.
Extensibility is the key here, and we maximize for that while keeping the library as small as possible - bloat is bad, and that shouldn't be the default in general.