Java Project Input/Output — Spring Boot scaffolding CLI
Project description
JPIO — Java Project Input/Output
A CLI tool that scaffolds production-ready Spring Boot projects in seconds. Stop writing boilerplate. Start building features.
Table of Contents
- Overview
- Why JPIO?
- Installation
- Quick Start
- Commands
- Project Architecture
- Generated Structure
- Supported Relations
- Roadmap
- Contributing
Overview
JPIO (Java Project Input/Output) is an open-source Python CLI that automates the creation of Spring Boot project scaffolding. You describe your entities and their relationships interactively in the terminal — JPIO generates all the layers: Entity, DTO, Mapper, Repository, Service, ServiceImpl, Controller, and Exceptions.
Built for developers who are tired of copy-pasting the same boilerplate across every new project.
Why JPIO?
Every Spring Boot project starts the same way:
mkdir config controller entity dto mapper repository service exception
Then you write the same JpaRepository interfaces, the same CRUD controllers, the same GlobalExceptionHandler, the same SwaggerConfig... over and over again.
JPIO eliminates that entirely.
| Without JPIO | With JPIO |
|---|---|
| ~30–60 min of boilerplate setup | ~2 minutes |
| Manual folder creation | Auto-generated structure |
| Copy-paste error-prone | Template-driven, consistent |
| Forgotten files | Nothing is missed |
Installation
pip install jpio
Requirements:
- Python 3.9+
- pip
Quick Start
# Create a new Spring Boot project
jpio new
# Follow the interactive prompts:
# ? Project name : ecommerce-api
# ? Base package : com.yourname.ecommerce
# ? Database : MySQL
#
# --- Entity 1 ---
# ? Entity name : Product
# ? Fields : name (String), price (Double), stock (Integer)
# ? Has relations? : Yes → ManyToMany → Category
#
# --- Entity 2 ---
# ? Entity name : Category
# ? Fields : name (String)
#
# ? Add another entity? No
#
# ✅ Project generated in ./ecommerce-api/
Commands
| Command | Description |
|---|---|
jpio new |
Create a new Spring Boot project interactively |
jpio add |
Add a new entity to an existing JPIO project |
jpio scan |
Display the current state of a JPIO project |
jpio new
Launches the full interactive wizard. Asks for project metadata (name, package, database), then collects entities and their fields and relations. Generates the complete project structure.
jpio add
Run inside an existing JPIO project. Prompts for a new entity and appends the generated files without touching existing code. Reads .jpio.json to stay aware of existing entities.
jpio scan
Reads .jpio.json and displays a summary table of the project: entities, fields, relations, and generated files.
Project Architecture
This section describes the internal architecture of JPIO itself (the CLI tool).
jpio/
├── jpio/
│ ├── main.py # CLI entry point (Click)
│ ├── commands/
│ │ ├── new.py # `jpio new` — full project wizard
│ │ ├── add_entity.py # `jpio add` — add entity to existing project
│ │ └── scan.py # `jpio scan` — display project state
│ ├── core/
│ │ ├── models.py # Dataclasses: Field, Relation, Entity, ProjectConfig
│ │ ├── analyzer.py # Interactive prompts → builds ProjectConfig
│ │ ├── generator.py # ProjectConfig → Jinja2 render → Java code strings
│ │ └── writer.py # Java code strings → files on disk
│ ├── utils/
│ │ ├── console.py # Rich: colors, spinners, tables, success/error output
│ │ └── file_helper.py # Path manipulation, mkdir, safe file operations
│ └── templates/
│ ├── entity/
│ │ ├── entity.java.j2 # JPA Entity class
│ │ ├── dto.java.j2 # Data Transfer Object
│ │ ├── mapper.java.j2 # DTO <-> Entity mapper
│ │ ├── repository.java.j2 # Spring Data JPA repository
│ │ ├── service.java.j2 # Service interface
│ │ ├── service_impl.java.j2 # Service implementation
│ │ ├── controller.java.j2 # REST controller (CRUD)
│ │ └── not_found_exception.java.j2 # EntityNotFoundException
│ ├── exception/
│ │ └── global_exception_handler.java.j2 # @ControllerAdvice handler
│ ├── config/
│ │ └── swagger_config.java.j2 # SpringDoc OpenAPI config
│ └── project/
│ ├── pom.xml.j2 # Maven dependencies
│ └── application.properties.j2 # Spring Boot config
├── tests/
│ ├── test_analyzer.py
│ ├── test_generator.py
│ └── test_writer.py
├── pyproject.toml
├── README.md
└── .jpio.json # Project snapshot (entities, relations, config)
Data Flow
jpio new
│
▼
analyzer.py ← interactive prompts (questionary)
│ returns ProjectConfig
▼
generator.py ← Jinja2 renders templates
│ returns { filepath: java_code_string }
▼
writer.py ← creates directories and files on disk
│
▼
console.py ← prints success report
│
▼
.jpio.json ← saves project snapshot for future `add` and `scan`
Core Models (core/models.py)
@dataclass
class Field:
name: str # e.g. "price"
type: str # e.g. "Double"
nullable: bool
@dataclass
class Relation:
kind: str # "OneToMany" | "ManyToMany" | "ManyToOne"
target: str # e.g. "Category"
mapped_by: str # owning side field name
@dataclass
class Entity:
name: str # e.g. "Product"
fields: list[Field]
relations: list[Relation]
@dataclass
class Enum:
name: str # e.g. "Role"
values: list[str] # e.g. ["USER", "ADMIN"]
@dataclass
class ProjectConfig:
project_name: str
base_package: str
database: str
entities: list[Entity]
enums: list[Enum]
Generated Structure
For a project ecommerce-api with package com.pio.ecommerce and two entities Product and Category:
ecommerce-api/
├── pom.xml
└── src/
└── main/
├── java/
│ └── com/pio/ecommerce/
│ ├── EcommerceApiApplication.java
│ ├── config/
│ │ └── SwaggerConfig.java
│ ├── controller/
│ │ ├── ProductController.java
│ │ └── CategoryController.java
│ ├── dto/
│ │ ├── request/
│ │ │ ├── ProductRequestDTO.java
│ │ │ └── CategoryRequestDTO.java
│ │ └── response/
│ │ ├── ProductResponseDTO.java
│ │ └── CategoryResponseDTO.java
│ ├── exception/
│ │ ├── GlobalExceptionHandler.java
│ │ ├── ProductNotFoundException.java
│ │ └── CategoryNotFoundException.java
│ ├── mapper/
│ │ ├── ProductMapper.java
│ │ └── CategoryMapper.java
│ ├── models/
│ │ ├── entity/
│ │ │ ├── Product.java
│ │ │ └── Category.java
│ │ └── enum/
│ │ └── Role.java
│ ├── repository/
│ │ ├── ProductRepository.java
│ │ └── CategoryRepository.java
│ └── service/
│ ├── ProductService.java
│ ├── ProductServiceImpl.java
│ ├── CategoryService.java
│ └── CategoryServiceImpl.java
└── resources/
└── application.properties
Supported Relations
| Relation | Description | Example |
|---|---|---|
OneToMany |
One entity has many of another | Order → OrderItem |
ManyToOne |
Many entities belong to one | OrderItem → Order |
ManyToMany |
Both sides have many | Product ↔ Category |
Relations are declared interactively. JPIO automatically handles:
- The
@JoinTableannotation forManyToMany - The
mappedByattribute on the inverse side - The correct field type (
List<TargetEntity>)
Roadmap
- MVP: interactive wizard + full CRUD scaffold generation
- OneToMany / ManyToMany relation support
-
jpio addcommand for existing projects -
jpio scanproject inspector - Enums support & Request/Response DTO separation (v0.2.0)
-
jpio add enumcommand for existing projects - IntelliJ IDEA plugin
- VS Code extension
- Spring Security scaffolding (optional layer)
- Lombok support toggle
- MapStruct vs manual mapper toggle
Contributing
Contributions are welcome. Please open an issue before submitting a pull request to discuss the proposed change.
git clone https://github.com/PIO-VIA/JPIO.git
cd JPIO
pip install -e ".[dev]"
License
MIT © PIO
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jpio_cli-0.4.0.tar.gz.
File metadata
- Download URL: jpio_cli-0.4.0.tar.gz
- Upload date:
- Size: 32.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bed88c2f1f70279831dfcfda4549bb0f8252ab038c5778462ea8eceaafde66f3
|
|
| MD5 |
9c629bd51939f38acd69c4f19abbf2be
|
|
| BLAKE2b-256 |
8ed13cfcc9e07c008b54c4fb0758581e57e6b151046f03a7890192557c79a935
|
Provenance
The following attestation bundles were made for jpio_cli-0.4.0.tar.gz:
Publisher:
publish.yml on PIO-VIA/JPIO
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jpio_cli-0.4.0.tar.gz -
Subject digest:
bed88c2f1f70279831dfcfda4549bb0f8252ab038c5778462ea8eceaafde66f3 - Sigstore transparency entry: 1423171021
- Sigstore integration time:
-
Permalink:
PIO-VIA/JPIO@57e280eac5c9472ba66230c6ff82ac90a0da7bdf -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/PIO-VIA
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@57e280eac5c9472ba66230c6ff82ac90a0da7bdf -
Trigger Event:
release
-
Statement type:
File details
Details for the file jpio_cli-0.4.0-py3-none-any.whl.
File metadata
- Download URL: jpio_cli-0.4.0-py3-none-any.whl
- Upload date:
- Size: 33.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
523c196f943bfb8b46a1b88d61f5999de53096701f3ff12fbc4512ad68e289da
|
|
| MD5 |
3c171d42c8da14a589e67a91623582bb
|
|
| BLAKE2b-256 |
3064558026e45ce8fcc3bf03833ed1a12d99e0bee2d11d8e0a79034a4f85f172
|
Provenance
The following attestation bundles were made for jpio_cli-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on PIO-VIA/JPIO
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jpio_cli-0.4.0-py3-none-any.whl -
Subject digest:
523c196f943bfb8b46a1b88d61f5999de53096701f3ff12fbc4512ad68e289da - Sigstore transparency entry: 1423171113
- Sigstore integration time:
-
Permalink:
PIO-VIA/JPIO@57e280eac5c9472ba66230c6ff82ac90a0da7bdf -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/PIO-VIA
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@57e280eac5c9472ba66230c6ff82ac90a0da7bdf -
Trigger Event:
release
-
Statement type: