This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend
π What I Built
I built an AI code explainer that doesn't let the AI decide what the architecture is.
Rahul is a friend and a regular collaborator on my projects. While working through an unfamiliar Spring Boot codebase, he ran into a problem that has nothing to do with syntax or writing code.
He couldn't easily see the bigger picture.
Which controller talks to which service?
Which repository sits behind that service?
Which entity is being used?
What endpoints does the application expose?
Where does a particular class fit in the overall structure?
In a small project, you can trace those relationships manually. In a larger Java codebase, that quickly becomes tedious, especially when you are seeing the project for the first time.
My first idea was straightforward: build a chatbot that reads the repository and explains it.
Then I changed the design.
I wanted the architecture to be derived from the source code first, rather than reconstructed by an LLM from raw code.
So I built Code2UML AI.
The system accepts a Spring Boot .zip, analyzes the Java source using deterministic static analysis, converts the extracted relationships into structured architecture data, and renders that data as interactive Mermaid diagrams.
An optional Gemma-powered assistant then answers questions about the architecture.
The code determines the architecture. Gemma explains it.
That separation is the core idea behind the project.
I gave the tool to Rahul to test the actual goal: could it make an unfamiliar Spring Boot project easier to understand?
The success criterion wasn't a flashy interface.
It was much simpler:
Can someone go from βI don't understand this codebaseβ to βI can see how these pieces fit togetherβ?
That's what Code2UML AI is built to help with.
π» Try the Demo
π Live demo: https://code2uml.onrender.com/
The public version is deployed on Render using Hacktoberfest Render credits.
β οΈ Privacy note: This is a public deployment. Use the included sample project for evaluation. Do not upload proprietary or sensitive source code to the public instance. For private projects, run Code2UML locally and use a local model endpoint.
Try it in about a minute
- Click Try Sample Project.
- Review the Architecture Observations panel.
- Open the Endpoints tab.
- Explore the Controller β Service β Repository β Entity relationships.
- Ask the Architecture Assistant questions such as:
- Which service handles UserController?
- What repository is connected to UserServiceImpl?
-
Is there an authentication component?
- Compare the answer with the generated architecture and the sample source code.
The sample project contains:
UserControllerUserServiceUserServiceImplUserRepositoryUserUserDTODemoApplication
The fixture produces 7 detected types, 6 packages, 4 REST endpoints, and 10 deduplicated architectural relationships.
Those expected results are also covered by the automated tests.
Screenshots
The dashboard with the sample project loaded. It shows the detected types, REST endpoints, relationships, rule-based observations, and analysis coverage. Coverage means the files were parsed; it is not a guarantee that every relationship was recovered.
The layered architecture view showing controllers, services, repositories, entities, and DTOs alongside the Architecture Assistant. The selector can switch between the full architecture and a focused controller view.
The UML class view generated from the extracted architecture JSON, including stereotypes, fields, methods, realization edges, and dependency relationships.
The endpoint catalog showing HTTP method, route, controller, handler method, and return type.
The Architecture Assistant identifies which engine produced each answer. The authentication question returns βnot detectedβ rather than inventing a component, and the response is limited to the analyzed project.
The Copy Mermaid action lets you export the generated diagram directly into a README or other documentation.
π Source Code
β‘ Code2UML AI
Deterministic Spring Boot architecture visualizer with an optional Gemma-powered assistant. The code determines the architecture. Gemma explains it.
Live demo: code2uml.onrender.com Β· Source: github.com/shraddhaa09/code2uml
β οΈ The hosted demo is a public deployment. Use the built-in sample project and do not upload proprietary or sensitive source code. For private code, run it locally (see Quick Start).
Contents
- Problem
- Solution
- Try it
- Architecture
- Privacy and data flow
- Tech stack
- Quick start
- Running with local Gemma (Ollama)
- Deployment on Render
- Running tests
- Supported constructs
- Performance
- Known limitations
- API endpoints
- Sample fixture
- Project layout
- Contributing
- License
Problem
Understanding a medium-to-large Spring Boot codebase is slow. Developers trace dependency-injection graphs by hand, hunt for REST endpoints across controllers, map JPA entities to repositories, and draw architecture diagrams manually. Many teams also cannot send proprietary source code to a hosted LLM, which rules out the obvious "paste it into a chatbot" shortcut.
The repository includes the backend, frontend, sample Spring Boot project, automated tests, and local setup instructions.
ποΈ How Code2UML AI Works
The system is built around one architectural rule:
Static analysis establishes the structure. AI explains that structure.
The pipeline is:
Spring Boot ZIP
β
Safe archive extraction
β
Deterministic Java analysis
(javalang AST + tokenizer/regex fallback)
β
Structured architecture JSON
β
Mermaid architecture + UML diagrams
β
Endpoints + observations + component catalog
β
Architecture Assistant
β
Deterministic engine OR Gemma
1. Safe ZIP extraction
The FastAPI backend accepts a Spring Boot project as a ZIP archive.
Before extraction, the archive is validated against unsafe conditions such as path traversal and oversized or suspicious archives. Files are extracted into a temporary working directory before analysis.
The upload pipeline also enforces an archive-size limit.
The goal is simple: make repository analysis convenient without treating an uploaded archive as inherently trustworthy.
2. Deterministic Java analysis
The analyzer looks for architectural signals directly in the source code.
It can identify things such as:
@RestController@Controller@Service@Repository@Entity@Table- DTOs
- Constructor injection
- Field injection
- REST endpoint mappings
- Repository-to-entity relationships
The primary parser uses javalang for Java AST analysis.
When the AST parser cannot handle a particular source construct, the analyzer can fall back to deterministic token and regex-based parsing.
There is no LLM in this stage.
That is important because the architecture should not depend on an AI model guessing what a class probably means.
3. Structured architecture
The extracted information is normalized into structured JSON.
A simplified example looks like this:
{
"roles": {
"controllers": ["UserController"],
"services": ["UserServiceImpl"],
"repositories": ["UserRepository"],
"entities": ["User"],
"dtos": ["UserDTO"]
},
"dependencies": [
{
"source": "UserController",
"target": "UserService",
"type": "injected"
}
],
"endpoints": [
{
"method": "GET",
"path": "/api/users",
"controller": "UserController"
}
]
}
This JSON becomes the structured representation used by the rest of the application.
Instead of asking a model to rediscover the architecture every time someone asks a question, the application can work from the same extracted representation.
4. Turning structure into diagrams
The architecture JSON is transformed into Mermaid representations for both architectural and UML-style views.
The frontend supports:
- Interactive diagrams
- Pan and zoom
- Full and focused views
- Endpoint inspection
- Component inspection
- Raw JSON inspection
- Mermaid copying
For larger graphs, the application can limit displayed edges so that the visualization remains usable rather than turning into an unreadable wall of connections.
5. Rule-based architectural observations
Not every useful insight needs AI.
Code2UML AI also generates deterministic observations from the extracted structure.
Examples include:
- Entities exposed directly through controllers
- Skipped architectural layers
- Service interfaces without implementations
These checks run without an LLM.
That means the core architecture analysis remains useful even when no AI model is configured.
6. The Architecture Assistant
Gemma is used at the explanation layer.
The assistant can answer architecture-focused questions such as:
βWhich service is connected to UserController?β
βWhat repository does UserServiceImpl use?β
βIs there an authentication component?β
There are two ways to answer those questions.
The deterministic engine handles supported architecture queries directly from the extracted structure.
When Gemma is configured, it receives the structured architecture as context and generates a natural-language response.
The important distinction is that Gemma is not asked to reconstruct the entire repository from raw source code.
The architecture has already been extracted.
The model is explaining the result.
ββββββββββββββββββββββββ
β Structured Analysis β
β JSON β
ββββββββββββ¬ββββββββββββ
β
βββββββββββββ΄ββββββββββββ
β β
Deterministic Engine Gemma
β β
Architecture answers Natural-language answers
When Gemma is unavailable, the deterministic engine remains available for supported questions.
7. Coverage and diagnostics
Static analysis is not perfect, so the application exposes parsing diagnostics instead of pretending that every file and relationship was understood completely.
The project tracks successful parsing, fallback parsing, failed files, and other analysis information.
This makes an important limitation visible:
If the analyzer cannot confidently extract something, the system should expose that limitation rather than silently presenting an incomplete graph as a complete one.
π§ͺ Testing
The repository currently contains a 21-test suite covering unit, integration, and browser-level behavior.
The tests cover areas including:
- Golden sample project analysis
- Expected type detection
- Relationship deduplication
- REST endpoint extraction
- Mermaid generation
- Full and default diagram views
- Controller endpoint limits
- Gemma grounding
- Database-vendor detection
- Missing-component responses
- Direct and indirect dependency questions
- Privacy boundaries
- Playwright browser flows
- Sample-project loading
- Chat Q&A
- Empty ZIP handling
- Corrupt ZIP handling
- Missing Java-file handling
The sample fixture is specifically checked for:
7 detected types + 10 deduplicated relationships + 6 packages + 4 REST endpoints
These tests are meant to verify known behavior on controlled fixtures.
They are not presented as a benchmark for large production repositories.
β οΈ Known Limitations
Code2UML AI is a static-analysis tool. It is not a complete Java program-understanding system.
There are several important limitations.
Static analysis can miss relationships that depend on runtime behavior, dynamic wiring, generated code, reflection, or other information that is not directly visible in the analyzed source.
Multi-module projects can be analyzed when their relevant Java source is included in the uploaded archive.
The generated diagrams represent extracted structure. They are not runtime execution traces.
Gemma can still produce incorrect answers. Supplying structured architecture instead of raw source narrows the problem, but it does not eliminate model errors.
The deterministic assistant only understands the architectural signals it has been designed to extract.
And the public deployment has different privacy properties from a local deployment.
I would rather make those limitations explicit than claim that AI or static analysis can perfectly understand every Spring Boot application.
π Why Open Models Matter Here
Code2UML AI uses Gemma 4, with Gemma 4 26B A4B IT used for the natural-language Architecture Assistant through the Google API integration.
The important part is not simply adding a model to the application.
The model is integrated into a system where the architecture itself is established independently.
That creates a clear separation:
Source Code
β
Deterministic Analyzer
β
Structured Architecture
β
Chosen AI Model
rather than:
Source Code
β
One AI Model
β
"Trust the explanation"
Local inference
The repository also supports OpenAI-compatible local endpoints such as Ollama.
That makes this possible:
Local Code2UML
β
Local static analysis
β
Structured architecture
β
Local Gemma
For developers working with sensitive code, this provides a path toward keeping both analysis and inference on their own machine.
Model independence
The AI endpoint and model are configurable through environment variables.
The deterministic analyzer does not need to be redesigned just because the inference provider changes.
The architecture remains:
Code β Analyzer β Structured Architecture
β
Chosen Model
The model is replaceable because it is not the component responsible for discovering the architecture.
AI is optional
This is one of the most important design decisions in the project.
Without an external AI model, Code2UML AI can still:
- Parse Java projects
- Identify Spring components
- Extract endpoints
- Build architecture diagrams
- Generate rule-based observations
- Answer supported architecture questions deterministically
Gemma adds natural-language exploration.
It does not become the source of truth.
π Privacy Model
Privacy depends on how Code2UML AI is deployed.
| Deployment | Code analysis | AI inference | Data leaving the machine |
|---|---|---|---|
| Local + local Gemma | Local | Local | None to an external AI provider |
| Local + hosted Gemma | Local | External provider | Structured architecture context is sent to the configured provider |
| Public Render demo | Render server | External Gemma API | The uploaded ZIP reaches the Render server, and structured context may be sent to the configured AI provider |
That means the public demo should not be treated as a private deployment.
For proprietary or sensitive projects, the intended approach is to run Code2UML locally and connect it to a local model endpoint.
The analyzer itself does not require an AI model to construct the architecture.
That separation is deliberate.
π Best Use of Gemma
The interesting part of the Gemma integration is not that Code2UML has a chatbot.
It is what the chatbot is given.
Gemma is provided with structured architectural information produced by deterministic analysis rather than being asked to infer the entire application architecture from raw source code.
That creates a clear division of responsibility:
Static analysis extracts the facts.
Gemma explains those facts.
For example, the system can extract:
UserController
β
UserService
β
UserRepository
β
User
and Gemma can turn that structure into an explanation a developer can understand.
When Gemma is unavailable, the deterministic engine can still answer supported architecture questions.
The model is therefore an explanation layer, not the system of record.
βοΈ Best Use of Render
Code2UML AI is deployed as a live web application on Render so judges and developers can try the project without setting up the entire stack locally.
The repository includes a Render Blueprint, and the application exposes a health endpoint at:
/api/health
The hosted flow is:
Browser
β
Render Web Service
β
FastAPI
β
Deterministic Spring Boot Analyzer
β
Structured Architecture
β
Gemma API
This makes the project immediately testable from the browser while keeping the local setup available for developers who need a private deployment.
The public demo intentionally uses the included sample project rather than asking users to upload sensitive repositories.
π― Why I Built It This Way
The most important decision in Code2UML AI was deciding what the model should not be responsible for.
A general-purpose AI code assistant can read a repository and produce an explanation that sounds convincing.
But a convincing explanation is not necessarily a structurally correct one.
So instead of asking:
βAI, understand this entire Spring Boot project.β
Code2UML AI asks a narrower question:
βHere is the architecture extracted from the code. Now explain it.β
That changes the role of the model.
The architecture is established first.
The model explains it second.
For Rahul, that means the first step into an unfamiliar codebase can start with a visual map rather than dozens of unrelated Java files.
And that is the real reason I built this.
Not to replace reading code.
Not to pretend static analysis is perfect.
Not to let an LLM confidently invent relationships.
Just to make the first hour inside an unfamiliar Spring Boot project a lot less painful.
The next feature I want to explore is deeper request-flow tracing, where Code2UML AI can follow a specific endpoint from controller through service and repository layers instead of only showing the extracted relationships.
The code determines the structure. AI helps explain it.





Top comments (0)