# How I Built a Python CLI to Scaffold Complete Projects


> Building Spawn, an open-source Python CLI that turns repetitive project setup into a configurable workflow, from templates and dependencies to Git initialization and developer tooling.

## The problem with starting a new project

Starting a new project sounds like the fun part.

In reality, there is usually a small ritual that happens before any actual development:

```bash
mkdir my-project
cd my-project

mkdir src tests docs
touch README.md .gitignore

git init

python -m venv .venv
# activate it

# install dependencies
# configure linting
# configure testing
# add CI
# add Docker
# create the usual project files...
````

None of these steps are particularly difficult.

That's exactly why they're annoying.

I've done this enough times to realize that I wasn't really solving a new problem every time I started a project.

I was repeating the same setup decisions.

So I started wondering:

> **What if the project could just be generated from those decisions?**

That became the idea behind **Spawn**.

---

## What is Spawn?

Spawn is an open-source Python CLI that generates a project foundation from a short interactive workflow.

Instead of manually creating the structure, initializing Git, setting up `uv`, installing dependencies, and wiring common development tools, you can start with:

```bash
pip install spawnio
```

and then:

```bash
spawn create
```

Spawn asks what you're building and generates the corresponding project foundation.

The goal isn't to write the application for you.

It's to get you from:

```text
"I have an idea"
```

to:

```text
"I have a structured project and can start coding"
```

with less repetitive setup in between.

---

## Designing the workflow

The first design decision was simple:

**I didn't want Spawn to be another command that required a long list of flags just to do something basic.**

So the default experience is interactive.

Running:

```bash
spawn create
```

walks through a short sequence of prompts.

The first step is the project name:

```text
Project Name: my-api
```

Then Spawn lets you choose the type of project you want to create.

```text
? Choose a template

» Backend API
  CLI Application
  Automation Tool
  AI Chatbot
  AI Agent
  RAG System
  Data Project
  MCP Server
  Custom Structure
```

The exact questions after that depend on the template.

For example, a backend project can ask which framework you want, while a data project can ask whether you're creating an analysis project, dashboard, ETL pipeline, or machine-learning project.

The important part is that the workflow is **intent-based**.

You're not starting with:

> "Which folders should I create?"

You're starting with:

> "What am I building?"

---

## Templates based on intent

Spawn currently provides eight project templates.

### 1. Backend API

Designed for REST APIs, microservices, and backend applications.

For example, a FastAPI project can start with a structure like:

```text
my-api/
├── app/
│   ├── api/routes/health.py
│   ├── core/config.py
│   ├── models/
│   ├── schemas/
│   ├── services/
│   └── main.py
├── tests/
│   └── test_health.py
├── .env.example
├── README.md
└── .gitignore
```

The supported backend frameworks are:

* FastAPI
* Flask
* Django

And optional extras include:

* Ruff
* Pytest
* Docker
* GitHub Actions

---

### 2. CLI Application

For developer tools, automation commands, project generators, and setup utilities.

A generated CLI can start with:

```text
my-cli/
├── src/
│   ├── commands/
│   ├── prompts/
│   ├── ui/
│   ├── utils/
│   └── main.py
├── tests/
├── README.md
└── .gitignore
```

The CLI type can be selected as part of the setup flow.

---

### 3. Automation Tool

For Python automation scripts and utilities that need a proper project structure instead of becoming a single giant `script.py`.

---

### 4. AI Chatbot

For starting conversational AI projects with a predefined foundation.

The workflow lets you choose the relevant provider and setup options rather than forcing every AI project into exactly the same structure.

---

### 5. AI Agent

For projects that need tool-calling and agent-style workflows.

Spawn currently supports agent setups involving PydanticAI and the OpenAI Agents SDK.

---

### 6. RAG System

For retrieval-augmented generation projects.

The current RAG template uses LlamaIndex and ChromaDB as its foundation.

---

### 7. Data Project

This one has several project types:

```text
Data Analysis
Dashboard
ETL Pipeline
Machine Learning
```

For example, the generated machine-learning project includes a starter dataset and training workflow using `RandomForestClassifier`.

---

### 8. MCP Server

Spawn also supports creating MCP servers using the official Python MCP SDK and `FastMCP`.

The generated project includes a working server with an example tool and resource.

---

## The part I didn't want to compromise on: customization

Templates are useful.

But templates can also become restrictive.

Eventually, you run into:

> "This is almost what I want... except for these seven folders."

So I added **Custom Structure**.

Instead of choosing one of the predefined templates, you can provide your own project structure.

Spawn accepts:

* Unix `tree` output
* Markdown lists
* Plain indented hierarchies

For example:

```text
app/
├── api/
├── services/
└── tests/
README.md
.gitignore
```

Spawn parses the structure, previews what it detected, and then creates it.

You can still enable the same setup features:

```text
Initialize Git? [Y/n]: Y
Initialize uv? [Y/n]: Y

Dependencies:
fastapi, uvicorn

Optional Setup:
● Ruff
● Pytest
○ Pre-commit
○ Dockerfile
```

This was important to me because I didn't want Spawn to say:

> "Use my architecture."

I wanted it to say:

> **"Bring your architecture. I'll handle the boring setup around it."**

---

## Why `uv` is part of the workflow

Python project setup often involves more than just creating folders.

There is also environment and dependency management.

Spawn can initialize `uv`, create the virtual environment, and install selected dependencies.

For example:

```bash
uv add fastapi uvicorn
```

is handled as part of the generation workflow when dependencies are selected.

This means the generated project isn't just an empty folder tree.

It has an actual development environment ready to use.

The same idea applies to optional development tooling.

If you select Ruff or Pytest, Spawn installs the relevant development dependencies and generates the associated configuration files.

---

## Making the CLI useful for automation

Interactive workflows are great for humans.

They're not always great for scripts, CI, or AI agents.

So Spawn also supports **non-interactive mode**.

For example:

```bash
spawn create \
  --name my-api \
  --template backend-api \
  --framework fastapi \
  --extras ruff,pytest \
  --git
```

No prompts.

You can also describe the project in a JSON configuration file:

```json
{
  "name": "my-api",
  "template": "backend-api",
  "framework": "fastapi",
  "extras": [
    "ruff",
    "pytest"
  ],
  "git": true,
  "uv": true
}
```

Then:

```bash
spawn create --config spawn.json
```

There is also a `--dry-run` option for validating the configuration and printing it without creating the project.

This was one of the more important additions to Spawn because a project generator shouldn't only work when someone is sitting at a keyboard answering prompts.

---

## Making generated projects more AI-friendly

Another thing I wanted to experiment with was giving generated projects useful context for coding agents.

Spawn automatically includes an `AGENTS.md` file in generated projects.

There is also a `--claude-md` option that generates a corresponding `CLAUDE.md`.

The idea is simple:

When an AI coding agent enters a freshly generated project, there should already be some project-level context available instead of starting from a completely blank slate.

It's a small feature, but it fits the direction developer tooling is moving toward.

---

## `spawn doctor`

After building a generator, I wanted to solve another problem:

> What happens after the project already exists?

That's where:

```bash
spawn doctor
```

comes in.

It analyzes the project and produces a health score out of 100.

For example:

```text
╭─────────────── 🏥 Project Health Report ─────────────────╮
│                                                           │
│  🟡 Good                                                  │
│  Some improvements recommended.                           │
│                                                           │
│  Project Score: 82%                                       │
│                                                           │
│  Documentation — 67                                       │
│  Version Control — 100                                    │
│  Configuration — 75                                       │
│  Testing — 80                                             │
│  Automation — 50                                          │
│  Code Quality — 100                                       │
│                                                           │
╰───────────────────────────────────────────────────────────╯
```

It then gives recommendations grouped by priority and identifies a single:

**Next Best Step**

The checks cover:

* Documentation
* Version Control
* Configuration
* Testing
* Automation
* Code Quality

The checks are filesystem-based. Spawn doesn't execute the project or send it over the network as part of this health check.

---

## Publishing to GitHub

Spawn can also help with the first GitHub push after project creation.

If Git was enabled, the workflow can ask:

```text
Publish to GitHub? [y/N]: y

Repository URL:
https://github.com/your-username/my-project
```

Spawn then stages the files, creates the initial commit, switches the branch to `main`, adds the remote, and pushes.

One intentional limitation:

**The GitHub repository must already exist.**

Spawn connects to it. It doesn't create the repository itself.

---

## Installing Spawn

The easiest way to get started is through PyPI:

```bash
pip install spawnio
```

You can also install it as a `uv` tool:

```bash
uv tool install spawnio
```

Or run it without installing it permanently:

```bash
uvx --from spawnio spawn create
```

Then:

```bash
spawn create
```

and you're off.

---

## Where Spawn is today

Spawn is currently published on PyPI as `spawnio`.

The project has evolved through several iterations.

Some of the features that have landed along the way include:

* Intent-based project templates
* Custom project structures
* `spawn doctor`
* Non-interactive generation
* MCP Server scaffolding
* Data project generation
* Agent context files
* Arrow-key driven prompts
* GitHub publishing
* PyPI distribution

The current version is focused on making the boring first 5–10 minutes of a project much shorter.

But there is still plenty to improve.

---

## What I want to improve next

I don't want Spawn to become a giant collection of random templates.

The goal is to make it genuinely useful.

That means I need feedback from people who actually build projects.

Some questions I'm currently thinking about:

* What project types should be added?
* Which templates are actually useful?
* Which setup steps should be automated?
* What does Spawn currently get wrong?
* Should more tools be supported as optional extras?
* What would make the non-interactive mode better for agents and automation?
* What would make you choose Spawn over creating a project manually?

Those answers are probably more valuable than anything I can come up with alone.

---

## Open source means I don't have to guess

Spawn is open source, and contributions are welcome.

If you want to add a new project intent, the project has a template system for doing exactly that.

A new intent can be added under:

```text
src/spawn/templates/your_intent/
```

and registered through the template registry.

Tests should be added alongside the new functionality.

Before submitting a PR:

```bash
uv run pytest
uv run ruff check .
```

If you have an idea for a new template, find a bug, or think the whole concept is unnecessary, I'd genuinely like to hear about it.

Especially the last one.

A developer tool should earn its place in someone's workflow.

---

## Try it

If repetitive Python project setup annoys you as much as it annoyed me:

```bash
pip install spawnio
```

Then:

```bash
spawn create
```

The project is open source:

**GitHub:**
[https://github.com/Abhiix0/spawn](https://github.com/Abhiix0/spawn)

**PyPI:**
[https://pypi.org/project/spawnio/](https://pypi.org/project/spawnio/)

---

## I'd love your feedback

This is the part I'm most interested in.

If you build Python projects, **what is the setup step you find yourself repeating every single time?**

Maybe it's:

* project structure
* dependency setup
* Docker
* CI
* testing
* linting
* environment configuration
* Git setup
* something completely different

Tell me what it is.

I'm building Spawn, but I'd rather build the tool developers actually want than the tool I *think* they want.

---

**Thanks for reading.**

Now back to building. 🐍


