Write (module) signatures, not (protocol) schemas

If you write a library, you'll have simpler code than if you write a standalone server, because type signatures (which describe libraries, modules and other importable pieces of code) are substantially more expressive than protocol schemas (which describe protocols for communicating with servers).

For example, a function pointer is a valid argument or return type for a function in most languages, even in C. But almost no protocol schemas support this. In more advanced languages, objects, interfaces, abstract data types, types themselves, type constructors, references to other modules, and many other constructs are valid arguments and return types. You can't express any of that in protocol schemas; this makes many tasks more complicated.

So why do people ever write servers instead of libraries?

A library can do anything that a standalone server can do. But our modern Unix-derived programming environments are slanted towards standalone servers, so some things are easier with standalone servers; hence, servers are almost always the first choice.

Nevertheless, contrary to popular belief, libraries can do anything, including: