- The churn caused by breaking changes in minor versions used to be annoyingly high.
- Slick looks neat at first but caused a lot of friction when used by less experienced developers.
- The fact Akka is in your dependency tree encourages people to reach for it and raw actors are usually a bad choice. Akka streams work well for websockets and SSE but it's another footgun.
Additionally:
- It was in state of semi-abandonment for several years before Lightbend gave the project to the community. Even though there are/were big companies deploying Play apps at scale, for instance Apple.
- The introduction of Guice (in 2.4 afaik) was a terrible mistake, completely unnecessary and at odds with the Scala philosophy. Sure you can not use it, or use something else (like macwire) but defaults matter.
- Play-JSON depends on Jackson which is annoying in the JVM world, causing binary compatibility issues when you have diamond dependencies.
- Standard library Futures are not so nice when you've experienced anything else (Scalaz Task, Cats IO, ZIO, even Twitter Future...)
- Code generation from routes files is an odd choice when Scala has always been expressive and DSL friendly.
- Swagger/OpenAPI integration is brittle.
I've personally used Tapir since 2019 and couldn't be happier. All Play apps still running at my company are being abandoned or replaced by Spring/Java projects.