Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Making sense of frontend code with forensic tec...

Making sense of frontend code with forensic techniques (v1-s) 🇬🇧 @JsHeroes 2026

In projects with hundreds of thousands of lines, it is easy to lose track of code, architecture and quality. Are we still on the right track, are we blocking ourselves with internal dependencies, or are we already stuck? Software is immaterial, we cannot see how it is doing.

In this talk, we will therefore look at the forensic techniques and tools we can use to make the quality of code and architecture tangible. The tools extract quantitative information from code, architecture, git history, and the techniques qualify these results. Put together we have accurate picture where we stand. This also support us in having a dialog with non-technical stakeholders at eye level about the required quality.

Avatar for Richard

Richard

May 11, 2026

More Decks by Richard

Other Decks in Programming

Transcript

  1. 15.05.26 Richard Gross (he/him) Software Archaeology richargh.de richargh.de/ richargh Hypermedia

    Modernisation Making Sense of Frontend Code with Forensic Techniques
  2. Figures CCO https://www.openpeeps.com/ Slide 2 CC BY-SA richargh.de You there

    Phoenix is not making any sense. They are getting slower and slower. This is Alex This is Alex’ Boss You are now in charge of it. Fix it. Huh? What is Phoenix?
  3. Slide 3 CC BY-SA richargh.de Huh? What is Phoenix? And

    she is already gone. Phoenix is 50k lines… Where do I even start?
  4. Slide 8 CC BY-SA richargh.de I’ll ask Claude Code Prompt:

    What are the biggest issues of this codebase and in what priority should I fix them?
  5. Claude Code Gobble up stuff, and send it to the

    LLM Subagent Explore() 1. Grep(TODO|FIXME|HACK|XXX) 2. Grep(password|secret|token|api_key|apikey) 3. Grep(eval|exec|dangerouslySetInnerHTML) 4. Grep(SELECT.*FROM.*WHERE) 5. Grep(componentWillMount|componentWillReceiveProps) 6. Grep(race condition|deadlock|mutex|RwMutex) 7. Grep(CVE|vuln) 8. Grep(console.log|error) 9. Bash(npm audit) 10. Bash(npm run test) 11. LineCount(*.ts) 12. LineCount(*.spec.ts) 13. Read(all package.json) 14. Read(all *.md) 15. Read(jest|webpack.config.*) 16. Read(largest files) Slide 9 CC BY-SA richargh.de
  6. Reliable? * Same prompt three times, /clear after each result

    1st try 2nd try ## Critical issues 1. MASSIVE TECHNICAL DEBT FROM TODO/FIXME MARKERS 2. SQL INJECTION VULNERABILITIES RISK 3. EXCESSIVE USE OF DANGEROUS REACT PATTERNS 4. DEPRECATED REACT LIFECYCLE METHODS 5. MASSIVE COMPONENT SIZE AND COMPLEXITY 6. INCOMPLETE TEST COVERAGE ## RECOMMENDATIONS ### Immediate (0-30 days) 1. Security Audit SQL Queries 2. Remove console.log statements 3. Patch bootstrap 4. Audit all dangerouslySetInnerHtml 🚨 CRITICAL - Fix Immediately [1-2 weeks] 1. Hardcoded Sentry DSN Exposed 2. SQL Injection Vulnerabilities 3. Weak Cryptography (SHA-1, MD5) ⚠ HIGH - Address Soon (1-2 months) 1. Monolithic App Layer (130K+ lines) 2. Technical Debt Backlog (TODO/FIXME) 3. Type Safety Issues (2,257 instances Total effort estimate: 715-1,080 hours Logging not mentioned Patching not mentioned Slide 10 CC BY-SA richargh.de 3rd try 🔴 CRITICAL - Fix Immediately 1. XSS Vulnerability Risk 2. Insecure Cryptographic Hash (SHA- 1) 3. Massive File Sizes 🟠 HIGH - Fix Within Sprint 1. localStorage Security Issues 2. 1,606 TODO/FIXME Comments 3. Excessive any Type Usage 📋 Recommended Priority Order Week 1-2 (Security Sprint): 1. Fix XSS vulnerabilities 2. Replace SHA-1 with SHA-256 3. Implement CSP headers 4. Secure localStorage or migrate to HttpOnly cookies SQL not mentioned /clear /clear
  7. Feels similar, with random priority Slide 11 CC BY-SA richargh.de

    999+ SQL Injections Console.logs 999+ Patch 999+ 1 2 3
  8. Slide 12 CC BY-SA richargh.de Software Forensics? Have you tried

    What is that? This is Taylor Now what? The reports have a lot of ideas…
  9. Software Forensics [soft-wer, fuh-ren-ziks], noun – applying techniques inspired by

    forensic psychology — in particular geographical offender profiling — to software systems by combining temporal (commits), social (authors) and static (code) data, to map hotspots, uncover hidden dependencies, and reveal organisational friction. Coined by Adam Tornhill, Your Code as a Crime Scene Provides a commercial tool, https://codescene.com/ — free for open-source Slide 13 CC BY-SA richargh.de
  10. Slide 15 CC BY-SA richargh.de Wow that sounds interesting EsLint

    is a source for static analysis. What we want is to correlate multiple sources on a map to find murderers. But isn’t that exactly what EsLint does? Wait what? Murderers? More correct would be “offenders”. Let me explain.
  11. Triangulating offenders * The more dimensions, the more precise you

    can be, roughly. Very simplified example, Your Code as a Crime Scene goes into more detail Slide 16 CC BY-SA richargh.de Dimension 2 Dimension 1 Dimension 3 The most likely location.
  12. Dimension 1 – Area See codecharta.com (developed by MaibornWolff), free,

    open-source, all data stays local Slide 17 CC BY-SA richargh.de Lines of Code
  13. Dimension 1 – Area, with Folders See codecharta.com (developed by

    MaibornWolff), free, open-source, all data stays local Slide 18 CC BY-SA richargh.de Lines of Code
  14. Dimension 2 – Height See codecharta.com (developed by MaibornWolff), free,

    open-source, all data stays local Slide 19 CC BY-SA richargh.de Cycl. Complexity Lines of Code
  15. Dimension 3 - Color See codecharta.com (developed by MaibornWolff), free,

    open-source, all data stays local Slide 20 CC BY-SA richargh.de Claude Smell (high) business.model.ts Lots of code. Many decisions. Lots of smells. Smells: FIXME comments, shotgun surgery, law of demeter, … Lines of Code Cycl. Complexity
  16. Slide 21 CC BY-SA richargh.de So I guess I’ll fix

    the complex & smelly code now? Complex code by itself is not bad. Add the temporal dimension to gain insights.
  17. Slide 22 CC BY-SA richargh.de So I guess I’ll fix

    the complex & smelly code now? Complex code by itself is not bad. Complex code that is changing all the time? Yes! Changes in complex code are much more risky and expensive. Add the temporal dimension to gain insights.
  18. Complex code that is changing all the time See codecharta.com

    (developed by MaibornWolff), free, open-source, all data stays local Slide 23 CC BY-SA richargh.de Churn (high) model.service.ts Lots of code. Many decisions. Lots of change. And, intention- hiding name Lines of Code Cycl. Complexity Prime hotspot
  19. Complex components that are changing all the time See codecharta.com

    (developed by MaibornWolff), free, open-source, all data stays local Slide 24 CC BY-SA richargh.de Churn (high) Lines of Code Cycl. Complexity High-chrun Components UX Design instability? Shifting requirements?.
  20. Such maps have huge benefits over TODO lists 1. Not

    a 1D list, but three dimensions we can correlate 2. See the forest and the trees à You can see file and cluster hotspots at the same time 3. Explorable with drilldown possible, not aggregated 4. It allows us to analyse and reason about large amounts of code 5. Shows the state to stakeholders and experts alike Slide 26 CC BY-SA richargh.de
  21. Graspable code, even for stakeholders See codecharta.com (developed by MaibornWolff),

    free, open-source, all data stays local, 3D print included J Slide 27 CC BY-SA richargh.de
  22. https://www.heise.de/en/background/CodeCharta-Visualize-software-quality-clearly-as-a-cityscape-10322754.html Slide 28 CC BY-SA richargh.de We improved names, added

    tests, reduced nesting and split up the remaining complexity of the hotspots. The team can work much faster now. 2021/04 2022/06
  23. Slide 30 CC BY-SA richargh.de You there You are now

    in charge of scaling Phoenix. Scaling? You mean add more people?
  24. * Yes, onboarding is much more than how the code

    looks. But we can certainly make it easier by investigating the code. Slide 31 CC BY-SA richargh.de Scaling? You mean add more people? And she is gone. What a nightmare, onboarding always takes forever*.
  25. Knowledge silos are a risk and bad for onboarding See

    codecharta.com (developed by MaibornWolff), free, open-source, all data stays local Slide 32 CC BY-SA richargh.de Lines of Code Cycl. Complexity Number of authors (1) Brent‘s codeTM Claude‘s codeTM
  26. But there is more that makes onboarding tricky Some files

    always have to be changed together but there is no visible coupling between them. Slide 33 CC BY-SA richargh.de
  27. Change Coupling1, the invisible coupling 1 from the book https://pragprog.com/titles/atcrime/your-code-as-a-crime-scene

    Slide 35 CC BY-SA richargh.de Lines of Code Cycl. Complexity Change coupling (High) RentComponent rent.component.ts Notice that no compile-time relation exists between the change-coupled files. Ingoing Change Coupling
  28. Change coupling starts simple 1. Often it’s a simple act

    of Copy/Paste 2. This copy has to stay in sync1 with the original lest you get bugs 3. This is a problem of duplicated knowledge2 4. Refactor towards SPOT3 (single point of truth) 1 https://connascence.io/ 2 https://verraes.net/2014/08/dry-is-about-knowledge/ 3 SPOT captures the idea better than DRY https://wiki.c2.com/?SinglePointOfTruth Slide 37 CC BY-SA richargh.de
  29. Slide 38 CC BY-SA richargh.de We started pairing to share,

    grouped things cohesively, added abstractions where necessary Everywhere? No! Only where change needed to happen.
  30. Slide 39 CC BY-SA richargh.de But then we made mistakes.

    We couldn’t keep it all in our head. Well you could define your architecture rules as code.
  31. Define your goal as code Example uses Dependency-Cruiser https://github.com/sverweij/dependency-cruiser TS-Arch

    is an alternative: https://github.com/ts-arch/ts-arch 1. { 2. name: ‘no-access-to-renting', 3. comment: ‘No code outside may access renting.', 4. severity: 'error', 5. from: { pathNot: [‘^src/renting/’ ] } 6. to: {path: '^src/renting/’ }, 7. } Slide 40 CC BY-SA richargh.de Define what you want (dependency-cruiser.js) 1. { 2. "rule": { 3. "severity": "error", 4. "name": ”no-access-to-renting" 5. }, 6. "type": "dependency", 7. "from": "src/some-other-component/some.service.ts", 8. "to": "src/renting/rening.service.ts", 9. } Define known exceptions (.known-violations.json) Can be generated via depcruise –output-type known-violations src/) 1. "lint:architecture": " 2. npx depcruise src 3. --ignore-known 4. .known-violations.json 5. " Check continuously
  32. Review and iteratively fix your violations See codecharta.com (developed by

    MaibornWolff), free, open-source, all data stays local Lines of Code Arc. Violations Arc. Violations (high) Slide 41 CC BY-SA richargh.de
  33. Slide 42 CC BY-SA richargh.de You there Everything seems to

    be running smoothly. What did you do?!
  34. Slide 43 CC BY-SA richargh.de Well we reduced complexity in

    key areas, improved test coverage, decoupled modules, - I don’t see any of that. You can see the effects in our delivery. You there Everything seems to be running smoothly. What did you do?! But I could also show you a map.
  35. Figures CCO https://www.openpeeps.com/ Slide 45 CC BY-SA richargh.de You there

    Unicorn is not making any sense. They are getting slower and slower. You are now in charge of it. Fix it.
  36. Figures CCO https://www.openpeeps.com/ Slide 46 CC BY-SA richargh.de You there

    Unicorn is not making any sense. They are getting slower and slower. You are now in charge of it. Fix it. Sure!
  37. Figures CCO https://www.openpeeps.com/ Slide 47 CC BY-SA richargh.de And gone

    You there Unicorn is not making any sense. They are getting slower and slower. You are now in charge of it. Fix it.
  38. In case you are interested in forensics + Adam Tornhill’s

    book: https://pragprog.com/titles/atcrime2/your-code-as-a-crime-scene-second-edition/ + Adam Tornhill’s own tool https://codescene.com/ Slide 48 CC BY-SA richargh.de Give CodeCharta a ⭐ Our CodeCharta experience in a customer project https://codecharta.com/ heise.de/...as-a-cityscape-10322754.html Or a PR?
  39. Happy to take questions and/or coffee richargh.de Richard Gross (he/him)

    Software Archaeology Hypermedia Modernisation Works for maibornwolff.de/ richargh.de richargh Slide 49 CC BY-SA richargh.de https://content.maibornwolff.de/meetings/richard-gross Drink a (virtual) coffee with me.
  40. Getting started Easy to get started Easy to extend See

    codecharta.com, free, open-source, all data stays local Slide 51 CC BY-SA richargh.de 1. java --version # analysis uses java 2. npm i –g codecharta-analysis 3. git clone <phoenix-project> 4. ccsh unifiedparser phoenix –o phoenix.uni 5. # open the uni file in the visualization 6. # all files stay on your machine 7. open https://codecharta.com/visualization/app 1. ccsh gitlogparser repo-scan --repo-path=phoenix –o phoenix.git 2. ccsh merge phoenix.uni.cc.json.gz phoenix.git.cc.json.gz –o phoenix.merge 3. # open the merge file in the visualization 4. # all files always stay on your machine 5. open https://codecharta.com/visualization/app
  41. Add Sonar (more metrics, more languages) Add Sonar Extended language

    support: https://docs.sonarsource.com/sonarqube-server/analyzing-source-code/languages/overview Slide 52 CC BY-SA richargh.de 1. ccsh sonarimporter <your_server> <your_project_id> -u <your_key> –o phoenix.sonar 2. ccsh merge phoenix.sonar.cc.json.gz phoenix.git.cc.json.gz –o phoenix.merge 3. # open the file in the visualization 4. open https://codecharta.com/visualization/app
  42. Which map tool 1 free for open-source https://codescene.com/ 2 https://codecharta.com/

    3 Many more like this exist. This list is not complete. Slide 53 CC BY-SA richargh.de Free, open-source, all data stays local, extend with your own metrics. CodeCharta2 No €-invest to try forensics 1 powered by CodeHealth™, the only validated metric measuring the business impact of code quality. Commercial
  43. Which graph tool? 1 free for non-profit open-source https://www.hello2morrow.com/products/sonargraph/architect 2

    https://github.com/MaibornWolff/dependacharta 3 Many more exist. The list is not complete. Slide 54 CC BY-SA richargh.de Free, open-source, all data stays local, early alpha. DependaCharta2 No €-invest to try forensics swiss army knife for architects SonarGraph1 Commercial
  44. DependaCharta Find all Dependencies Hide downgoing arrows, for less noise.

    1 https://github.com/MaibornWolff/DependaCharta, free, open-source, all data stays local, early alpha Slide 55 CC BY-SA richargh.de Sort top-to-bottom heuristically Has only outgoing dependencies Has only ingoing dependencies Has more outgoing dependencies, than the one below Top Bottom MetricChooser .component MetricChooser .service import {} from “”
  45. Primary focus on the upward dependencies * The ones that

    create knots in your brain. X depends on Y but Y also depends on X. ** see https://github.com/MaibornWolff/DependaCharta, free, open-source, all data stays local, early alpha Slide 56 CC BY-SA richargh.de Upgoing Dependenc y
  46. Also find central/monolithic state * Hard to scale independently if

    everything depends on the same state. Slide 57 CC BY-SA richargh.de
  47. Identify file cycles Slide 58 CC BY-SA richargh.de Upgoing Dependenc

    y Downgoing Dependency that creates a file cycle
  48. Identify the most connected components see https://github.com/MaibornWolff/DependaCharta, free, open-source, all

    data stays local, early alpha Slide 59 CC BY-SA richargh.de Upgoing Dependenc y Downgoing Dependency that creates a file cycle Downgoing Dependency, only shown on hover
  49. Hierarchy of needs Slide 60 CC BY-SA richargh.de Is the

    capacity to act given? Are there any unaccepted/unmitigated risks? If you cannot deploy main, you cannot act. Risks can also be accepted or mitigated. The #flexible part the boss wants adressed
  50. Dimension 3 – Color See codecharta.com, free, open-source, all data

    stays local Slide 61 CC BY-SA richargh.de Coverage (low medium high) Lines of Code Cycl. Complexity
  51. Investigation guide, make sure your needs are met first CC=CodeCharta

    codecharta.com DC=DependaCharta https://github.com/MaibornWolff/DependaCharta Slide 64 CC BY-SA richargh.de Question Tool Area Height Color Where does most of the work happen? CC RLoC Cycl. Complexity Churn How good is my coverage? CC RLoC Cycl. Complexity Coverage Are there knowledge silos? CC RLoC Cycl. Complexity Num Authors 1. java --version # analysis uses java 2. npm i –g codecharta-analysis Look for file or cluster hotspots Question Tool Arrows Are the dependencies understandable? DC Feedback & twisted edges Do file cylces happen DC Show only cycles
  52. Check coordination bottlenecks Slide 65 CC BY-SA richargh.de Lines of

    Code DataMocks.ts Lots of code, but no decisions. Probably fine. Cycl. Complexity Number of authors (high) FleetService.ts Lots of code, many decisions and 20 authors. Why?
  53. Invisible coupling can make onboarding rather tricky Seasoned developers have

    an intuition what parts are tricky and have to be changed together. Slide 66 CC BY-SA richargh.de
  54. Visible dependency coupling, invisible extent See codecharta.com (developed by MaibornWolff),

    free, open-source, all data stays local Slide 67 CC BY-SA richargh.de Lines of Code Cycl. Complexity Dependency Coupling (High) FileService Why do so many services need rent service? Where data comes from Ingoing Dependencies rent.service.ts