This document explains the architecture and design of litestar-start, a CLI tool for scaffolding Litestar projects.
litestar-start is an interactive CLI tool that helps developers quickly scaffold new Litestar projects with optional plugins like AdvancedAlchemy ORM.
src/
├── __init__.py # Package metadata and version
├── cli.py # Main CLI entry point with questionary prompts
├── generator.py # Project generator orchestrator
├── models.py # Data models using msgspec
├── utils.py # Utility functions (templating, validation)
└── Litestar/ # Litestar framework templates
├── __init__.py
├── generator.py # Litestar-specific generation logic
├── Config/ # Project configuration templates
│ ├── pyproject.toml.jinja
│ ├── gitignore.jinja
│ ├── env.example.jinja
│ └── readme.md.jinja
├── App/ # Core application templates
│ └── *.jinja
├── Containers/ # Docker templates
│ ├── Dockerfile.jinja
│ ├── docker-compose.yml.jinja
│ └── docker-compose.infra.yml.jinja
└── Plugins/ # Optional plugin templates
├── __init__.py
├── AdvancedAlchemy/
│ ├── __init__.py
│ └── Templates/
├── LitestarSAQ/
│ ├── __init__.py
│ └── Templates/
├── LitestarVite/
│ ├── __init__.py
│ └── Templates/
└── LitestarGranian/
└── __init__.py
The CLI is the entry point for the tool. It uses:
- questionary - For interactive prompts
- rich - For beautiful console output
Flow:
- Display welcome banner
- Ask for project name
- Ask for backend framework (currently only Litestar)
- Ask for database choice
- Ask for plugins (based on database choice)
- Ask for Docker configuration
- Display summary and confirm
- Generate project
Uses msgspec for efficient data serialization. Key models:
- Framework - Enum of supported frameworks (Litestar, future: FastAPI)
- Database - Enum of database options (PostgreSQL, SQLite, MySQL, None)
- MemoryStore - Enum of memory store options (Redis, Valkey, None)
- ProjectConfig - Main configuration struct containing all user choices
- DatabaseConfig - Database-specific configuration (driver, port, URL)
The orchestrator that delegates to framework-specific generators. Currently supports:
LitestarGenerator- Generates Litestar projects
Handles the actual file generation:
- Config Files - Generates
pyproject.toml,.gitignore,.env.example,README.md - Base Application - Generates core
app/directory with main.py, config.py - Plugins - Generates plugin-specific files (db/, auth/) if selected
- Containers - Generates Docker files if requested
All templates use Jinja2 with .jinja extension. Template context includes:
project_name- Human-readable nameproject_slug- Python-safe namedatabase- Selected database enumadvanced_alchemy- Boolean flagdocker- Boolean flag
-
Create plugin directory under the framework's
Plugins/directory:src/Litestar/Plugins/NewPlugin/ ├── __init__.py └── Templates/ └── *.jinja -
In
__init__.py, create a class that extendsBasePlugin:from src.models import ProjectConfig from src.plugin import BasePlugin class NewPlugin(BasePlugin): """Description of the plugin.""" @property def name(self) -> str: """Get the plugin display name.""" return "New Plugin" @property def description(self) -> str: """Get the plugin description.""" return "Description for the CLI" def is_applicable(self, config: ProjectConfig) -> bool: """Check if this plugin is applicable.""" return True # or check config fields
-
The plugin will be automatically discovered by
discover_plugins(). No enum or CLI changes are needed. -
Add Jinja2 templates in the
Templates/subdirectory. They will be rendered intosrc/backend/of the generated project.
-
Create framework directory:
src/NewFramework/ ├── __init__.py ├── generator.py ├── App/ ├── Config/ ├── Containers/ └── Plugins/ -
Add to
Frameworkenum inmodels.py -
Create
NewFrameworkGeneratorclass ingenerator.py -
Update main
generator.pyto handle the new framework -
Update CLI to enable the framework option
-
Add to
Databaseenum inmodels.py -
Add configuration in
DatabaseConfig.for_database():Database.NEW_DB: cls( driver="newdb+async", port=1234, default_url="newdb+async://...", docker_image="newdb:latest", )
-
Update templates that reference database configuration
Templates are rendered using Jinja2 with these settings:
trim_blocks=True- Removes first newline after block taglstrip_blocks=True- Strips leading whitespace from block lineskeep_trailing_newline=True- Preserves trailing newlines
| Variable | Type | Description |
|---|---|---|
project |
ProjectConfig |
Full project configuration |
project_name |
str |
Human-readable project name |
project_slug |
str |
Python-safe name |
database |
Database |
Selected database enum |
db_config |
DatabaseConfig |
Database configuration |
advanced_alchemy |
bool |
AdvancedAlchemy plugin enabled |
has_database |
bool |
Any database selected |
docker |
bool |
Dockerfile requested |
docker_infra |
bool |
Infra compose requested |
A typical generated project looks like:
my_project/
├── src/
│ └── backend/
│ ├── __init__.py
│ ├── app.py
│ ├── config.py
│ ├── models/ # If AdvancedAlchemy selected
│ │ └── users.py
│ └── lib/ # If plugins are selected
│ ├── dependencies.py
│ ├── services.py
│ └── tasks.py # If SAQ selected
├── .env.example
├── .gitignore
├── pyproject.toml
├── README.md
├── Dockerfile # If Docker selected
├── docker-compose.yml # If Docker selected
└── docker-compose.infra.yml # If Docker infra selected
- questionary - Interactive CLI prompts
- rich - Terminal formatting and output
- jinja2 - Template rendering
- msgspec - Fast data serialization
- Add FastAPI framework support
- Add more plugins (Structlog, CORS)
- Add test scaffolding for generated projects
- Add CI workflow for generated projects