Should I Protect function's options

Protect everything from the package's context, unless it is explicitly meant to be set by the package's users*. It doesn't matter if the symbol is an option or not.



(* list all symbols meant for export,
   including any symbols used as options only *)


(* package code *)

With[{syms = Names["Foo`*"]},
  SetAttributes[syms, {Protected, ReadProtected}]



I agree with @Henrik that it is good practice to use strings for option names to limit name pollution (and reduce the chance of name conflicts), especially if the option will be used with a single function only.

It is true that if you use the Workbench documentation tools, then it will not be possible to have a separate documentation page for a string option. But should you have one? I prefer to document options in the doc page of the function they belong to—except when the same option is used by several functions with the very same meaning.

* Even then it's probably better to have the settable symbol protected and overload Set for it—that way you can have error checking for its value.

I always use strings as the names for the options (like "op1" instead of op1). You cannot overwrite a string. That's good! For some weird reason, you can still use the "unstringfied" version op1 as in myFunc[bla,op1->2]. Of course, myFunc[bla,"op1"->2] is also valid. So, you get safety even without Protection and still you are not forced to type many quotes.