Why Flask Blueprints Aren’t Enough for Large Apps¶
Flask blueprints are the recommended way to organize large Flask applications. They’re a solid tool — but they’re not a complete solution. As your application grows beyond a certain size, blueprints alone leave critical gaps that turn your codebase into technical debt.
This post explains what blueprints do well, where they fall short, and what a complete modular architecture looks like.
What Blueprints Do Well¶
Blueprints solve the problem of route organization. Instead of one massive app.py with 500 route decorators, you split routes into logical groups:
# auth/views.py
auth_bp = Blueprint("auth", __name__)
@auth_bp.route("/login")
def login(): ...
@auth_bp.route("/register")
def register(): ...
This is a meaningful improvement. It’s the first step every Flask developer should take. But it’s only the first step.
Where Blueprints Fall Short¶
1. No model isolation
Blueprints only organize views. Your models still live in a single models.py or are scattered across files with no clear ownership. A module that owns its views should also own its models, forms, and templates.
# What most blueprint-based apps look like:
auth/
├── views.py # routes
models.py # all models, including auth models
forms.py # all forms, including auth forms
Auth models shouldn’t live next to billing models any more than auth routes should live next to billing routes.
2. No template encapsulation
Blueprints can have a template_folder, but there’s no convention for how templates should be organized. Without enforced structure, templates end up in a flat directory with hundreds of files and unclear ownership.
3. No auto-discovery
Every blueprint must be manually imported and registered in your app factory:
from auth.views import auth_bp
from billing.views import billing_bp
from dashboard.views import dashboard_bp
# ... 20 more imports
app.register_blueprint(auth_bp)
app.register_blueprint(billing_bp)
app.register_blueprint(dashboard_bp)
# ... 20 more registrations
Forget to import one? Your route silently doesn’t exist. This is fragile and doesn’t scale.
4. No enforcement of module boundaries
Nothing stops billing/views.py from importing auth/models.py directly. Over time, your modules become tightly coupled. You can’t test, refactor, or remove a module without fear.
5. No built-in module assets
Serving static files for a module (CSS, JS, images) requires manual path configuration. There’s no standard way to say “these assets belong to this module.”
The Modular Architecture: Blueprints + Boundaries¶
The solution isn’t to abandon blueprints — it’s to add the missing layers around them. A true modular architecture adds:
Concern |
Blueprints Only |
Modular Architecture |
|---|---|---|
Views |
✅ Organized |
✅ Organized |
Models |
❌ Global |
✅ Per-module |
Forms |
❌ Global |
✅ Per-module |
Templates |
❌ Flat |
✅ Per-module, namespaced |
Static assets |
❌ Manual |
✅ Per-module, auto-served |
Auto-discovery |
❌ Manual imports |
✅ Drop-in registration |
Boundary enforcement |
❌ None |
✅ Convention + tooling |
Tests |
❌ Centralized |
✅ Per-module |
How Shopyo Bridges the Gap¶
Shopyo was built specifically to solve these problems. Every Shopyo module is a self-contained unit with its own views, models, forms, templates, tests, and static assets:
modules/billing/
├── __init__.py
├── view.py # routes (blueprint)
├── models.py # billing models only
├── forms.py # billing forms only
├── global.py # template variables, configs
├── info.json # module metadata
├── static/ # billing-specific CSS/JS
├── templates/
│ └── billing/ # namespaced templates
└── tests/
├── test_models.py
└── test_views.py
Modules are auto-discovered — you just drop them in the modules/ folder. The blueprint is registered automatically. Static assets are served transparently in both development and production. Module boundaries are enforced by convention (no cross-module imports) and supported by the framework.
This is what blueprints should have been from the start: a complete unit of functionality, not just a router with a name tag.
Next Steps for Modular Flask¶
Build Large Flask Apps Without Losing Your Sanity — Build your first modular Flask app
Architecture — How Shopyo’s module system works
Modules/Apps — Creating and managing modules