thumbor: an on-demand image service where the URL is the API
thumbor is an open-source photo thumbnail service by globo.com
At a glance
- What is it?
- thumbor is an MIT-licensed Python image service that crops, resizes and filters photos from signed or unsafe URLs. It suits teams with many image variants to serve and no wish to pre-generate them, but it is not a drop-in for a static asset pipeline.
- Who is it for?
- Adopt thumbor if you serve many image variants and want them generated on request rather than pre-rendered, and if you can run a Python HTTP service in front of your originals. Do not adopt it if you only need a handful of fixed sizes, or if you want a Go binary that embeds in another process; imgproxy is the closer fit there.
- Can I use it commercially?
- Yes. MIT 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 8 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 September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What thumbor does that a build-time resizer does not
A static pipeline answers a fixed question: which sizes do we need? You pick a set, generate them on upload, and store the results. The cost shows up later, when a new breakpoint, a new aspect ratio for a social card, or a retina variant appears, and every stored image has to be regenerated. thumbor inverts that. It is an HTTP server that produces the image when the request arrives, so a new size is a new URL rather than a migration.
The audience is teams with a large, changing set of image variants: editorial sites, marketplaces, and any product where the same photo is displayed at a dozen dimensions. The README frames it as a smart imaging service that enables on-demand cropping, resizing, applying filters and optimizing images, and the project is published by globo.com under the MIT license. It is a service, not a library you call from your application code, which is the decision that matters most when you evaluate it.
The URL is the API: how a thumbor request is structured
Every operation is encoded in the path. The README gives this example, and it is worth reading slowly because it contains the whole model:
http://<thumbor-server>/300x200/smart/thumbor.readthedocs.io/en/latest/_images/logo-thumbor.pngThe first segment after the host is the target geometry, 300x200. The next segment is the crop strategy, here smart, which tells thumbor to choose the crop region rather than take the centre. What follows is the source image location. Change the geometry segment and you get a different image from the same source; add a filter segment and you get a transformed one. The README states you can create as many different images as you want just by varying path parameters.
The smart strategy is the part with real machinery behind it. According to the README, thumbor uses AI for smart detection, with detection algorithms documented separately, and the feature list names face and feature detection including glasses and interesting points. That detection is what prevents the severed-heads problem the README calls out as the usual failure of automatic cropping. The optional dependency group in pyproject.toml is where this lives: the opencv extra pulls opencv-python-headless and numpy, which is a signal that detection is not free in the base install.
Installing thumbor and making a first request
The README offers three installation routes: pip, a distribution package, and Docker. Start with pip, choosing the extras that match what you need. The base install is the smallest and the README labels it as main dependencies only.
pip install thumbor
pip install thumbor[opencv]
pip install thumbor[all]If you would rather not manage a Python environment, Debian and Ubuntu ship thumbor in their official repositories, and the README gives the apt form:
sudo apt update
sudo apt install thumborThe Docker route is the shortest path to a running server. The README documents an official image on GitHub Container Registry, published on port 8888:
docker run -p 8888:8888 ghcr.io/thumbor/thumbor:latestOnce it is running, the README says to start it with the thumbor command and then reach it on localhost:8888 with an unsafe URL. The example it gives points at a sample image in the project's own repository:
thumborhttp://localhost:8888/unsafe/https://raw.githubusercontent.com/thumbor/thumbor/master/example.jpgThe unsafe segment is the part to notice. It means the URL is not signed, so anyone who can reach the server can ask it to fetch and transform whatever source URL they like. That is fine on a laptop and a different proposition on a public host. If the server does not come up cleanly, the README points at a diagnostic command, thumbor-doctor, which can read your configuration file:
thumbor-doctor -c thumbor.confFrom a development checkout the README says to use make setup, make compile_ext and make run instead, and to run the same diagnostic through uv run --locked thumbor-doctor. The Makefile confirms this: run depends on compile_ext and starts thumbor with -l debug -d -c thumbor/thumbor.conf, while run-prod uses -l error.
Where thumbor is the wrong tool
The clearest limitation is the install surface. thumbor is a Python service with a compiled extension layer: setup.py builds C filter extensions under thumbor/ext/filters, compiled with -Wall -Wextra -Werror, and pyproject.toml requires Python 3.10 or newer. That is a real deployment commitment compared with a single static binary. If your platform team does not want to run Python services, or you need image resizing inside an existing process rather than behind an HTTP boundary, thumbor is a poor fit regardless of its feature list.
The second limitation is the security model. The README's own quick start uses an unsafe URL, and the README does not document the signing workflow; the documentation site does. That gap matters because the unsafe form is exactly the configuration that lets a stranger use your server as a proxy for arbitrary remote images. Anyone deploying thumbor should treat URL signing as the default posture and read the signing documentation before exposing the service, not after.
There is also a maturity signal worth reading plainly. pyproject.toml classifies the project as Development Status :: 4 - Beta. The last push to the default branch was on 2026-09-21, and the most recent release listed is 7.8.0 from 2026-05-30, so the project is moving. Beta classification on a project this widely deployed is a documentation convention rather than a warning about stability, but it does mean you should pin a version and read the CHANGELOG before upgrading.
thumbor vs imgproxy: two different answers to the same question
People searching for thumbor alternatives usually land on imgproxy, and the comparison is instructive because the two disagree about almost everything except the URL shape.
imgproxy is a Go binary. You deploy a single static executable, and the request model is also path-based with signed URLs. The difference in approach is what comes bundled. thumbor is a Python application with a plugin architecture: the README describes it as highly extensible, the storage layer supports local storage, AWS S3, Rackspace and Ceph, and the project maintains a separate awesome-thumbor list of integrations for languages and frameworks. If you need a custom detector, a custom storage backend, or a filter that does not exist yet, that extensibility is the reason to pick thumbor, and the C extension layer in setup.py is the mechanism for the performance-sensitive parts.
imgproxy trades that extensibility for a smaller operational footprint. There is no Python runtime, no dependency on Pillow or Tornado, and no compiled extension build step. If your requirement is simply resize, crop and sign, and your constraint is that the thing must be one binary in a container, imgproxy is the more direct answer. thumbor earns its place when the transformation logic itself is custom, or when the storage backends you already run are the ones thumbor supports.
Maintenance cost, the MIT license, and what to check before upgrading
The dependency list in pyproject.toml is the maintenance surface: Pillow, Tornado, statsd, piexif, JpegIPTC, libthumbor, derpconf, pytz and thumbor-plugins-gifv, all with upper bounds. Those bounds are deliberate. Pillow is pinned below 13.0.0 and Tornado below 7.0.0, so a major release of either will require a thumbor release before you can move. pytz is bounded below 2027.0.0, which gives an unusually long runway for a dependency that most projects have replaced.
Upgrades are not automatic. The repository carries a CHANGELOG and the releases are tagged, so the practical path is to pin a version, read the changelog entry for the target release, and test your custom detectors and storage backends against it, since those are the parts that live outside the core and are not covered by the project's own test suite. The Makefile shows the project's own test flow: make test builds the extensions, starts Redis, runs unit tests with coverage, then integration tests and flake, then kills Redis. Reproducing that locally is the cheapest way to find out whether your environment can build the C extensions at all.
The license is MIT, declared both in pyproject.toml and in the LICENSE file. MIT is permissive: it allows commercial use, modification and redistribution, with the requirement that the copyright notice and permission notice travel with the code. thumbor is a service you run rather than a library you distribute, so the notice obligation mostly concerns redistribution of modified source. This is a description of the license text, not legal advice; if you are embedding thumbor in a product you ship, have your own counsel read the LICENSE file.
Editorial conclusion
Adopt thumbor if you serve many image variants and want them generated on request rather than pre-rendered, and if you can run a Python HTTP service in front of your originals. Do not adopt it if you only need a handful of fixed sizes, or if you want a Go binary that embeds in another process; imgproxy is the closer fit there. Before committing, check which optional extras your deployment needs, because the smart-crop behaviour depends on the opencv extra rather than the base install, and confirm the security key path you intend to use, since thumbor's own documentation is the only source for the signing details and the README only shows the unsafe URL form.
Frequently asked questions
How does thumbor compare with imgproxy?
Both generate images on demand from a path-based URL, but thumbor is a Python service with a plugin architecture and configurable storage backends such as local storage, AWS S3, Rackspace and Ceph, while imgproxy is a Go binary with a smaller deployment footprint. Choose thumbor when you need custom detectors, filters or storage integrations; choose imgproxy when you want a single binary and only standard resize and crop behaviour.
What are the alternatives to thumbor?
The README does not name alternatives. The closest comparison in this article is imgproxy, which differs mainly in language and deployment model: a Go binary instead of a Python service with compiled extensions. If your constraint is operational simplicity rather than extensibility, that is the trade to evaluate.
How do I install thumbor?
The README gives three routes: pip install thumbor (or thumbor[opencv] or thumbor[all] for the optional dependency groups), the Debian and Ubuntu packages via apt, or the official Docker image at ghcr.io/thumbor/thumbor, which the README runs with port 8888 mapped. From a development checkout, the README uses make setup, make compile_ext and make run.
What does the smart segment in a thumbor URL do?
It selects the crop strategy. The README's example URL places smart between the 300x200 geometry and the source path, and the README states that thumbor uses AI for smart detection so that automatic cropping does not cut off heads. The detection features listed include faces, glasses and interesting points, and the opencv extra in pyproject.toml is what supplies the opencv-python-headless and numpy dependencies for it.
What is the unsafe prefix in a thumbor URL?
It marks a request whose URL is not signed, which is the form the README uses in its quick start on localhost. The README does not document the signing workflow; that lives in the project's documentation site. Treat an unsafe, publicly reachable server as one that will fetch and transform whatever source URL a caller supplies.
Official sources
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.
[](https://hysenlabs.com/projects/thumbor-thumbor)