fledge 0.2.1

Corvid-themed project scaffolding CLI — get your projects ready to fly.
fledge-0.2.1 is not a library.

fledge

Get your projects ready to fly.

A fast, opinionated project scaffolding CLI built in Rust. Create new projects from templates — local or remote — with smart defaults, Tera-powered rendering, and zero boilerplate.

Why fledge?

  • Fast — native Rust binary, no runtime dependencies
  • Smart defaults — pulls author/org from git config, renders dates, computes name variants automatically
  • Remote templates — use any GitHub repo as a template source with owner/repo syntax
  • Extensible — create your own templates with a simple template.toml manifest
  • Safe — remote template hooks require explicit confirmation before running
  • Optional TUI — interactive template browser with --features tui

Install

# From crates.io
cargo install fledge

# With TUI support
cargo install fledge --features tui

# From source
git clone https://github.com/CorvidLabs/fledge.git
cd fledge && cargo install --path .

Quick Start

# Create a new Rust CLI project
fledge init my-tool --template rust-cli

# Browse templates interactively
fledge init my-project

# Use a remote GitHub template
fledge init my-app --template CorvidLabs/fledge-templates/react-app

# Preview what would be created
fledge init my-tool --template rust-cli --dry-run

# Skip all prompts with defaults
fledge init my-tool --template rust-cli --yes

# List available templates
fledge list

Built-in Templates

Template Description
rust-cli Rust CLI application with clap, CI, and release automation
rust-lib Rust library crate with docs and publishing workflow
swift-pkg Swift package with Package.swift, CI, and coding conventions
ts-bun TypeScript project with Bun runtime
angular-app Angular application with mobile-first setup

CLI Reference

fledge init <name>

Create a new project from a template.

fledge init <name> [OPTIONS]

Arguments:
  <name>              Project name

Options:
  -t, --template      Template to use (skip interactive selection)
  -o, --output        Parent directory for the project [default: .]
      --no-git        Skip git init and initial commit
      --no-install    Skip dependency installation (post-create hooks)
      --refresh       Force re-clone of cached remote templates
      --dry-run       Show what would be created without writing anything
  -y, --yes           Skip all confirmation prompts (accept defaults)

fledge list

List all available templates (built-in + configured).

fledge tui (requires --features tui)

Interactive terminal UI for browsing templates and scaffolding projects. Navigate with arrow keys, fill in variables with Tab, confirm with Enter.

fledge tui [OPTIONS]

Options:
  -o, --output        Parent directory for the project [default: .]
      --no-git        Skip git init and initial commit

fledge completions <shell>

Generate shell completions for your shell. Supported: bash, zsh, fish, powershell.

# Bash
fledge completions bash >> ~/.bashrc

# Zsh
fledge completions zsh > ~/.zfunc/_fledge

# Fish
fledge completions fish > ~/.config/fish/completions/fledge.fish

Remote Templates

Any GitHub repository can be a template source. Use owner/repo syntax:

# Use a single-template repo
fledge init my-app --template user/my-template

# Use a specific template from a collection
fledge init my-app --template CorvidLabs/templates/python-api

# Force re-download of a cached template
fledge init my-app --template user/my-template --refresh

Remote templates are cloned and cached locally. Post-create hooks from remote templates always require confirmation unless --yes is passed.

Template Repositories

You can register template repos in your config so they appear in fledge list:

# ~/.config/fledge/config.toml
[templates]
repos = ["CorvidLabs/fledge-templates", "myorg/templates"]

Configuration

fledge reads from ~/.config/fledge/config.toml:

[defaults]
author = "Your Name"
github_org = "YourOrg"
license = "MIT"           # default license for new projects

[templates]
paths = ["~/my-templates"]                     # additional local template directories
repos = ["CorvidLabs/fledge-templates"]         # GitHub repos to include in template list

[github]
token = "ghp_..."         # for private template repos (also reads FLEDGE_GITHUB_TOKEN / GITHUB_TOKEN env vars)

If author is not set, fledge falls back to git config user.name. The GitHub token is checked in order: FLEDGE_GITHUB_TOKEN env var → GITHUB_TOKEN env var → config file.

Creating Templates

A template is a directory with a template.toml manifest and any number of files. Files are rendered through Tera (a Jinja2-like engine) before being written.

Directory Structure

my-template/
├── template.toml          # manifest (required)
├── src/
│   └── main.rs            # template files — Tera syntax supported
├── README.md
├── Cargo.toml
└── .github/
    └── workflows/
        └── ci.yml

template.toml Reference

[template]
name = "my-template"                           # template name (used in --template flag)
description = "A short description"            # shown in fledge list
min_fledge_version = "0.1.0"                   # optional minimum fledge version

[prompts]
# Each key becomes a template variable. Values have `message` and optional `default`.
description = { message = "Project description", default = "A new project" }
port = { message = "Default port", default = "3000" }

# Defaults can use Tera expressions referencing earlier variables:
repo_url = { message = "Repository URL", default = "https://github.com/{{ github_org }}/{{ project_name }}" }

[files]
render = ["**/*.rs", "**/*.toml", "**/*.md", "**/*.yml"]   # files to render through Tera
copy = ["**/*.png", "**/*.ico"]                             # files to copy as-is (binary files)
ignore = ["template.toml"]                                  # files to exclude from output

[hooks]
post_create = ["cargo fmt", "npm install"]     # commands to run after scaffolding

Built-in Variables

These are always available in your templates — no need to define them in [prompts]:

Variable Description Example
project_name The project name as provided by the user my-cool-app
project_name_snake Snake case version my_cool_app
project_name_pascal PascalCase version MyCoolApp
author From config, git, or prompted Leif
github_org From config or prompted (default: CorvidLabs) CorvidLabs
license From config (default: MIT) MIT
year Current year 2026
date Current date 2026-04-18

Tera Syntax

Templates use Tera syntax:

# {{ project_name }}

{{ description }}

## Author

Created by {{ author }} ({{ github_org }}) in {{ year }}.

{% if license == "MIT" %}
This project is MIT licensed.
{% endif %}

File Rules

  • render — glob patterns for files that should be processed through Tera. Template variables ({{ project_name }}, etc.) are replaced with actual values.
  • copy — glob patterns for files that should be copied as-is. Use for binary files (images, fonts) that would break if parsed.
  • ignore — glob patterns for files to exclude from the output entirely. template.toml should always be listed here.

Files not matching any rule are rendered by default.

Post-Create Hooks

Commands listed in hooks.post_create run inside the newly created project directory after all files are written. Use them for dependency installation, formatting, or other setup:

[hooks]
post_create = ["bun install", "bun run format"]

For local (built-in) templates, hooks run automatically. For remote templates, fledge shows the commands and asks for confirmation before running — unless --yes is passed.

Testing Templates Locally

Point fledge at your template directory during development:

# Add your template directory to config
# ~/.config/fledge/config.toml
[templates]
paths = ["~/dev/my-templates"]

# Or use it directly as a remote-style path
fledge init test-project --template ./my-template

Then iterate: edit template files, run fledge init test-output --template my-template, inspect the output, delete and repeat.

Example: Creating a Template from Scratch

mkdir my-template && cd my-template

Create template.toml:

[template]
name = "python-api"
description = "Python FastAPI project with Docker"

[prompts]
description = { message = "Project description", default = "A FastAPI application" }
python_version = { message = "Python version", default = "3.12" }

[files]
render = ["**/*.py", "**/*.toml", "**/*.md", "**/*.yml", "Dockerfile"]
ignore = ["template.toml"]

[hooks]
post_create = ["python -m venv .venv"]

Create template files using Tera variables:

# app/main.py
"""{{ description }}"""
from fastapi import FastAPI

app = FastAPI(title="{{ project_name_pascal }}")

@app.get("/")
def root():
    return {"name": "{{ project_name }}"}
# Dockerfile
FROM python:{{ python_version }}-slim
WORKDIR /app
COPY . .
RUN pip install -e .
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0"]

Test it:

fledge init test-api --template python-api --dry-run
fledge init test-api --template python-api

License

MIT