Templates¶
UV Forger uses a JSON-based template system to define project structures. Templates live in uv_forger/config/templates/ and determine which folders, files, and packages are created for each project.
Template directory layout¶
uv_forger/config/templates/
├── ui_frameworks/ # One JSON per UI framework
│ ├── flet.json
│ ├── pyqt6.json
│ ├── default.json # Fallback template
│ └── ...
├── project_types/ # One JSON per project type
│ ├── django.json
│ ├── fastapi.json
│ └── ...
└── boilerplate/ # Starter file content
├── common/ # Shared across all project types
│ ├── async_executor.py
│ └── constants.py
└── ui_frameworks/ # Framework-specific starter code
└── flet/
├── main.py
├── state.py
└── components.py
Template format¶
Each template is a JSON file defining a list of FolderSpec structures:
[
{
"name": "core",
"create_init": true,
"root_level": false,
"subfolders": [],
"files": ["state.py", "models.py"]
},
{
"name": "tests",
"create_init": true,
"root_level": true,
"subfolders": [],
"files": []
}
]
| Field | Type | Description |
|---|---|---|
name |
string | Folder name |
create_init |
boolean | Whether to create __init__.py in this folder |
root_level |
boolean | true = created at project root, false = inside app/ |
subfolders |
array | Nested FolderSpec objects |
files |
array | Filenames to create in this folder |
Loading fallback chain¶
When you select a UI framework, templates are loaded in this order:
- Framework-specific template — e.g.,
ui_frameworks/flet.json - Default template —
ui_frameworks/default.json - Hardcoded defaults —
DEFAULT_FOLDERSinconstants.py
The first one found is used. Project type templates follow the same pattern with their own directory.
Template merging¶
When you select both a UI framework and a project type, UV Forger merges their templates:
- Matching folders (same name) are merged recursively — files are unioned,
create_initandroot_levelare OR'd, subfolders are merged the same way - Unmatched folders from both templates are included as-is
- The UI framework template takes priority for ordering
This means selecting "Flet" + "FastAPI" gives you a project with the folder structures from both, intelligently combined rather than duplicated.
Smart scaffolding (boilerplate)¶
When files are created during a build, UV Forger looks for starter content instead of creating empty files. The lookup follows a fallback chain:
flowchart TD
A[File created during build] --> B{User template exists?}
B -- yes --> U[Use user template]
B -- no --> C{Framework boilerplate exists?}
C -- yes --> F[Use framework boilerplate]
C -- no --> D{Project type boilerplate exists?}
D -- yes --> P[Use project type boilerplate]
D -- no --> E{Common boilerplate exists?}
E -- yes --> K[Use common boilerplate]
E -- no --> T[Create empty file]
- User templates — persistent custom content saved from the file editor (highest priority)
boilerplate/ui_frameworks/{framework}/{filename}— framework-specific (e.g., Flet'smain.py)boilerplate/project_types/{project_type}/{filename}— project-type-specificboilerplate/common/{filename}— shared utilities- Empty file — if no boilerplate exists (zero breakage risk)
Boilerplate files can use {{project_name}} as a placeholder. At build time, it's replaced with a title-case version of the project name (e.g., my_app becomes My App).
User templates are stored in the platform data directory by default (e.g., ~/.config/UV Forger/templates/boilerplate/ on Linux) or at a custom path configured in Settings.
File content editing¶
Right-click any file in the folder tree to open a context menu with four actions:
| Action | Description |
|---|---|
| Preview Content | Read-only view of the file's boilerplate or custom content |
| Edit Content... | Opens a full-screen code editor |
| Import from File... | Load content from an existing file on disk |
| Reset to Default | Remove custom overrides and revert to boilerplate |
Right-click any folder to see:
| Action | Description |
|---|---|
| Import Folder from Disk... | Pick a directory from disk and import it as a subfolder with all its contents |
You can also select a file and click the Edit File button (pencil icon) in the Folders section toolbar.
Browse button (Add File dialog)¶
When adding a new file via the Add Folder/File dialog, switch the type to "File" to reveal a Browse... button. Clicking it opens a file picker — the selected file's name auto-fills the name field (editable) and its content is stored in the project's file overrides. This lets you import an existing file from disk in a single step, instead of adding a blank file and then right-clicking to import.
Import from Disk (Add Folder dialog)¶
When adding a new folder via the Add Folder/File dialog (with type set to "Folder"), an Import from Disk... button appears. Clicking it opens a directory picker — the selected folder is scanned recursively and its entire structure (subfolders and file contents) is imported into the project template.
The scanner:
- Reads up to 5 levels deep and 50 files
- Imports text files with common extensions (
.py,.json,.yaml,.toml,.md,.html,.css,.js,.ts, and more) - Skips hidden directories,
.git,__pycache__,node_modules,.venv, and other build/cache directories - Skips binary and non-UTF-8 files silently
After scanning, a summary line shows how many folders, files, and skipped items were found. The folder name auto-fills from the picked directory but is editable before adding.
Import Folder via right-click¶
Right-click any folder in the project tree to see an Import Folder from Disk... context menu item. This uses the same scanning logic as the Add Folder dialog but imports the directory directly as a subfolder of the clicked folder — no dialog needed.
Both methods store all imported file contents in the project's file overrides, so the content will be written into the built project instead of using boilerplate.
Editor features¶
The full-screen editor is powered by fce-enhanced and includes:
- Syntax highlighting — Python, JSON, YAML, HTML, CSS, JavaScript, and more (language auto-detected from file extension)
- Search & replace — Cmd+F to search, Cmd+Alt+F for search & replace
- Diff pane — Cmd+D to compare your changes side-by-side with the original
- Go to line — Cmd+G
- Command palette — Cmd+Shift+P
- Font zoom — Cmd++ / Cmd+-
- Read-only toggle — Cmd+L
On Windows/Linux, replace Cmd with Ctrl.
See Keyboard Shortcuts for the full shortcut list.
Custom content indicators¶
Files with custom content (edited or imported) show a ✎ pencil indicator in the folder tree. These overrides take priority over boilerplate during the build and survive template reloads. To persist your customized folder structure and packages for reuse, save it as a preset.
User templates¶
When you save from the editor (Cmd+S), your content is persisted to a user templates directory. These user templates sit at the top of the boilerplate fallback chain, so they override built-in content for all future projects.
- The default storage location is platform-dependent:
~/Library/Application Support/UV Forger/templates/boilerplate/on macOS%LOCALAPPDATA%/UV Forger/on Windows~/.config/UV Forger/templates/boilerplate/on Linux
- You can set a custom path in Settings.
Adding a new template¶
New UI framework¶
- Add the framework name to
UI_FRAMEWORKSinuv_forger/core/constants.py - Add its package to
FRAMEWORK_PACKAGE_MAPin the same file - Add a display entry to
UI_FRAMEWORK_CATEGORIESinuv_forger/ui/dialog_data.py - Create
uv_forger/config/templates/ui_frameworks/<name>.json - Optionally add boilerplate files to
uv_forger/config/templates/boilerplate/ui_frameworks/<name>/
New project type¶
- Add the type and its packages to
PROJECT_TYPE_PACKAGE_MAPinuv_forger/core/constants.py - Add a display entry to
PROJECT_TYPE_CATEGORIESinuv_forger/ui/dialog_data.py - Create
uv_forger/config/templates/project_types/<name>.json - Optionally add boilerplate files to
uv_forger/config/templates/boilerplate/project_types/<name>/
Tip
Adding boilerplate is just dropping files into the right directory — no code changes needed. Look at existing templates for reference.