When you execute a command like NotebookWrite[obj,data] the actual operation of inserting data into your notebook is performed in the front end. Normally, however, the kernel is needed in order to evaluate the original command, and to construct the appropriate request to send to the front end. But it turns out that the front end is set up to execute a limited collection of commands directly, without ever involving the kernel.
|NotebookWrite[obj,data]||version of NotebookWrite to be executed in the kernel|
|FrontEnd`NotebookWrite[obj,data]||version of NotebookWrite to be executed directly in the front end|
The basic way that the Wolfram Language distinguishes between commands to be executed in the kernel and to be executed directly in the front end is by using contexts. The kernel commands are in the usual context, but the front end commands are in the context.
|FrontEndExecute[expr]||send expr to be executed in the front end|
If you write sophisticated programs for manipulating notebooks, then you will have no choice but to execute these programs primarily in the kernel. But for the kinds of operations typically performed by simple buttons, you may find that it is possible to execute all the commands you need directly in the front end—without the kernel even needing to be running.