Folder Structure Matters: My Python Project Template Explained
Here’s the folder structure I use to keep my Python projects clean, scalable, and ready for production — plus why it works.

Most Python projects don’t fail because of bad code — they fail because they’re impossible to maintain.
Folder Structure Matters: My Python Project Template Explained
If there’s one thing that separates beginner code from professional-grade software, it’s structure.
Over the years, I’ve worked on everything from quick scripts to full-blown production systems in Python.
And no matter the size of the project, one lesson stands out:
Your folder structure is not just about organizing files — it’s about scaling sanity.
In this article, I’ll walk you through the Python project template I’ve honed through trial, error, and late-night refactors.
It’s simple, scalable, and battle-tested.
My Go-To Python Project Template
Here’s the folder structure I use for almost every Python project — from APIs to CLI tools:
my_project/
│
├── src/
│ └── my_project/ ← Application code lives here
│ ├── __init__.py
│ ├── config.py
│ ├── main.py
│ ├── utils/
│ │ └── __init__.py
│ └── modules/
│ ├── __init__.py
│ ├── auth.py
│ └── data.py
│
├── tests/ ← Unit and integration tests
│ ├── __init__.py
│ └── test_main.py
│
├── .env ← Environment variables
├── .gitignore
├── pyproject.toml ← Project metadata and dependencies
├── README.md
└── requirements.txt ← (optional) Pinned dependencies for pip users
Inside the Structure
1. src/
and the Double Folder Trick
Putting your actual app inside src/
and then a second my_project/
inside it seems redundant, but here’s why I do it:
- It prevents import shadowing. With this pattern, running tests from the root won’t mistakenly import files from the wrong places.
- It clearly separates source code from test, config, and infra files.
Set your PYTHONPATH
to src/
in dev environments.
2. config.py
: Centralized Settings
All environment-based settings go here — API keys, database URLs, debug flags.
You can load them with os.getenv()
or a library like pydantic
.
import os
DEBUG = os.getenv("DEBUG", "False") == "True"
DATABASE_URL = os.getenv("DATABASE_URL")
3. modules/
: Group Features by Responsibility
Rather than lumping everything into a single file, I split features into modules — e.g., auth.py
, data.py
, analytics.py
.
Each module does one thing.
This makes the code easier to test, debug, and reuse.
4. utils/
: Common Helpers
Utility functions that are reused across the project — like date formatting, error handling, or logging — go here.
If a utility grows too large, I break it into smaller files within utils/
.
5. tests/
: Your Safety Net
Tests mirror the structure of my_project/
.
Each module has a corresponding test file.
I use pytest
for simplicity, readability, and speed.
pytest tests/
6. pyproject.toml
: One File to Rule Them All
This is the future of Python packaging and configuration. You can define dependencies, formatters, and linters all in one place.
Here’s a minimal pyproject.toml
with Poetry:
[tool.poetry]
name = "my_project"
version = "0.1.0"
description = "Awesome Python project"
authors = ["You <you@example.com>"]
[tool.poetry.dependencies]
python = "^3.10"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Development Workflow Tips
- Use virtual environments (
venv
,poetry shell
, oruv
) to isolate dependencies. - Stick to a naming convention for modules and functions.
- Adopt type hints and a linter (
ruff
,flake8
, orblack
) early. - Consider using pre-commit hooks to auto-format and lint before every commit.
- Document your decisions in the
README.md
for future-you (and your team).
Bonus: Making It a Template
Want to reuse this structure for every project?
You can:
- Zip it and keep a local starter template.
- Use GitHub’s template repo feature.
- Automate with Cookiecutter to scaffold new projects in seconds.
Final Thoughts
You don’t need a fancy structure to start coding. But if you want to grow confidently, collaborate with others, and deploy without pain — your project layout matters.
This template has saved me from countless hours of confusion and refactoring.
I hope it saves you too.
If you liked this breakdown, feel free to bookmark it and customize the template to fit your workflow.
Want more articles like this? Follow me on Medium and check out:



