Never using inheritance is pushing the dogma to the other extreme imo. The whole prefer composition over inheritance is meant to help people avoid the typical OO over use of inheritance. It doesn't mean Is-A relation doesn't/shouldn't exist. It just means when there is data, prefer using composition to give access to that data.
There will be times when you want to represent Is-A relationship - especially when you want to guarantee a specific interface/set of functions your object will have - irrespective of the under the hood details.
Notifier n = GetNotifier(backend_name);
Here what you care about is notifier providing a set of functions (sendNotification, updateNotification, removeNotification) - irrespective of what the implementation details are - whether you're using desktop notifications or SMS notifications.
There will be times when you want to represent Is-A relationship - especially when you want to guarantee a specific interface/set of functions your object will have - irrespective of the under the hood details.
Here what you care about is notifier providing a set of functions (sendNotification, updateNotification, removeNotification) - irrespective of what the implementation details are - whether you're using desktop notifications or SMS notifications.