Not that long ago I wrote an entry on my views on Flymake and Flycheck in GNU Emacs , when Flycheck v36 was the latest release and my impression was that there hadn't been deep changes in Flycheck for a while. To summarize my views, the two were basically equal but Flymake was a bit better if you only used Eglot while Flycheck gave you more flexibility, especially if you weren't using a LSP client. All of that changed in Flycheck 38 (and Flycheck 39), which added a bunch of exciting and important features ( cf ). Now, my view is that you should pick Flycheck if you're at all on the fence.
Flymake is (still) perfectly okay when you're using a LSP client and for a few languages even without one, and it has the advantage of being built in to GNU Emacs (which means you don't need to obtain and configure it in order to get things to basically work, at least in Eglot ). But Flycheck is now more or less better at everything. It has good built in Eglot integration (including features Flymake currently lacks), the new annotation mode can surface diagnostics just as well as Flymake, and Flycheck has pulled ahead on useful general features , including LSP server based diagnostics for people who don't want to use a LSP client . There are only a few small things left where Flymake (in Eglot) is ahead of Flycheck in features, and Flycheck still has its better support for multiple checkers and switching between them.
(As a quick tip to myself, if I want to switch back and forth between LSP provided diagnostics and native Flycheck checkers in an Eglot buffer, the easy thing to do is to turn
flycheck-eglot-mode
on or off. This is most useful in Python, where for me the native checkers are more linters and the LSP diagnostics are real error checkers.)
This isn't quite the situation with Eglot versus lsp-mode , where I think you'll wind up using Eglot sooner or later because it's better integrated into the overall GNU Emacs ecosystem. Instead I think Flycheck has simply become better, and it's likely to stay that way because it has the advantage of being able to make new releases faster than Flymake can, because Flymake releases are part of GNU Emacs releases and those only happen every so often. Sooner or later you're probably going to want something that Flycheck has and Flymake doesn't.
(This includes in Emacs Lisp, where I don't think Flymake has an equivalent of Flycheck's
flycheck-emacs-lisp-initialize-packages
.)
This big Flycheck improvement has caused me to drop a number of my GNU Emacs packages . Gone are flycheck-eglot (now a native feature), flycheck-inline (also now a native feature), flyover , and sideline along with all of its associated packages. In theory the latter two aren't completely obsolete; flyover works in Flymake as well, and sideline can expose LSP code actions. But in practice I wasn't using them and I decided to do some summer configuration cleaning.
(I haven't yet gone so far as to drop all of my Flymake configuration, partly because I want to be able to see what a native Flymake experience is like for comparison and debugging purposes.)
PS: Flycheck staying ahead of Flymake in the future isn't guaranteed. Flymake could have a renaissance that improves it rapidly (the recent Flycheck improvements might encourage that), and Flycheck could go quiet again. You can't predict the long term future of an open source project, especially in the world of GNU Emacs packages (and GNU Emacs itself).