#dependencies #language #file #call #import

app unidep

A universal dependency graph generator at either files or functions level

1 unstable release

Uses new Rust 2024

new 0.1.0 May 24, 2025

#265 in Development tools

LGPL-3.0-only

790KB

unidep

Installation

Unidep might (hopefully) support a large number of programming languages. The default installation installs everything, but it is also possible to specify the languages you are interested in to keep dependencies manageable.

Default installation

The default installation will install all currently supported languages. You can use unidep:

  • as a CLI binary:
    cargo install unidep
    
  • as a Rust library, in your Cargo.toml:
    [dependencies]
    unidep = "0.1.0"
    

Custom installation

To install only a selected subset of languages (see the list of currently supported languages):

cargo install unidep --no-default-features --features "python,rust"

Or, if you plan to use unidep as a library:

[dependencies]
unidep = { version = "0.1.0", default-features = false, features = ["python", "rust"]}

Currently supported languages

For now, there are obviously no language supported at all.
  • python
  • rust

If your favorite language is missing, feel free to contribute.

How does it work

There are two kinds of dependencies:

  • between functions (a function is calling another function)
  • between files (a file requires code stored within another file)

Dependencies between functions are straightforward, all functions calls are intercepted by the iterator, and are added as dependencies of the current functions. Note that different functions of this function tree may live in different source files - and we want to keep track of that (the same function might live in multiple files! because it can be declared multiple times and defined once).

Dependencies between files are slightly more complicated. They can be explicit, with some import or include directives. But they can also be implicit: let's say we have a file a.h declaring various functions, themselves defined in both a.c and b.c. a.h is an explicit dependency of both a.c and b.c. But a.h also implicitly depends on a.c and b.c - because the function definitions live there.


Unidep supports:

  • function (and macro) calls
  • module declarations and imports

Unidep doesn't support:

  • functions depending on global variable defined elsewhere

Obviously, unidep relies heavily on the whole tree-sitter project.

Plenty of language-specific tools already exist. Below is a small sample from some popular ones.

Language Tool
C/C++ include-what-you-use
C/C++ cpp-dependencies
C/C++ clang-include-graph
Java Jarviz
JavaScript  Madge
JavaScript dependency-cruiser
OCaml odep
Python pydeps
Rust cargo-depgraph
Python, JavaScript, PHP, Ruby code2flow
Python, Rust StackWalk
  • UniDep is a project sharing the same name, but has nothing to do with our project.

Contributing

TODO

Thanks to all (future?) contributors!

Dependencies

~6–11MB
~230K SLoC