top of page
  • How do you help companies untangle their codebases?
    We use dynamic Dependency Structure Matrices. Rearranging these without requiring recompilation helps us quickly untangle large codebase cycles. We can parse JVM and GraphViz graphs quickly; most languages support conversion of their dependency graph to GraphViz. This allows complex code to be understood in one pass in small incremental steps.
  • I can't wait! How can I untangle my code right now?
    Use for free static Dependency Structure Matrix analysis. Contact us for an access code for dynamic Dependency Structure Matrix analysis.
  • How do I find out more about Dependency Structure Matrices in general?
  • How does Dependency Structure Matrix analysis compare to other forms of static analysis?
    Static analysis tools such as mypy, pylint, SonarQube etc. typically have local scope (either line-specific or file-specific to the definition and usage of a particular syntax). Although we typically focus on the larger scale structure involving multiple files and projects, we have also used Dependency Structure Matrix analysis to rearrange code within very large individual code files so they can be understood incrementally and split easily. These tools typically don't detect issues where A uses B, B uses C and C uses A. Even in languages that prevent cycles (at the JVM module level or Python import level), this usually isn't enough to prevent multi-module cycles, cycles within large modules or cycles within large files. You were taught not to create large files, classes and functions in Computer Science 101, but what's the point if you just have many of these that all use each other and can't be understood incrementally? Often, most of a company's codebase is involved in or subject to one large fragile cycle that holds it back. If you can't safely delete or rearrange code, you most likely have this problem in some form.
  • How does compare to other Dependency Structure Matrix tools?
    We support JVM languages natively and a multitude of non-JVM languages via GraphViz. The free version of can be used immediately from any web browser that supports pop-ups and file uploads.
  • How does this all translate to results?
    Large cycles in codebases are often explain why a minority of original contributors are the only people who can meaningfully contribute to a substantial codebase. They typically internalize the 'ways things can break each other' without formalizing the dependency graph. By taking a formal approach to minimizing cycle size, you can ensure that people can easily contribute to unfamiliar parts of the codebase with confidence, because they can quickly see what each code change can break. Breaking cycles are a prerequisite for incremental testing and achieving the equivalent of Test Certified Level 3 at Google. Code that meets this level is substantially easier to modify rapidly with confidence than other code. If your code matters at all (even as a coding exercise you're submitting as part of a job interview process), seeing the topology of your code with a dynamic Dependency Structure Matrix will help! The splits that a DSM suggest usually separate concerns in ways that are already familiar to software engineers; as an example models / POJOs / schemas typically group together.
  • How does this help advanced build systems?
    High-performance build systems like bazel and buck require cycles to be split. Dependency Structure Matrices help split the inevitable bottleneck projects that remain when moving towards faster and more reproducible build and test processes. Iteration rate (build / test / review duration) and reproducibility of results are key differentiators between low and high performing engineering processes. Developers shouldn't be blocked or left wondering if their changes to unfamiliar parts of the codebase have broken anything.
  • Advanced! Pfft. Someone converted our build system to bazel and it is worse than before! How do I know these Dependency Structure Matrices are any better?
    Did they define the third-party boundary multiple times (as evidenced by more than 1 WORKSPACE file)? Fast and reproducible design principles don't help unless you follow the ideas behind them. We've seen what works and what doesn't across a wide range of scales (from sole contributors up to thousands of coordinated developers).
  • What upload formats do you support and how do I analyze them?
    .jar (JVM), .gv (GraphViz) and .dot (GraphViz) files are supported. They can be dragged'n'dropped onto the purple box in If a new tab doesn't open, ensure pop-ups are enabled and that your VPN isn't blocking uploads.
  • Which languages are supported and how do I analyze each of them?
    Native jar support: JVM languages (Java, Scala, Kotlin, Groovy etc.): Upload a .jar file to directly GraphViz support: Generate a GraphViz (.gv or .dot extension) file and upload it to, using the tools below for each language: C++: CMake --graphviz=modules.gv codeviz dependency-graph Go: modgraphviz Example: go list -f '{{.ImportPath}} {{join .Imports " "}}' all | grep "internal-package-root-substring" | sort -u | go run ../modgraphviz.go > internal-packages.gv Then drag'n'drop internal-packages.gv onto the purple box in Pulumi: pulumi stack graph Python: pyan3 1.1.1 (pyan3 1.2.0 has bugs)
bottom of page