DepZero: Building a Zero-Dependency Dependency Intelligence Engine in 72 Hours
How Team CR7 built a static AST analysis tool that audits imports, maps call sites, and suggests realistic Python standard-library migrations without installing a single external package.
Project at a Glance
1. The Irony of the Blank Canvas
There is a particular kind of quiet panic that sets in during the opening hour of a hackathon when your first instinct is to run pip install and you suddenly remember that you are strictly forbidden from doing so. When the three of us—Anant, Ahil, and Dhanvin—sat down for Zero Dependency 2026, the constraints established by Hackathon Raptors were absolute: standard library only, no third-party runtime packages, no frameworks, zero pip dependencies, and the entire project had to build and execute cleanly with a single documented command.
Most teams naturally looked at those constraints and started brainstorming games, text parsers, or minimalist web utilities. But as we discussed potential project directions, we kept returning to the same realization: modern Python development has become utterly reliant on an enormous chain of external packages. We pull in external distributions for the simplest tasks, often without realizing how much complexity, potential security risk, and maintenance overhead we are importing alongside that single utility function.
That was when the irony struck us: why not build a zero-dependency tool whose sole purpose is to analyze dependencies? Instead of building just another application that happened to avoid external libraries, we decided to make the hackathon's core constraint the subject of our project. We wanted to build DepZero—a static analysis tool that parses supported Python source files, tracks down detected third-party imports, maps out where and how they are being called, and determines whether those specific usages could realistically be replaced by Python's built-in standard library.
2. The Problem: Inventory Is Not Intelligence
Whenever software teams talk about managing dependencies, the conversation usually revolves around package inventory or vulnerability scanning. Tools like pip list, pipdeptree, and various Software Bill of Materials (SBOM) generators will happily print out a list telling you that your project depends on requests, pandas, click, and pyyaml. Vulnerability scanners will cross-reference those version strings against known CVE databases.
While inventory tools are useful, they fail to answer the most practical questions developers ask when trying to clean up a repository:
• Call Site Discovery: Where in the codebase are detected imports actually being used?
• Functional Granularity: What specific subset of the library's functionality is being invoked?
• Standard-Library Feasibility: Is this dependency truly necessary for this specific use case, or did someone import a large package just to perform a straightforward task that Python's standard library already handles?
Consider a common scenario in modern Python code: a microservice lists requests in its manifest simply to make a single, unauthenticated HTTP GET request to a health-check endpoint. In another file, pandas is imported solely to parse a two-column CSV file and iterate over the rows. In both cases, the project introduced external packaging overhead for tasks that standard-library modules like urllib.request and csv could have handled in a few lines of clean, readable code.
DepZero was created to bridge this exact gap. It does not simply list what packages you have declared; it inspects how your source code interacts with them, providing evidence-based dependency intelligence.
3. Architecture & Static AST Analysis: Looking Without Touching
From the very beginning of the hackathon, we established one non-negotiable architectural requirement: DepZero must analyze code statically. It must never execute, import, or evaluate the user's project code.
The reasoning behind this decision was straightforward: executing untrusted or unfamiliar code simply to inspect its dependencies introduces serious risks. An unknown repository or a poorly configured build script could execute arbitrary logic, spawn background processes, or tamper with the local environment during an evaluation step.
DepZero does not execute the scanned project's Python code or setup.py. It parses files statically, which significantly reduces the risk associated with analyzing untrusted source code, while still acknowledging that static analysis itself is not a complete security sandbox.
To accomplish this without third-party parsing tools, we turned to Python's built-in ast (Abstract Syntax Tree) module. When Python reads source code, it parses the text into an abstract syntax tree representing the grammatical structure of the program. By walking this tree, we can systematically inspect every statement, expression, and identifier in a file.
We specifically targeted Python 3.11+ as our baseline environment. This version requirement gave us access to two critical standard-library additions that made a pure-stdlib implementation substantially cleaner:
• sys.stdlib_module_names: A comprehensive set containing the names of all standard library modules in the running Python installation. Prior to Python 3.10+, determining whether an import belonged to the standard library or third-party space required maintaining fragile hardcoded lists or probing file paths. With this set, stdlib classification is instantaneous and reliable.
• tomllib: Python's built-in TOML parser, introduced in Python 3.11. This allowed us to natively parse modern pyproject.toml configuration files without relying on external libraries like tomli or toml.
4. Manifest vs. Reality: Auditing Declarations Safely
A complete dependency audit requires comparing two different realities: what the project claims it needs (the manifest files) versus what the source code actually imports (the AST findings).
DepZero inspects three standard Python manifest formats:
• requirements.txt: Parsed line by line, stripping version specifiers, environment markers, and comment lines.
• pyproject.toml: Parsed using Python 3.11's built-in tomllib to extract [project.dependencies], [tool.poetry.dependencies], and [project.optional-dependencies] sections.
• setup.py (Static AST Extraction): Historically, many tools inspect setup.py by executing python setup.py egg_info. As discussed, executing an unfamiliar project's build script is unsafe. Instead, DepZero parses setup.py as an AST, traversing the tree to find setup() function calls and statically extracting the string literals inside the install_requires list.
We deliberately designed DepZero to handle dynamic setup.py scripts with intellectual honesty. If a developer wrote a setup.py file that dynamically constructs install_requires through environment variables, external file reads, or runtime functions, DepZero does not guess and it does not execute the file. Instead, it marks the manifest as containing unresolvable dynamic declarations, provides an explicit warning to the user, and relies on direct source code AST scans to detect the actual imports.
By cross-referencing manifest declarations against discovered imports, DepZero identifies two common types of project debt:
• Unused Dependencies: Packages declared in requirements.txt or pyproject.toml that have zero import references across the scanned codebase.
• Undeclared Dependencies: Third-party packages imported in the source code that appear to be missing from the project manifest, which could lead to unexpected runtime failures in clean environments.
5. The Hard Engineering Challenge: Scope Tracking and Usage Resolution
Extracting import statements from an AST is relatively straightforward. The real engineering challenge began when we tried to answer: 'Where is this specific imported entity being called, and what methods are being invoked on it?'
Python is a dynamic, highly expressive language. A naive keyword search or shallow AST visitor breaks immediately on real-world code patterns:
• Import Aliasing: A developer writes import requests as req or from urllib.request import urlopen as fetch.
• Relative Package Imports: A developer writes from ..utils import helpers or from .client import APIClient.
• Lexical Shadowing: A local variable inside a function shadows an imported name (e.g., a function parameter named json inside a module that imported the json package).
• Attribute and Call Chaining: A developer imports requests, creates an instance via session = requests.Session(), and subsequently calls session.get(url) several lines later.
To handle these patterns without bringing in heavyweight semantic engines, we implemented a lightweight lexical scope tracker. Our visitor maintains a stack of lexical scopes corresponding to modules, class definitions, function definitions, and comprehension blocks.

As the AST walker encounters variable assignments, function parameters, loop targets (for item in items:), and import bindings, it registers them in the current scope. When an attribute access or call expression like client.get() is evaluated, the tracker resolves client back through the scope hierarchy to check whether it originated from a third-party import binding.
Honest Boundaries of Our Static Analyzer
We want to be completely candid about what our static analyzer can and cannot do. Python's runtime dynamism means that purely static analysis without code execution has inherent theoretical and practical limits. DepZero cannot reliably resolve:
• Dynamic Imports: Imports performed via __import__(var) or importlib.import_module(dynamic_string).
• Metaprogramming & Runtime Patching: Modifications to sys.modules, runtime monkey-patching, or dynamic attribute injection via setattr().
• Runtime Plugins & Interprocedural Flow: Complex dependency injection containers or objects passed through arbitrary foreign callbacks.
• Distribution vs. Import Mismatches: Packages whose PyPI distribution name differs unpredictably from their top-level import name (e.g., pyyaml vs yaml, scikit-learn vs sklearn, Pillow vs PIL), except where we have explicit mapping rules.
Rather than hiding these blind spots behind inflated marketing claims, DepZero tracks unresolved references explicitly and surfaces them in the report as 'Unresolved / Dynamic Items' so the developer knows exactly what requires manual inspection.
6. The Recommendation Engine: Pragmatic, Evidence-Based Migrations
A major pitfall in zero-dependency tooling is dogmatism. Telling a software team to 'just delete pandas and use standard library csv' is terrible engineering advice if they are performing matrix operations, time-series resampling, or complex multi-table joins.
From day one, we designed DepZero's recommendation engine to be conservative, evidence-based, and nuanced. Every migration suggestion is backed by concrete AST call-site evidence and assigned a confidence rating:
• HIGH Confidence: The AST demonstrates that the codebase only uses simple, easily replaceable functions from the library, with no advanced features detected.
• MEDIUM Confidence: The code uses standard features, but standard-library replacements require slight structural adjustments (e.g., handling binary stream decoding or custom header dictionaries).
• LOW Confidence / KEEP: The code invokes complex library-specific abstractions, session managers, custom adapters, or vectorized operations that have no straightforward stdlib equivalent. In these cases, DepZero advises KEEPING the dependency.
7. The DepZero Score: A Directional Refactoring Heuristic
To help developers quickly assess their dependency health and track refactoring progress, DepZero computes a project-specific metric called the DepZero Score.
We want to emphasize clearly: the DepZero Score is NOT an industry standard, an academic metric, or a formal security rating. It is a pragmatic heuristic developed specifically for this tool to provide a directional indicator of dependency reduction potential.
The scoring model evaluates projects on a 100-point scale based on three factors:
• 1. Current Dependency Weight: Base score starts at 100 and scales downward based on the total number of third-party dependencies and their distribution across files.
• 2. Manifest Hygiene: Points are deducted for unused dependencies declared in manifests and undeclared imports found in code.
• 3. Migration Potential: The tool calculates a 'Potential Score' by simulating what the project score would become if all HIGH-confidence migration opportunities were executed and unused declarations were purged.
8. The DepZero Command Center: Offline-First Visual Triage
While command-line output is great for terminal power users and CI pipelines, reviewing dozens of call sites across a repository can quickly become overwhelming in plain text. We wanted to build an interactive dashboard that would let developers explore their dependency graph visually.
However, building a web interface under the Zero Dependency 2026 rules created a unique set of constraints: we could not use React, Vue, Svelte, Tailwind CSS, or any npm packages, and we could not load JavaScript or CSS from external Content Delivery Networks (CDNs) because the application had to run completely offline.
We built the DepZero Command Center entirely from scratch using Python's standard library:
• Backend Server: We implemented a custom request dispatcher using http.server.HTTPServer and http.server.BaseHTTPRequestHandler. It serves JSON API responses for scan results and delivers embedded HTML/CSS/JS assets directly from memory.
• Zero-Framework Frontend: The frontend UI is written in clean, semantic HTML5, modern vanilla CSS (using CSS Grid and Flexbox), and native ES6 JavaScript.
• Core Dashboard Capabilities: The GUI includes a high-level dependency overview, dependency filtering controls, score metrics, migration recommendations, evidence traces, clickable dependency details with modal views, demo project scanning, and a light/dark theme toggle.
• Security & Escaping: All user-supplied strings, file paths, and code snippets rendered in the HTML report are sanitized through Python's html.escape() to prevent Cross-Site Scripting (XSS) when viewing untrusted source files.
The local web interface is launched with:
![]()
When executed, the server starts locally on 127.0.0.1, opens the default web browser, and presents the interactive triage dashboard.
9. Verification & Hackathon Bonus Quests
During the 72-hour sprint, we focused on building a robust, self-contained architecture while addressing the official hackathon side-quests.
Additional Verification: Self-Check Audit
If DepZero is a tool designed to analyze dependencies and verify standard-library conformance, the most natural validation step was to have DepZero audit itself.
We built an automated self-check feature into the tool, invoked via:
The self-check performs two independent static AST audits against the standalone depzero.py implementation:
• Audit A (Primary AST Visitor): Runs DepZero's standard AST visitor across depzero.py to extract and classify all import statements.
• Audit B (Secondary Verification Parser): Runs an independent, secondary AST parser that uses a different tree-traversal strategy (ast.walk flat token extraction) to cross-verify that no third-party package names appear in any import statement.

As highlighted in the tool's output, this self-check provides strong static verification under standard usage, but it is not a formal mathematical proof that the program can never contain a dependency under all possible execution paths. Acknowledging this nuance was an essential part of our engineering approach.
Official Bonus 1: Single-File Implementation (+5)
The entire DepZero application—including the CLI parser, the static AST engine, the lexical scope tracker, the recommendation engine, and the offline web GUI—is implemented in a single, self-contained file: depzero.py.
This single-file artifact requires no build pipelines, no package unpacking, and no virtual environments. It can be copied directly into any system with Python 3.11+ and run immediately.
Official Bonus 2: Reproducible Build Verification (+5)
To ensure that packaging DepZero is completely deterministic, we implemented a reproducibility test suite.
The reproducibility mechanism relies on deterministic file ordering, fixed ZIP metadata timestamps, deterministic archive construction, and cryptographic hash verification using SHA-256. When the build process is executed across two completely independent runs, it produces byte-identical .zip archives with matching SHA-256 hashes:

Official Bonus 3: Package Killer Demonstration (+3)
To earn the 'Package Killer' bonus, we created an offline demonstration showing how a useful subset of requests-like functionality can be implemented using only Python's standard library modules (urllib.request, urllib.error, urllib.parse, and json).
The demonstration can be run directly using:
![]()
To make the demonstration completely self-contained without requiring an internet connection, the command starts a local http.server in a background thread and tests the standard-library micro-client against it.
The demonstrated functionality includes:
• HTTP GET Request Handling: Fetching endpoints using urllib.request.urlopen().
• Custom Headers: Setting User-Agent, Authorization, and Content-Type headers via urllib.request.Request.
• JSON Response Handling: Reading byte streams and safely deserializing JSON payloads.
• 404 & HTTP Error Handling: Catching urllib.error.HTTPError to inspect non-200 status codes.
• Malformed JSON Handling: Catching json.JSONDecodeError on invalid payloads.
• Timeout & Connection Error Handling: Handling socket timeouts and urllib.error.URLError without crashing.
We want to be very clear: this does not claim to be a replacement for the entire requests package. We did not build custom connection pooling, persistent session managers, or custom transport adapters. What we demonstrated is that for common scripts and microservices performing straightforward HTTP GET queries and JSON parsing, Python's standard library provides everything required.
Official Bonus 4: The STDLIB Substitution Matrix (STDLIB.md) (+3)
As part of our hackathon documentation, we created STDLIB.md—a detailed engineering log documenting common third-party libraries, their standard-library counterparts, and the architectural trade-offs involved in migrating between them.
Third-Party Package Standard Library Equivalent Migration Nature Key Trade-offs & Limitations
10. Roadblocks, Mistakes, and Hard Lessons
Building a static analyzer in 72 hours without external dependencies was an educational experience, but it was also filled with moments of intense trial and error.
One of our earliest roadblocks involved import aliasing and multiline import statements. We initially attempted to extract imports using regular expressions before quickly realizing that Python syntax permits countless edge cases—parenthesized multiline imports, trailing commas, inline comments, and chained aliases (import a.b.c as d, e.f.g as h). Scraping these with regex was brittle and incomplete. Moving entirely to Python's AST visitor resolved the parsing issues, but forced us to learn the internal structure of ast.Import and ast.ImportFrom nodes intimately.
Another major challenge was the difference between PyPI distribution names and top-level Python import names. For example, a developer declares PyYAML in their requirements.txt, but in their code they write import yaml. A project declares scikit-learn, but imports sklearn. A project declares Pillow, but imports PIL. A naive equality check between manifest strings and AST import names produces false-positive 'unused dependency' warnings. We had to implement a normalized mapping table for common packages to bridge this gap.
We also encountered path traversal issues when scanning nested project repositories. If a project contained virtual environments inside the repository root (.venv/), our initial scanner crawled thousands of third-party library files inside the virtualenv. We had to build explicit directory filtering, recursion controls, and Path.resolve() checks to ensure DepZero only audits the user's actual project code.
11. Technical Stack & Standard Library Manifest
DepZero was engineered exclusively using Python 3.11+ standard library modules. No third-party packages were installed or utilized at runtime.
12. Conclusion: What 72 Hours Taught Us About Dependencies
When the three of us started Zero Dependency 2026, we viewed the 'no third-party packages' constraint as a demanding technical hurdle. But after 72 hours of designing, debugging, and testing DepZero, our perspective evolved.
Python's standard library is far more capable and mature than modern development habits often acknowledge. Over time, the convenience of running pip install has made it easy to reach for external packages to solve problems that Python already supports out of the box. Every dependency added to a project comes with real trade-offs: potential supply chain risks, maintenance overhead, and extra cognitive load.
At the same time, building DepZero reinforced that third-party packages are not inherently bad. Specialized libraries like NumPy, PyTorch, cryptography, or full-featured web frameworks solve difficult domain problems through years of dedicated engineering. DepZero is not an attempt to eliminate dependencies blindly—it is an effort to give developers visibility into how dependencies are actually used so they can make informed, evidence-based decisions.
For our team, building DepZero from scratch with zero dependencies wasn't just about finishing a hackathon project. It gave us a deeper appreciation for Python's internal architecture, the realities of static analysis, and the value of keeping software architectures as simple and intentional as possible.
~ TEAM cr7
ANANT SHARMA, DHANVIN ARUN, AHIL SANJAY
GITHUB REPOSTRY=https://github.com/Anant007-bot/DepZero
YOUTUBE LINK=https://youtu.be/0K2LCY5RvQA?si=_U8n_8XIdMl32QhR
LINKEDIN PROFILE=www.linkedin.com/in/anant-sharma-150524cr










Top comments (0)