I have been playing around with Vert.x framework for over three years now. I started by trying it out for some side projects like Throo and liked it so much that I introduced it in Myntra as a viable contender for the asynchronous-framework-of-choice position next to Play! Framework. Having used it to build multiple high-scale services in production and several side-projects, I have no hesitation in saying that this is my favourite framework for building any kind of Java application.
Modular, with lots of modules
The usual understanding of a framework versus a library is that framework calls user code and user code calls libraries. Vert.x is not a framework in this sense of the word. It comes as a large number of independent modules with vertx-core being the only critical, shared element among them. It is essentially a set of libraries all of which share the same design principles and play well with each other. But they do not HAVE to be used together. We can pick the circuit-breaker and RabbitMQ connector, drop it into an existing Spring based Java application, and things will work perfectly fine. There is no all-or-nothing, and this makes de-risks the framework choice by making it it gradual and reversible.
The extremely modular nature if the framework make it easy to gradually try-out different parts of the framework and get used to the shared design constructs among them all. Then we can decide how much of our system should be built using Vert.x and where we need other libraries and frameworks.
And there are a LOT of modules. Check them out here - Vert.x folks have all the toys!
Asynchronous from the ground-up
Like node.js, Vert.x is built around the concept of an event loop and is asynchronous from ground up. This means that the default mental model for writing code in Vert.x is asynchronous (we can anyway write synchronous code in core Java, so why would we use a framework for that). Everything in Vert.x revolves around not blocking the event loop, which forces developers to maximize the application's scalability by fully embracing the async programming paradigm.
Writing synchronous code is possible via blockingHandler etc but it feels like an afterthought.
Really Fast and Light
Because Vert.x is fundamentally asynchronous and can therefore scale pretty well out-of-the-box, there isn't a whole lot of multi-threading going on in its internals. This makes the system extremely efficient by removing much of the thread synchronization overhead which is a performance killer in so many other tools. Vert.x is very, very fast. Additionally, it has very low intrinsic runtime memory footprint. The application memory usage remains very low and stable.
Vert.x has a small set of concepts that we need to learn to work with it. Everything is a handler, everything is asynchronous and backed by an event loop, etc. There are a limited number of constructs, and they behave the same everywhere. This comes from building an up-front, coherent design philosophy that can connect so many modules together seamlessly.
This concise dictionary of concepts lends itself to very quick onboarding and a very consistent programming style. In fact, I was recently struck by how similar some of my Vert.x code looked to Golang code (Golang is very popular for its small but expressive language feature set). This allows developers to easily get accustomed to moving around in Vert.x based code.
There are many other cool things about Vert.x like its polyglot nature but I did use them a lot so do not want to comment on them.
What I wish was better
An all-in option
While the un-opinionated, non-compulsive nature of Vert.x was a great thing to begin with, I was looking for a more all-in, all-Vert.x option once my mind was made up about the framework. Something like Play! framework or Spring Boot which would abstract the best practices of the framework under conventions and let me get on with my actual work super-quick.
I didn't find any compelling options at the time, so I am currently working on building one. QVertx is intended to be the quick-start service template for the Vert.x world. I have also seen some work around running Vert.x event loop inside Spring Boot itself, but it looks early stage right now.
Better support on serialization formats
Vert.x framework seems a little too tied to JSON as a serialization format, and working with XML and other formats proved to be a bit of a challenge. It can be done, of course, but I wish it was a little more straight forward.