DEAP: the Python framework where you write the evolutionary loop yourself
Distributed Evolutionary Algorithms in Python
At a glance
- What is it?
- Six thousand four hundred stars, an LGPL license, a dependency on numpy and moocore, and a README example short enough to read in one sitting. Here is what DEAP actually gives you and what it leaves to you.
- Who is it for?
- DEAP is a good fit when the shape of your search matters more than the search itself, when you want to see every operation the algorithm performs, and when you would rather assemble operators from parts than adopt someone else's optimizer. The creator and toolbox split is the reason it is worth learning: adding a representation or a variation operator takes a few lines rather than a patch.
- Can I use it commercially?
- Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 172 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 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A framework for prototyping, not a library of optimizers
The project's own description is short: Distributed Evolutionary Algorithms in Python, hosted at readthedocs, written in Python, LGPL 3.0, 6441 stars, 1161 forks, 281 open issues, default branch master, last pushed 2026-04-17. The README calls it a framework for rapid prototyping and testing of ideas, and it makes a design promise in the same breath: algorithms should be explicit and data structures transparent.
That promise is the whole architecture. There is no GeneticAlgorithm class you configure with a mutation rate. Instead you get a toolbox, a creator factory, a set of operator functions, and an algorithms module with loops like `varAnd` and `eaMuPlusLambda` that call back into your own registered functions. The loop is short enough to read, short enough to edit, and short enough to break when your problem does not fit the standard shape.
The feature list in the README is worth reading closely because it is a claim about scope. Genetic algorithms with any imaginable representation, including list, array, set, dictionary, tree and numpy array. Genetic programming over prefix trees, loosely typed or strongly typed, with automatically defined functions. Evolution strategies including CMA-ES. Multi-objective work through NSGA-II, NSGA-III, SPEA2 and MO-CMA-ES. Co-evolution of several populations, cooperative and competitive. Parallel evaluation. A hall of fame holding the best individuals that ever lived. Checkpoints. A benchmarks module. Genealogy of a run, readable by NetworkX. And alternative algorithms as examples, including particle swarm, differential evolution and estimation of distribution.
That is not a small library. It is a parts bin, and the value depends entirely on how comfortable you are assembling the parts yourself.
The Onemax example is the whole tutorial
The README ships one example, and it is the most useful thing in the file. It solves Onemax, where the goal is a vector of 100 bits all set to one, using a generational genetic algorithm.
import random
from deap import creator, base, tools, algorithms
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)
toolbox = base.Toolbox()
toolbox.register("attr_bool", random.randint, 0, 1)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_bool, n=100)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
def evalOneMax(individual):
return sum(individual),
toolbox.register("evaluate", evalOneMax)
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
toolbox.register("select", tools.selTournament, tournsize=3)
population = toolbox.population(n=300)
NGEN=40
for gen in range(NGEN):
offspring = algorithms.varAnd(population, toolbox, cxpb=0.5, mutpb=0.1)
fits = toolbox.map(toolbox.evaluate, offspring)
for fit, ind in zip(fits, offspring):
ind.fitness.values = fit
population = toolbox.select(offspring, k=len(population))
top10 = tools.selBest(population, k=10)Five things in twenty lines are worth naming. `creator.create` builds new classes at runtime, attaching a fitness class and then an individual class that has a `fitness` attribute. `Toolbox.register` binds a name to a callable plus its bound arguments, so `toolbox.mate` is always a two-point crossover with no parameters attached. `tools.initRepeat` builds individuals and then populations from the same registration, which is how a representation change propagates without touching the loop. `toolbox.map` is the evaluation seam, and it is the reason multiprocessing works later without changing any algorithm code. And `algorithms.varAnd` applies variation and mutation with the crossover and mutation probabilities you pass, then hands control back to you for evaluation and selection.
Note what is absent. There is no early stopping, no logging, no checkpoint write, no migration logic. Those are yours to write, which is exactly the tradeoff the project is making.
Installation is one line, and the dependency list tells you a lot
Installation is the ordinary thing:
pip install deapThe README also offers a git install straight from master, and warns that distribution packages such as apt-get or yum usually ship an outdated version. That warning is worth taking seriously for a research tool that has no published releases on its hosting platform, where commits to master are what people actually run.
The declared dependency list is short and has changed shape recently:
install_requires=['numpy', 'moocore'],
)`moocore` is the newer name in that list and worth understanding. It is a separate library of modern multi-objective optimisers, and its presence means parts of the multi-objective surface that older DEAP versions implemented in house are now delegated. Numpy remains required, which the README attributes to CMA-ES specifically. There is no PyTorch dependency, no JAX, no compiled extension of DEAP's own, so a wheel exists for essentially any platform Python runs on.
The rest of the setup file is informative about intent. Packages exclude both `examples` and `tests`. Platforms is `any`. The classifiers mark the development status as 4 - Beta, and list developers, education and science research as intended audiences, which tells you this is aimed at people writing experiments rather than people shipping a service. The author field is a team address and the contact is a Google group, so there is a community behind the package even though there is no support contract behind it.
The README's requirements section is a historical artifact
Here is the kind of detail that only shows up when you read the whole file rather than the summary. The README states that the most basic features require Python 2.6, that combining the toolbox with the multiprocessing module needs Python 2.7 because of its support for pickling partial functions, and that since version 0.8 DEAP is compatible with Python 3 via an automatic 2to3 translation of the source at install time, requiring `setuptools<=58` and recommending a pinned older setuptools.
None of that matches the current packaging. The classifiers in setup.py list Python and Python 3 only, with no Python 2 entries. The project has a Simplified Chinese README alongside the English one. It was pushed to in April 2026. A 2to3 step at install time is not something a project retains for years.
The practical reading is that the README's requirements section is stale prose that survived a migration, while the packaging metadata is the truth. Trust `install_requires` and the classifiers over the prose. But the section is worth noticing for a second reason: it is a reminder that documentation written by the project can lag the code by years, so when you hit a discrepancy in DEAP, check the metadata and the source before you check the docs again.
Parallel evaluation, checkpoints and the hall of fame are the practical extras
Three features in the list are less glamorous than the algorithm names and more useful day to day.
Parallel evaluation is the big one, and the design explains why it works. Because your evaluation function is registered in the toolbox and called through `toolbox.map`, swapping that map for a multiprocessing pool changes nothing else. The README also says the framework works in harmony with parallelisation mechanisms such as multiprocessing and SCOOP, a shared-memory framework for Python that can hold population state outside the main process. Evolution strategies are embarrassingly parallel by nature, since each candidate scores independently, which is why this library has always leaned that way.
Checkpoints take snapshots of a system regularly. In an evolutionary run you may spend hours of compute and then crash, and there is no partial credit in the usual sense because the population is the state. Being able to serialise it and resume is the difference between an experiment and a gamble.
The hall of fame keeps the best individuals that lived in the population, not just the best in the final generation. With a tournament selection and a mutation rate that can undo a good solution, the last generation is often worse than the third from the end. The hall of fame is how you keep the answer anyway.
Genealogy is the feature that surprised me most and the one I would point a new user at. It records how individuals related across generations and is compatible with NetworkX, so you can load a run and ask a graph library to draw it. When a run behaves strangely, seeing which parents produced which offspring is often more informative than another fitness histogram.
Licensing, maintenance signals, and what they mean for adoption
The license is the part to read properly, because LGPL 3.0 is not a permissive license and people misclassify it constantly. It is a weak copyleft license aimed at libraries. If you import DEAP into your own application and ship that application, your code stays under your own terms. If you modify DEAP itself and distribute the modified library, those modifications must be released under the same terms. Dynamic linking and import-into-memory is the pattern the license is designed around, which is why importing a Python package is generally a comfortable arrangement and vendoring a patched copy is not.
The licensing classifiers in setup.py say the same thing, and note that the package's stated license field is simply `LGPL` without a version. For anything shipped, check the LICENSE.txt in the tree rather than the metadata string.
Maintenance signals are mixed in an instructive way. 281 open issues on 6441 stars is a high absolute number, but for a project of this age and scope it is not alarming; it is closer to a backlog than a crisis. There are zero published releases on the platform, so there is no changelog to read and no version bump announcement to track. Travis-CI appears in the badge row and in the build status section, alongside an Azure Pipelines badge, which is a project whose continuous integration has been moved more than once.
The examples directory is the honest signal. It holds a black box optimization script, a notebook on hyperparameter tuning, and separate folders for cooperative co-evolution, differential evolution, estimation of distribution, evolution strategies, genetic algorithms, genetic programming and particle swarm. That is a working researcher's filing cabinet, not a curated tutorial series, and it tells you where the framework is actually comfortable.
When to reach for it, and when to reach for something else
DEAP is at its best in three situations. When you are writing an algorithm and want the operator, the representation and the loop all visible in your own file, because you intend to modify all three. When the search space is unusual enough that a generic optimiser would need a plugin system anyway, which is exactly what the creator and toolbox pattern is. And when the evaluation is expensive enough that parallel evaluation and checkpointing are requirements rather than nice-to-haves.
It is the wrong tool in two others. If you want a tuned implementation of a well known optimiser with sane defaults, an existing library that ships a working CMA-ES or differential evolution will get you a result this afternoon. And if your search space happens to be well served by gradient descent with a good optimiser, evolutionary methods will spend far more compute for a worse answer.
The learning cost is genuinely low and that is the most underrated thing here. Twenty lines of Python is the entire tutorial. The operator library is broad enough that most of what you need already exists, and the parts you do need to write are the parts specific to your problem, which is the part you had to write anyway.
One practical note before you start. The version number in the package metadata comes from `deap.__revision__` rather than being written literally in setup.py, so a reproducible environment needs a pinned release from PyPI rather than a git install of master. That one line in the setup file tells you more about how to deploy this dependency than most release notes would.
Editorial conclusion
DEAP is a good fit when the shape of your search matters more than the search itself, when you want to see every operation the algorithm performs, and when you would rather assemble operators from parts than adopt someone else's optimizer. The creator and toolbox split is the reason it is worth learning: adding a representation or a variation operator takes a few lines rather than a patch. Two things to keep in view before you commit. The package is LGPL, so read what that means for how you distribute a product that links it, and the README's requirements section still describes a Python 2 era that the current packaging metadata no longer reflects. With 6441 stars, 1161 forks and no published releases on the platform, the community around it is large and the versioning story is thin, so pin your version and keep your own copy of the documentation you relied on.
Frequently asked questions
What does DEAP stand for?
In this project it stands for Distributed Evolutionary Algorithms in Python, which is the string used as the package description in setup.py. The same letters are also used for an unrelated phonological assessment that dominates search results for the acronym, so searching for the framework by name alone tends to surface the wrong thing. Searching for the project owner along with the name gets you to the right repository.
How do you install DEAP?
With pip, from the command line. The README also offers installing directly from the master branch of the repository, which is useful when you need an unreleased fix, and it warns that operating system packages such as apt-get and yum generally ship an outdated version. Building from a clone is a third option and goes through the standard setup script. The declared dependencies are numpy and moocore, and they install automatically.
Is DEAP still relevant or has it been superseded?
It is actively worked on. The repository was last pushed to in April 2026, the English README has a Simplified Chinese counterpart, and the CI configuration has been migrated to Azure Pipelines. It is a mature project rather than a new one, with the pattern most research frameworks converge on, where the framework supplies operators and bookkeeping and the researcher supplies the problem and the loop.
Can I use DEAP in a commercial product?
That is a licensing question and the answer sits in the license rather than the code. The project is LGPL 3.0, a weak copyleft license for libraries. Importing DEAP into your application and shipping that application is the case the license is designed to allow, and your own code is not forced to open. Modifying DEAP itself and distributing the modified version is the case that carries an obligation to publish those modifications under the same terms.
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/deap-deap)