Ask HN: Why aren't code diagram generating tools more common?
When I'm trying to get familiar with a new codebase it often takes me a long time to build a proper mental model of the whole system. Even with my own projects, it's easy to lose track of all the components and their interactions since they're constantly changing, and making hand-drawn diagrams is time consuming.
So my questions are:
- Why isn't diagram generation automated as part of the build process (UML or otherwise)?
- Why aren't code visualization tools more popular? The options out there seem outdated
- Would you want to use these tools? What would be your ideal tool?
Edit: looks like this is a duplicate question https://news.ycombinator.com/item?id=31569646
I can't delete it so feel free to discuss more
111 comments
[ 0.74 ms ] story [ 173 ms ] threadOne reason it is slower is that it is is difficult to create a map like diagram where you zoom in to get greater detail.
But more seriously, it depends on how complex the system is and how it’s modelled. The case I was working with then transferred excellently to such diagrams (shallow and deep inheritance, and other forms of composition and linkage, with every box a link) and key-value property sheets about the types and the likes, but I don’t think I’ve encountered another system where anything even vaguely like that would work particularly well.
A visualization can be helpful as an artifact for non-technical colleagues, but I always end up hand-rolling those diagrams to highlight a specific aspect of the system and hide irrelevant features.
I find creation of a sequence diagram with class instances as columns and method names as arrows can help visualise things.
For instance, I frequently build small paper diagrams of different code paths through a component and nearly always find leaky abstractions, mixed layers of abstractions, weird cyclical dependencies, etc. etc. and there really is no clear way to diagram this. Instead, you sort of have to make judgements and assumptions to make the diagram concise and understandable; the sort of decisions that machines just aren't that good at.
On the other side, when code is simple and easy to follow then the pay off of building a diagram just isn't there.
Exactly. I've found that there is no perfect tool and I'm closing in on 40 years of writing software. I use a blend of UML, IE (James Martin's Information Engineering), etc. Anything that makes it "easy-to-grok". Draw.io generally does what I want it to do; there is no feedback loop back to the codebase. It's really just to help onboard new helping hands.
I feel that people have just embraced Agile blindly and simply forgot about basic modelling.
Ultimately, you just create and endless amount of complex work that keeps developers continuously busy. On the bright side there's a never ending amount of tedious work wrestling systems back into some manageable form, on the downside that work is miserable, in my opinion because much of it can be removed whth proper planning. At some point, expectations eventually meet reality no matter how many developers management burns through, at some point it's clearly not an issue with technology, it's an issue with approach and project management. By that time the organization has had enough turnover in those above and below those pushing agile that those issues too can be hand waived away and the cycle repeats.
Very Good Point!
If you only look at things piecemeal and never holistically, the need for modeling and corresponding tools decreases.
To answer your question, people do use various tools to extract Class Hierarchies, Call Graphs, Cross-Reference listing etc. The other HN thread that you have linked to contains some details. Lots of people do use them. You can easily add Doxygen/CFlow etc. to your make files to generate the diagrams during every build. The key thing for usage is that do not try to comprehend the entire system as a whole (all but impossible for large systems) but localize your study to a module at a time. Once you have the different pieces mapped out, you can combine them by hand.
PS: Came across the book Software Visualization - Visualizing the Structure, Behaviour and Evolution of Software by Stephan Diehl which seems to provide a good survey of the field.
https://docs.microsoft.com/en-us/visualstudio/modeling/map-d...
In many cases it might really be faster and easier to just diagram things out with a pad of paper and a pencil compared to setting up a tool like this and getting all the parts working correctly without any bugs.
That said, a virtual reality 3D tool for visualizing code base dependencies, internal structure, what parts call what other parts, internal exception handling etc. would be pretty cool. Maybe it's an area where AI machine learning could do something.
With a manually constructed diagram, I have leverage to handwave irrelevant details away.
Perhaps to compare with documentation: it's easy to automatically describe things like types, and maybe callgraphs, but there's value in having prose which explains details about the interface which the program's type doesn't reveal. - With diagrams to visualise a system, the significance (or incidental nature) of the relationships may be hard to pick automatically.
Most of a system is either uninteresting or trivial. You need someone to tell you where the interesting part is.
As someone who is not a very visual person at all, I found it really nice to use to make my design docs more comprehensible to visual learners. I've gotten good feedback about designs every time I've used the tool.
The closest I found that solves this problem is https://c4model.com/ but you still need the code to turn your code into these markups. Can this be well inferred from code alone without framework specific interpreters? I doubt it.
And then you still need a frontend to zoom and navigate the ridiculous amount of hierarchy found within any modern software architecture, e.g microservices.
It also doesn't help microservices patterns also prescribe that you don't share repositories or code. So now you also need to pattern match untyped references across these codebases.
This is a lot of convention and tooling that I'm not sure exists.
Edit: and this is before even getting into version control and reconciling the target->as-is iterative loop.
It’s better to generate a diagram as needed than to archive an outdated artifact that could lead to confusion.
At the moment, codeatlas is just the static gallery, but we're only a few weekends away from releasing a Github action that deploys this diagram on github pages for your own repos - if you're interested, feel free to watch this repo: https://github.com/codeatlasHQ/codebase-visualizer-action
OP, how close is this to what you had in mind in your question?
EDIT: fixed broken links :o
Diagrams are sometimes unnecessary overhead early in a project. Sometimes I’ve used them and seen other people use them for initial design planning, especially if management needs to be involved or approve the plans & schedule. But by a year later, the design has grown and changed, and everyone on board is so familiar with the code, but also so pressed for time and feature delivery, that making diagrams doesn’t make sense: nobody involved at this point needs them. Two years later, when the code is getting complicated and slowing down, and you’re onboarding some new people, that’s when it might help to sketch the flow of code.
FWIW, sometimes a good profiling tool will show you and let you explore call stacks, call graphs, execution charts, etc. I often reach for a profiler when I’m new to a codebase. Flame charts are a fave of mine. You can find flame charts in Chrome’s debug tools, or in compiled language profilers like vtune or valgrind. Here’s a decent article on how to use them https://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html
Another issue is that well designed code bases diagram themselves by their module structure, while diagrams for poorly designed code bases may not help understand them at all. When code has too many side effects, or things are poorly or misleadingly named, when class boundaries aren’t well defined or the code has a lot of spaghetti, diagrams might not really help.
IMO two things worth doing are: get a mentor in any new codebase any time you can, and 2) start building your own arsenal of code diagramming tools, rather than wondering why or waiting for others to do it. Demonstrate the value of diagramming code to people around you and see if you can get it to catch on.
IMO there’s no real substitute for getting the design explained by the people who designed it. (Of course this isn’t always possible, but when it is, take advantage.) Automated tools can never prioritize the explanation nor summarize what parts are critical or tricky vs what parts are incidental or trivial, and they can’t tell you which parts should be redesigned because they were slapdash vs which parts look ugly to a newbie but have a long list of hard to see requirements, and touching things should be done with extreme care. Good diagrams are very helpful, but best used as a supplement to in-person stories, in my opinion.
People do want it (contrary to the common HN refrain of “well, I don’t want it so clearly nobody wants it”). We’ve had customers where I work specifically ask for these kinds of tools. They’re just harder than they seem to write, not only for the parsing reason I mention above. For many codebases you see a giant ball of spaghetti if you look at the full graph, or the layout algorithm gives you something gigantic and hard to browse. That’s a deficiency in graph visualization tools: again, a hard problem with little good tooling out there.
I’d love to see more work in this area since there do exist people who see value in it, contrary to the skeptics.
What you need is the ability to filter the graph. Narwhal and the nx mono-repo toolset has a pretty cool dependency graph feature built in. Here's a video of how they use it:
https://youtu.be/KTGKpoiLE0k?t=253
But not everyone thinks about designs as 2-D pictures. I'd argue there's selection pressure that favors programmers being good spellers and symbol-manipulators. Some people find it intuitive to think of concepts as boxes and the relationships between those concepts as lines. Or maybe to think of a 2-D grid of actions/dependencies with deliverables on the vertical axis and work-steps on the horizontal.
But not everyone likes these kinds of visualizations. Some prefer a text-based description. And some designs don't fit any obvious pictorial representation.
I want to see the big picture, what they can generate are direct translations of the code down to the line level.
I was so happy not being the one doing this useless task..
I vaguely recall Visual Studio has this option where you can generate some sort of class diagram. It looked like shit the last time I used it (~2019) especially as your classes get more and more functions built into it. I also can't imagine how shitty it looks for codebases that have a significant coupling problem.
Furthermore, creating a UML diagram is a documentation process rather than something that should be automatically built in. I put it on the same level as writing a document in a word doc or something that's done as the project gets closer to being finished. Some places can live with it, a lot of places (actual software companies) probably do not as they move unreasonably fast (Agile) which does not even allow time for documentation or they just purposely neglect documentation.
> Why aren't code visualization tools more popular? The options out there seem outdated
Because they look like shit. I tried mermaid with markdown, I was not happy with the results, I tried plantUML back in 2019, I hated how it ended up looking, I hated how I have to install java for it, and I gave up on it pretty quickly.
The only code visualization tool I ever use is either draw.io or MS Visio. At lease there's a plugin for that for VS Code.
> Would you want to use these tools? What would be your ideal tool?
Markdown with vim option. It also must have an option to force a top-down flow approach and not freaking forcing it to be a left-right layout
That's the point, right? Visually representing the complexity of the system. I've used IntelliJ to do this before to show why modifying certain behavior was so slow and error-prone. In that case there were 3-4 classes with heavily overlapping functionality because, surprise, in the past there were multiple teams contributing to the same codebase that all did their own thing.