It sounds so simple: Magento 2 has a Developer Mode and a Production Mode. And the Developer Mode is there for development, so do not enable it in production. But why?
The modes of operandi
There are 3 deployment modes aka application modes: Production, Developer and Default. I'm assuming that this sounds like really basic stuff, when you're reading this - my writing is not indended for newbies. The modes differ in various ways, among which also the way that they log exceptions (to the screen or to a file), some other debugging settings and code deployment. Code deployment is actually split up in two parts: PHP code compilation (following the DI configuration) and static view file caching.
Because code compilation and static view file copying is done statically with the Production Mode, this leads in general to a better performance, because PHP needs to do less things. Classes are not generated on-the-fly anymore but generated before-hand to the
generated/ folder. And files are copied into the
pub/ beforehand, so that they don't need to be resolved on request time. This is nice.
Why use the Developer Mode in production?
But what if this additional performance that the Production Mode gives is less important than the ease of use of the Developer Mode? Quickly adding or removing a module is possible with the Developer Mode, but the Production Mode requires minutes of deployment for such a simple change.
And even though the PHP execution will definitely be slower in the Developer Mode, some merchants don't require that additional performance: Perhaps most pages are cached in a Full Page Cache anyway? Perhaps the frontend performance is better improved with Hyvä? Perhaps the performance is less of an issue? Ok, this sounds a bit sarcastic, because in general, more performance is always good. But at what price?
To me, the real issue with the right mode is not the performance bit, even though it is used by many as the main selling point of having the Production Mode enabled in production. No, to me, the other features of the Developer Mode are a problem: Some debugging information as added to HTTP headers, some errors end up on the frontend, but most importantly, the exceptions are normally printed with a full stack trace.
All in all, this debugging information could be vital when exploiting security issues, so it is helping the bad guys. And assuming that errors can occur in Magento :o this is an unwanted feature in production.
Extensions that check for the Developer Mode
Perhaps this could be simply solved with a simple module that overrides the exception handler to log things instead of writing things to HTML. I've done a similar thing in that past with the Yireo Whoops module, so this is definitely possible. But there is a catch.
It is not only the core features of the Developer Mode that you need to worry about. Other third party modules were also written in mind with the fact that the Developer Mode is for development only. For instance, my own refactored Yireo GoogleTagManager2 v3 adds all kinds of logging when logging is enabled and the Developer Mode is active. Shortly put, with the Developer Mode, you don't know what kind of debugging behaviour is going to show up on the frontend. And if you start getting to the bottom of this, you might as well just use the Production Mode only in production.
Ok, so what about the Default Mode?
What about the other mode - the Default Mode? Well, first of all, let me say that when I explain to students what the modes are about, I always explain the Default Mode is not to be used because it is confusing. Let me explain why it is confusing.
According to the docs, there is a concept called static view file caching, which is disabled in the Developer Mode but enabled in the Default Mode and Production Mode. Using the command
setup:static-content:deploy you can generate this cache, which copies files from all of the place to
pub/. In the Developer Mode, files are not being copied, but being symlinked instead. Fun fact, in the Default Mode of today, files are also being symlinked, in other words, the docs are wrong.
Next, debugging output is hidden with the Default Mode. And finally the code compilation is still active, meaning that classes are generated on the fly. In short, the Default Mode is the Developer Mode minus debugging. Or, the Default Mode is the Production Mode with more flexibility and less performance.
The Default Mode, the new Developer Mode for production
Whenever I meet a merchant that runs a shop in Developer Mode, I'm keen to slap that person in the face. But sometimes there are reasons to choose for this lesser option: Maybe not enough budget for a complex deployment procedure? And yes, I think that more performance could lead to more revenue, which leads to more budget. But the main point is that there might be reasons to run in Developer Mode. But now, knowing the above, let's agree that running the Default Mode in production is a better option than running the Developer Mode in production.
And if you like performance, run the Production Mode in production.