Well, since you mentioned that "nowadays there is a hype about the Composition over inheritance" I suppose that you are talking from the frontend and especially JavaScript point of view.
JavaScript never had, doesn't has and will never have a classical OOP, simply, because it is really not needed. JavaScript per design was and still is a simple language. Unfortunately, many people made JS feel too bad and complicated last years.
Answering your question from the JavaScript point of view - yes, OOP in JS is very bad, it was a weak language from the beginning and had an absolutely different design and use-case.
First of all, I (and many other great JS engineers and architects) would recommend avoiding using "class" syntactic sugar in ES6 at all because it only added more complexity and didn't solved any problem, moreover, this new class feature is confusing for people who don't know JS well and it also is very bad implemented, for example, you can't define properties at all, lolwhut, and they called it class, rly? When I need to make some properties readonly, writable, configurable I still need to use Object/prototype syntax, omg. All those "OOP" features in JS were implemented only to make language more popular because there are so many people around the world who don't know the main secret in the software engineering:
Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function.
That is also a reason why JS became so complicated last years, just all that backenders and Java-fanboys came into the frontend and they can't imagine that it is absolutely possible to write a whole codebase without a single class.
After working with JS for long time now I also had to train myself and change my mindset. You can't use any language without understanding it and its culture first. You will never become a professional English speaker if you will keep following Chinese languages rules, for example, and vice versa. People also should learn JavaScript only within it's main use-case and environment - browser and Web APIs.
So, simplest approach I (and many others) found is just using Composition over Inheritance, where everything is just a set of pure functions and whenever you need something a bit complicated, you just combine those primitives together. This gives you maximum simplicity and flexibility and I call it a Lego principle. You have a lot of ready small details, just pick ones you need and you are ready-to-go. Apart from the useless "class" syntax ES6 introduced the new most powerful feature of the language - Object.assign()
I wrote an article Vanilla JavaScript Components with different Object.assign() examples and use-cases. Probably, there is no true composition, but you may pass many objects to Object.assign(). For example, you may have simple object which adds accessibility to your component, another simple object deals with attributes, and you now may easily combine them.
const Button = Object.assign({}, AccessibleComponent, UIComponent, EventsComponent, {
...
});
There is also no inheritance because it really introduces only needless complexity and a Gorilla-Banana problem. You may change the original object or you may create a new object and assign to it all the properties and methods of the one or more source objects.
In many OOP languages you also can't do a multi-inheritance, you will have a single instance problem which requires to use a Singleton/Facade pattern, you will need to use "new" a lot, and many other problems you may face.
Pro JavaScript OOP takeaways:
I really very miss now that simplicity and flexibility of JavaScript in the other languages.
However, answering your question from the Software engineering point of view - of course NO, OOP is not about classes, OOP is about good design and primarily SOLID principles and every software engineer should know and follow them.
At the end there is no general solution or style. Combining everything together in a smart way is a best approach.