cargo tree | wc -l tends to over-count dependencies a lot because there are many very common crates.
Use grep package -F '[['package Cargo.lock | wc -l instead. This is doubly true if you pull in multiple crates using the same framework behind it, e.g. in async projects. E.g. for exa this is 45 instead of 61. For deno this turns into a 3x difference (515 vs. 1571).
Other reasons, besides what has been mentioned (vendoring being very uncommon, crates existing for common type and trait definitions, crates being generally scoped more narrowly resulting in more smaller crates), a lot of crates have additional crates for macros. Bindings often end up being a whole bunch of crates for this reason (i.e. one xyz-sys crate for the FFI bindings, plus one or more crates for a rusty wrapper and perhaps one or more crates for convenience crates). Case in point from deno's dependency tree:
Use grep package -F '[['package Cargo.lock | wc -l instead. This is doubly true if you pull in multiple crates using the same framework behind it, e.g. in async projects. E.g. for exa this is 45 instead of 61. For deno this turns into a 3x difference (515 vs. 1571).
Other reasons, besides what has been mentioned (vendoring being very uncommon, crates existing for common type and trait definitions, crates being generally scoped more narrowly resulting in more smaller crates), a lot of crates have additional crates for macros. Bindings often end up being a whole bunch of crates for this reason (i.e. one xyz-sys crate for the FFI bindings, plus one or more crates for a rusty wrapper and perhaps one or more crates for convenience crates). Case in point from deno's dependency tree: