DeriveWhen
DebugAlmost always — enables {:?} printing
CloneWhen copying the value makes semantic sense
CopyWhen type is small, stack-only, and implicit copy is fine (requires Clone)
PartialEq / EqWhen equality comparison makes sense
PartialOrd / OrdWhen ordering makes sense
HashWhen used as HashMap/HashSet key (requires Eq)
DefaultWhen a sensible zero/empty value exists
Serialize / DeserializeWhen crossing API/file boundaries (via serde)

Practical default: slap #[derive(Debug, Clone)] on almost everything. Add the rest as needed.

Not using common derives may cause problems to our crate users due to orphan rules - we cannot implement external traits (derives in this case) to external structs (our crate), so the user of our crate must do some workarounds such as using wrapper structs (newtype pattern).