Library / SDK
pallets/werkzeug avatar
pallets/werkzeug

Werkzeug: the WSGI toolkit under Flask, with a browser debugger and no opinion on templates or databases

The comprehensive WSGI web application library.

6,882 stars1,880 forksPythonBSD-3-Clause

At a glance

What is it?
pallets/werkzeug is a BSD-3-Clause Python library of WSGI building blocks: request and response objects, URL routing, HTTP helpers, an interactive debugger, a local development server and a test client. It deliberately leaves templating, databases and request handling to you.
Who is it for?
Use Werkzeug when you want to assemble a WSGI application yourself, or when you need its routing, request objects, debugger or test client without a full framework. Choose Flask instead if you want structure and patterns decided for you.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 4 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • pallets/werkzeug6,882 ★ · +3
Star history
Repository2026-09-232026-11-13
pallets/werkzeug6.9k6.9k

3 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The name is the job description: werk plus zeug, a tool

The README opens with the etymology. Werkzeug is a German noun meaning tool, built from werk, work, and zeug, stuff. The project calls itself a comprehensive WSGI web application library that began as a simple collection of utilities for WSGI applications and became one of the most advanced WSGI utility libraries.

That history explains its shape. It is a set of independent tools for working with WSGI, not a framework that owns your application's structure. You can take the routing system without the debugger, or the test client without the server.

The practical consequence is that Werkzeug alone does not give you a project layout, configuration system or conventions. If you want those, the README points to Flask, which wraps Werkzeug and handles the WSGI details while providing more structure and patterns for defining applications.

It enforces no template engine and no database adapter

Werkzeug does not enforce any dependencies. It is up to the developer to choose a template engine, a database adapter, and even how to handle requests. The README says it can build blogs, wikis and bulletin boards.

The package metadata is consistent with that restraint. The only declared runtime dependency in pyproject.toml is markupsafe>=3.0.3, and the one optional extra is watchdog>=6. Everything else, such as ruff, tox, pytest, sphinx, mypy and pyright, sits in development groups.

The cost of the freedom is decisions. With Werkzeug alone you will pick a template library, wire up data access and write the view layer yourself. A team that wants those choices made should start from Flask. A team that wants control, or is building its own framework layer, gets a base that does not push opinions into its design.

Request.application turns a function into a WSGI app

The README example shows the core idea. A function decorated with Request.application receives a Request and returns a Response, and the decorator makes it a WSGI callable. The development server is started with run_simple:

python
# save this as app.py
from werkzeug.wrappers import Request, Response

@Request.application
def application(request: Request) -> Response:
    return Response("Hello, World!")

if __name__ == "__main__":
    from werkzeug.serving import run_simple

    run_simple("127.0.0.1", 5000, application)

Running python -m app prints Running on http://127.0.0.1:5000/ and the message Press CTRL+C to quit.

The request object is described as full featured, with objects to interact with headers, query args, form data, files and cookies. The response object can wrap other WSGI applications and handle streaming data. So the same two classes cover both a simple page and a pass-through wrapper.

The interactive debugger runs code in the browser, so it belongs on a development machine

The debugger lets you inspect stack traces and source code in the browser, with an interactive interpreter for any frame in the stack. That is more than a traceback page. You can open a frame from a failed request and evaluate expressions in it.

The consequence follows from the capability. A page that offers an interpreter inside a live process is a development tool, and it should be enabled only where you are the only person who can reach it. The README presents it alongside the local development server, not as a production feature.

The threaded WSGI server is likewise described as being for use while developing applications locally. When you move to a real deployment, the README does not name a production server, so choose one deliberately instead of carrying run_simple forward by habit.

Routing matches URLs to endpoints and generates them back

The routing system works in both directions: it matches URLs to endpoints, and it generates URLs for endpoints. It also has an extensible system for capturing variables from URLs.

Generation is the part that saves maintenance. If links in templates and redirects are produced from endpoint names, changing a URL pattern updates every place that uses it. Hard coded paths do not get that benefit.

The HTTP utilities add helpers for entity tags, cache control, dates, user agents, cookies, files and more. These are the small pieces that applications otherwise reimplement badly. Because Werkzeug is a toolkit, you can use routing and these helpers inside an application that is not built on Flask, or inside a framework of your own, without importing anything you do not need.

The test client simulates requests without starting a server

A test client simulates HTTP requests during testing without requiring a running server. For a WSGI application that means tests call the application object directly, with no port to bind and no process to start or stop.

The repository's own tooling reflects a test heavy project. The tests dependency group lists pytest, pytest-timeout, cryptography, cffi, ephemeral-port-reserve and watchdog, and tox with tox-uv is in the dev group.

The limit is what is being simulated. The client exercises your WSGI app, not the real network path in front of it, so behaviour that depends on a reverse proxy or a production server needs a separate check. It also means the test client is the right place for fast route and response checks, while the debugger and development server are for manual exploration.

Main is a 3.2.0 development line, and Python 3.11 is the floor

The newest releases are 3.1.9 on 2026-09-27, 3.1.8 on 2026-04-02 and 3.1.7 on 2026-03-24, while pyproject.toml on the main branch reads 3.2.0.dev. A checkout of main is therefore ahead of any release, so install a tagged version for anything you ship.

The package requires Python 3.11 or newer, builds with flit_core, and is classified Development Status 5 - Production/Stable and Typing :: Typed. The last push was on 2026-10-30 and the repository is not archived.

The examples directory has complete sample applications: coolmagic, couchy, cupoftee, plnt, shortly, shorty, simplewiki and webpylike, plus single files such as httpbasicauth.py, upload.py and wsecho.py. They are reference material for how to assemble an app from these tools, not packaged features. Changes are recorded in CHANGES.rst.

Editorial conclusion

Use Werkzeug when you want to assemble a WSGI application yourself, or when you need its routing, request objects, debugger or test client without a full framework. Choose Flask instead if you want structure and patterns decided for you. Before deploying, remember that its server is described for local development, and that main is at 3.2.0.dev while the newest release is 3.1.9.

Frequently asked questions

What is Werkzeug used for?

Werkzeug is a WSGI library for building web applications, with request and response objects, URL routing, HTTP utilities, a debugger, a development server and a test client.

What does Werkzeug mean?

Werkzeug is a German noun meaning tool, formed from werk, work, and zeug, stuff.

What is Werkzeug in Flask?

Flask wraps Werkzeug and uses it to handle the details of WSGI, while adding more structure and patterns for defining applications.

Official sources

  1. License: BSD-3-Clause
  2. pallets/werkzeug on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/pallets-werkzeug.svg)](https://hysenlabs.com/projects/pallets-werkzeug)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/pallets-werkzeug.svg)](https://hysenlabs.com/projects/pallets-werkzeug)

Was this useful?