One of the divisions in GNU Emacs people is between using Flymake , which is built into GNU Emacs and is well supported by other standard GNU Emacs packages such as Eglot , and using Flycheck . I've used Flycheck for a long time ( cf ) and recently tried using Flymake , which has given me some pragmatic opinions for my own usage.
(For non GNU Emacs people, Flymake and Flycheck both exist to present (and to some extent detect) 'diagnostics' about your code or whatever file you're editing.)
For me, Flymake and Flycheck are about as good as each other, at least in LSP based environments and Emacs Lisp. Flymake is better integrated into Eglot and can make errors more visible, Flycheck comes with more keybindings by default, and I go back and forth about how I feel about their modelines (after I diminished Flymake's verbose modeline name down to 'FlyM' and changed the colours a bit). Why I prefer Flycheck is that it's more flexible in one way that matters to me.
My particular taste with checkers is that by default I only want to see actual errors (or relatively strong style issues), but I want to have access to linters that express views I may not agree with in order to see what they say and maybe fix some things they complain about. This way I can keep my code free of real, core issues (that are reported by the error linters) and have a nice clear modeline showing '0' issues (and not have to remember how many baseline non-issues a file has), while still being able to conveniently see style issues if I want to consider them.
As far as I can tell, Flymake has no built in support for (easily) changing what sources of diagnostics it draws on. Things are just magically supposed to get it right, which is fine if they actually do but sub-optimal if they don't. One case where they don't necessarily is in Eglot, where as far as I know the normal diagnostics will only come from the LSP server you're running and will cover only what it provides. Even in cases where it's possible, changing what diagnostics you get from a LSP server isn't simple .
Perhaps because you can switch Flycheck checkers around, there are a bunch of third party Flycheck packages that support optional Go and Python style checkers (and some for other languages). Flymake has some third party checkers, but not really in the way Flycheck does (and what third party checkers it has can be rather out of date). The Flycheck situation is convenient and useful for me, because it means I can easily run (for example) golangci-lint against my Go code within the Flycheck framework with all sorts of jump to complaint support.
(There is an adapter to connect Flycheck checkers to Flymake, but as far as I know you're still left without a convenient way to pick your checker.)
Although Flycheck is my default, I've kept my Flymake configuration around and wired up some personal functions so that I can switch back and forth (either buffer locally or globally). Sometimes I flip over to Flymake to see what it says or use some of its other features.
(There's also Flycheck's comparison page with Flymake . A bunch of the differences that Flycheck lists aren't important to me, partly because I don't use GNU Emacs to edit everything in sight so the large collection of languages and configuration files that Flycheck supports aren't as important.)
PS: I'm dating this in the title because both Flymake and Flycheck have changed over time. My impression is that Flymake stagnated for a while, putting Flycheck clearly ahead in those days, but that things are more even today (especially in LSP environments, where both are getting the same diagnostics from the LSP server).