5 ms·
Show HN: Pyscn – Python code quality analyzer for vibe coders
Hi HN! I built pyscn for Python developers in the vibe coding era.
If you're using Cursor, Claude, or ChatGPT to ship Python code fast, you know the feeling: features work, tests pass, but the codebase feels... messy.
Common vibe coding artifacts:
• Code duplication (from copy-pasted snippets)
• Dead code from quick iterations
• Over-engineered solutions for simple problems
• Inconsistent patterns across modules
pyscn performs structural analysis:
• APTED tree edit distance + LSH
• Control-Flow Graph (CFG) analysis
• Coupling Between Objects (CBO)
• Cyclomatic Complexity
Try it without installation:
uvx pyscn analyze . # Using uv (fastest)
pipx run pyscn analyze . # Using pipx
(Or install: pip install pyscn)
Built with Go + tree-sitter. Happy to dive into the implementation details!
- deleted 1y ago[deleted]
- deleted 1y ago[deleted]
- brynary 1y agoThis looks great! Duplication and dead code are especially tricky to catch because they are not visible in diffs. Since you mentioned the implementation details, a couple questions come to mind: 1. Are there any research papers you found helpful or influential when building this? For example, I need to read up on using tree edit distance for code duplication. 2. How hard do you think this would be to generalize to support other programming languages? I see you are using tree-sitter which supports many languages, but I imagine a challenge might be CFGs and dependencies. I’ll add a Qlty plugin for this (https://github.com/qltysh/qlty https://github.com/qltysh/qlty) so it can be run with other code quality tools and reported back to GitHub as pass/fail commit statuses and comments. That way, the AI coding agents can take action based on the issues that pyscn finds directly in a cloud dev env.
- d-yoda 1y agoThank you! 1.For tree edit distance, I referred to "APTED: A Fast Tree Edit Distance Algorithm" (Pawlik & Augsten, 2016), but the algorithm works as O(n²) so I also implemented LSH (classic one) for large codebases.The other analyses also use classical compiler theory and techniques. 2. Should be straightforward! tree-sitter gives us parsers for 40+ languages. CFG construction is just tracking control flow, and the core algorithm stays the same. I focused on Python first because vibe coding with Python tends to accumulate more structural issues. But the same techniques should apply to other languages as well. Excited about the Qlty integration - that would make pyscn much more accessible and would be amazing!
- scuff3d 1y agoThis is an interesting idea but you might be better off marketing it as a tool for software engineers, maybe to help with old code bases. Or even for someone stuck cleaning up vibe coded nonsense. Vibe coders don't care about quality and wouldn't understand why any of these things are a problem in the first place.
- d-yoda 1y ago"You're absolutely right!" - the messaging could be clearer. I built pyscn because more engineers than expected are using AI assistants these days (to varying degrees), and I wanted to give them a tool to check code quality. But the real value might be for engineers who inherit or maintain AI-generated codebases as you say, rather than those actively vibe coding.
- CuriouslyC 1y agoVibe coders do care about quality, at least the ones that try to ship and get burned by a mountain of tech debt. People aren't as stupid and one dimensional as you assume.
- flare_blitz 1y agoAnd where, exactly, did this commenter say that vibe coders are "stupid and one dimensional"? Stop putting words in people's mouths.
- CuriouslyC 1y ago>> Vibe coders don't care about quality and wouldn't understand why any of these things are a problem in the first place. He literally bucketed an entire group of people by a weak label and made strong claims about competence and conscientiousness.
- flare_blitz 1y agoThat comment sounds pretty benign to me. I also don't know why you're assuming the original commenter is male. The only person in the wrong here is you, and you're wrong twice over.
- xrd 1y agoI absolutely love this. Tests and code coverage metrics are still important, but so easy to leave behind as you are running toward the vibe. This is a nice addition to the toolbox.
- d-yoda 1y agoThank you! I'll keep improving it more and more!
- smoe 1y agoI’d argue that those kinds of automated tools are much more important much earlier in a project than they used to be. Personally, I can deal with quite a lot of jank and a lack of tests or other quality control tools in the early stages, but LLMs get lost so quickly. It’s like onboarding someone new to the codebase every hour or so. You want to put them into a feedback loop with something or someone that isn’t you.
- aDyslecticCrow 1y agoCurrent AI is most proficient in java-script and python because of the vast training data. But in the long-run, i feel like languages with good static analysis, static type checks, clear language rules, memory leak detection, fuzzing, test oriented code, and any number of other similar tooling is gonna be the true game-changer. Directed learning using this tooling could improve the models beyond their training set, or simply allow humans to constrain AI output within certain bounds.
- buremba 1y agoI was more optimistic before bur if 95% of the all software is written by these two languages, it will be very hard for any (better) alternative to disrupt them. The only way will likely to make better profiling & debugging tools to help maintain existing codebase.
- d-yoda 1y agoI'm actually more optimistic. While Python/JS have huge ecosystems, there are still things only Go/Rust can achieve.
- aDyslecticCrow 1y agoPersonally i think we would need to see more specialized models RustGPT or ClangCPT or GoGPT. A model tuned for a specific language with proper tooling integration beyond MCP tools. The current general purpose models will always be biased towards what they have training data for, and we're clearly seeing them struggle with these languages. (My personal experience with AI C or Rust code is quite atrocious.) But specialization restricts target market and requires time to develop. Its currently faar more lucrative trying to make a general purpose model and attract VC funding for market capture.
- d-yoda 1y agoGreat point! Golang is indeed one of those languages with strong "vibe coding resistance" - it's personally one of my favorites for that reason. On the flip side, I think there's a future where tools like pyscn work alongside AI to make languages with large communities like Python even more dominant.
- CuriouslyC 1y agoI'm surprised you went with go for this, you're going to encounter so much pain with large codebases.
- dangoor 1y agoCurious why you say this. It says in the readme it can do 100K lines per second.
- d-yoda 1y agoYeah Go is very fast!
- CuriouslyC 1y agoThe SIMD story in Rust or another lower level systems language is much better, and the memory control is more fine grained without forfeiting inlining. For a hot loop that's amenable to SIMD, Rust can deliver twice the performance of Go if you don't hand roll platform specific code.
- d-yoda 1y agoRust is definitely the king of performance! I personally love Go, but Rust's performance is truly impressive.
- maleldil 1y agoI'm not sure what that means. My codebase with 40k lines (via cloc) takes 20 seconds (M1 Pro).
- derekcheng08 1y agoThis is pretty awesome! If it's built on tree-sitter, is it fair to assume it's generalizable across languages?
- d-yoda 1y agoYes! tree-sitter supports multiple languages and the core algorithms should transfer easily. I focused on Python first because I saw many people struggling with code quality issues in Python.
- derekcheng08 1y agoJust based on usage, I would assume js/ts would be very valuable as well. I see a lot of the same issues there and agree the core algos seem to apply generally. Very cool project!
- _joel 1y agoAgreed, I do python and ts depending on the use case, a ts version would be cool
- aitchnyu 1y agoTangential, tree-sitter also allowed Aider, AI coding asisstant to exist and allow LLMs to work on codebases above their context limit. https://aider.chat/docs/recordings/tree-sitter-language-pack.html https://aider.chat/docs/recordings/tree-sitter-language-pack...
- FergusArgyll 1y agoVery cool! I've never seen a cli that opens an html file when it's finished. I kinda like it, hope to see more of that in the future
- guilhermesfc 1y agoThis is great! Is there something similar for Typescript?
- d-yoda 1y agoNot yet! But the algorithms should transfer well - the core logic supports TypeScript, so it's definitely doable.
- scosman 1y agothis should be a MCP server the agent can use and optimize on I have a MCP server that wraps developer tool CLIs (linting, tests, etc), but this would need a textual report instead of HTML. https://github.com/scosman/hooks_mcp https://github.com/scosman/hooks_mcp
- brynary 1y agoWhat benefits do you see from having the agent call a CLI like this via MCP as opposed to just executing the CLI as a shell command and taking action on the stdout?
- mogwire 1y agoThis is one of the most important questions I see when people recommend an MCP server. If cursor and Claude code can already run an executable why do I need to add an MCP server in front of it? I feel like a lot of times it’s, “Because AI”
- scosman 1y agoFew things: - Security/Speed: I leave "approve CLI commands" on in Cursor. This functions as a whitelist of known safe commands. It only needs to ask if running a non-standard command, 99% of the time it can use tools. It will also verify paths passed by the model are in the project folder (not letting it execute on external files) - Discoverability: For agents to work well, you need to explain which commands are available, when to use each, parameters, etc. This is a more formal version than a simple AGENTS.md, with typed parameters, tool descriptions, etc. - Correctness: I find models mess up command strings or run them in the wrong folders. This is more robust than pure strings, with short tool names, type checking, schemas, etc. - Parallel execution: MCP tools can run in parallel, CLI tools typically can't - Sharing across team: which dev commands to run can be spread across agents.md, github workflows, etc. This is one central place for the agents use case. - Prompts: MCP also supports prompts (less known MCP feature). Not really relevant to the "why not CLI" question, but it's a benefit of the tool. It provides a short description of the available prompts, then lets the model load any by name. It's requires much less room in context than loading an entire /agents folder.
- senand 1y agoHow does this compare to ruff?
- d-yoda 1y agoThey complement each other - Ruff for style, pyscn for architecture. pyscn focuses on structural quality - checking if your code follows fundamental design principles like DRY, YAGNI, or other best practices.
- eric15342335 1y agoWhat about Pylint? iirc pylint has code duplication check as well. is it the same thing?
- d-yoda 1y agoPylint's duplication check is text-based (compares lines), while pyscn uses tree edit distance on ASTs. This means pyscn can catch structural clones even when variable/function names differ.
- joduplessis 1y agoThere's no way vibe coders care about this. Focus on real engineers.
- d-yoda 1y agoFair point! My initial target was engineers using AI, but I'm open to refining the messaging.
- amacbride 1y agoI'm going to push back hard on the folks dunking on "vibe coders" -- I have been programming longer than most of you have been alive, and there are times when I absolutely do vibe coding: 1) unfamiliar framework 2) just need to build a throwaway utility to help with a main task (and I don't want to split my attention) 3) for fun: I think of it as "code sculpting" rather than writing So this is absolutely a utility I would use. (Kudos to the OP.) Remember the second-best advice for internet interactions (after Wheaton's Law): "Ssssshh. Let people enjoy things."
- convolvatron 1y agowe can have a pissing contest. I don't begrudge anyone their fun, but when my job becomes taking hundreds of thousands of lines of vibe code and just finding that one little change that will make it all work, we have a serious problem with expectations.
- amacbride 1y agoI don't think we're at odds: I think "vibe coding" is strictly for fun and for prototypes. However, people will misuse any tool, so having utilities to mitigate the risk isn't a bad thing.
- kelnos 1y agoI too have probably been programming longer than most people here, and I'll vibe code on occasion for your #2 reason. (Recently I needed to take an OpenAPI spec file and transform/reduce it in some mechanical ways; didn't feel like writing the code for it, didn't care if it was maintainable, and it was easily verifiably correct after a quick manual skim of its output.) I don't think #1 is a good place to vibe code; if it's code that I'll have to maintain, I want to understand it. In that case I'll sometimes use an LLM to write code incrementally in the new framework, but I'll be reading every line of it and using the LLM's work to help me understand and learn how it works. A utility like pyscn that determines code quality wouldn't be useful for me with #1: even in an unfamiliar framework, I'm perfectly capable judging code quality on my own, and I still need and want to examine the generated code anyway. (I'm assuming we're using what I think is the most reasonable definition of "vibe coding": having an LLM do the work, and -- critically -- not inspecting or reviewing the LLM's output.)
- ok123456 1y agoI ran these on some (non-vibe-coded) large repositories of my code that I'm not too proud of, and it gave me an A. I feel validated.
- d-yoda 1y agoHaha, maybe your code is better than you think! But seriously, we'd love to hear if the thresholds feel too lenient. Feedback welcome!
- khimaros 1y agosee also https://github.com/mozilla/rust-code-analysis https://github.com/mozilla/rust-code-analysis which also builds on Tree Sitter, tracks similar metrics, and supports quote a few languages
- d-yoda 1y agoThanks for sharing! Good to know about rust-code-analysis. Always helpful to see what other tools are doing in this space.
- ktrnka 1y agoLooks good to me! The status bar did something weird on my codebase in which 2% was really 100% so it looked like it was gonna take hours but only took a minute or so. I'll try hooking it into my refactor/cleanup workflow with copilot and see how it works as grounding.
- d-yoda 1y agoThanks for trying it out! For the progress bar bug, would you mind opening a GitHub issue with details? That'll help us track it down. Great idea using it as grounding for AI-assisted refactoring! Let us know how that workflow goes.
- stuaxo 1y agoHere are some anti patterns a colleague put in their code. Prescriptive comment: Comment describes exactly what the following code does without adding useful context. (Usually this is for the LLM to direct itself and should be removed). Inconsistent style: You have this across modules, but this would be in the same file. Inconsistent calling style: A function or method should return one kind of thing. (In the worst case, the LLM has generated a load of special cases in the caller to handle the different styles it made). Unneeded "Service" class: I saw a few instances where something that should have been simple function calls resulted in a class with Service in the name being added, I'm not sure why, but it did happen adding extra complications. Those are the ones off the top of my head. As a senior dev, I think use of these tools can be fine, as long as people are happy to go and fix the issues and learn, anyone can go from vibe coder to coder if you accept the need to learn and improve. The output of the LLM is a starting point, however much we engineer prompts, we can't know what else we need to say until we see the (somewhat) wrong output and iterate it.
- d-yoda 1y agoThis is super insightful, thank you for sharing. It's a great list of common LLM-generated anti-patterns. I'd love to look into incorporating checks for these into pyscn. This is exactly the kind of stuff I want it to catch.
- incomingpain 1y agoI saw this project show up in some newsletters. Awesome project idea. I've been using 'vulture' so far. But when i try to run analyze or check. Running quality check... Complexity analysis failed: [INVALID_INPUT] no Python files found in the specified paths Dead code analysis failed: [INVALID_INPUT] no Python files found in the specified paths Clone detection failed: no Python files found in the specified paths Error: analysis failed with errors I'm certainly in a folder with python files.
- d-yoda 1y agoWow, was it really in some newsletters? That's awesome to hear, and would definitely explain the recent spike on GitHub! Thanks a lot for the bug report and for providing the details. I have a hunch—it's possible that you need to explicitly specify the path depending on your directory structure. For example, if your Python files are under a src directory, could you try running it like [your_tool_name] analyze src/? If that still doesn't solve the problem, it would be a huge help if you could open a quick issue on GitHub for this. Thanks again for your feedback!
- incomingpain 1y agohttps://imgur.com/a/382mtPr https://imgur.com/a/382mtPr It was linked in the TLDR newsletter on monday. (myglobalenv) steve@bird:~/PycharmProjects/netflow$ ls aggregator.py data netflow settings.py assets database.py notifications.py sniper.py config.py Dockerfile opencode.json start.sh context_manager.py integration.py __pycache__ tcpports.py context.py largflow.py README.md dashboard.py main.py requirements.txt (myglobalenv) steve@bird:~/PycharmProjects/netflow$ pyscn check . Running quality check... Complexity analysis failed: [INVALID_INPUT] no Python files found in the specified paths Dead code analysis failed: [INVALID_INPUT] no Python files found in the specified paths Clone detection failed: no Python files found in the specified paths Error: analysis failed with errors Usage: pyscn check [files...] [flags] Flags: --allow-dead-code Allow dead code (don't fail) -c, --config string Configuration file path -h, --help help for check --max-complexity int Maximum allowed complexity (default 10) -q, --quiet Suppress output unless issues found --skip-clones Skip clone detection Global Flags: -v, --verbose Enable verbose output -v doesnt give me anything neither.
- Def_Os 1y agoNice idea, good timing. Any plans to wrap this in an MCP? My Claude Code instance should have this in their toolbox.
- d-yoda 1y agoYes, that's definitely something I'm looking into. I've received a few comments about AI coding integrations, so it's becoming a high priority.