Flask remains the default answer when a Python service needs a router and templating without inheriting a full framework. The microframework bet still holds: you trade Django's batteries for control over every dependency, which suits APIs, glue services, and ML-serving layers well. FastAPI has taken the async-first, typed-API crown, so reach for Flask when the project values a small, legible core and a mature extension pool over native async throughput. For most CRUD apps and internal tools, it is still a solid, low-surprise pick.
- Tiny core: a router, request context, and Jinja templating, nothing more
- You assemble the stack, ORM, auth, and migrations stay your choice
- Enormous Python talent pool and a deep extension ecosystem
- Readable source, gentle learning curve, well-documented
- Async views supported via the async extra since 2.0
- No batteries: ORM, admin, and auth are all bring-your-own
- Larger apps need disciplined structure Flask does not impose
- Sync-first design, async is bolted on rather than native
- Per-request concurrency depends on the WSGI server you pick
Flask is a minimalist Python web framework built on Werkzeug and Jinja. It ships a request router, a templating engine, and a development server, then leaves every other decision to you. That restraint is the point: Flask is for developers who want to choose their own ORM, auth, and project layout rather than accept a framework’s defaults.
Where it fits
Flask is a microframework. The core is deliberately small, and you assemble the rest of the stack from extensions and libraries you pick yourself. That makes it a natural fit for REST and JSON APIs, small to mid-size web apps, internal dashboards, and quick prototypes. It is also the common glue layer in front of machine-learning models, where a thin HTTP wrapper around an inference call is all the project needs.
The framework suits teams that want control over batteries-included convenience. If you already have opinions about SQLAlchemy versus another ORM, or want to keep dependencies lean, Flask stays out of the way. If you would rather inherit a full set of conventions, a larger framework will save time.
Cost to adopt
Flask is free, open source under the BSD license, and self-hostable on any WSGI server (Gunicorn, uWSGI, or Waitress). The real cost is time: you assemble the extensions yourself, so the first project carries some setup overhead that Django folds into its defaults. That cost is offset by an enormous Python talent pool, a mature extension ecosystem (Flask-SQLAlchemy, Flask-Login, Flask-Migrate), and source code readable enough to debug directly. Compared with Django’s batteries-included approach or FastAPI’s async-first, type-driven design, Flask trades built-in features for a small, predictable core you grow on your terms.
How it compares
Django, Batteries-included: ORM, admin, auth, and migrations ship in the box. Pick when you want conventions and built-in features over assembling your own stack.
FastAPI, Async-first with type-driven validation and automatic OpenAPI docs. Pick for high-concurrency typed APIs where native async throughput matters.
Express, The same minimalist philosophy in the Node ecosystem. Pick when your team and stack are JavaScript-first rather than Python.
What changed recently
Flask 3.1.3 shipped on 2025-02-19 as a security fix release (advisory GHSA-68rp-wp8r-4726), correcting session-access tracking so key-only operations like in and len mark the session accessed. The 3.1 line, opened in late 2024, hardened async support: stream_with_context no longer fails inside async views, copy_current_request_context can decorate async functions, and class-based View and MethodView handlers can be coroutines when Flask is installed with the async extra. The framework continues under the Pallets community governance model rather than a single corporate sponsor.
Sources
- Flask 3.1.3 release, github.com, February 2025
- Flask changelog (3.1.x), flask.palletsprojects.com, 2026
- Using async and await, flask.palletsprojects.com, 2026
- Flask on PyPI, pypi.org, 2026