TaxSolver is a constrained optimization-based tool that enables policymakers to design optimal income tax reforms by focusing on the desired outcomes of a reform in conjunction with fiscal guarantees that a reform has to abide by rather than ad-hoc rule adjustments. Read our accompanying paper Implementing Optimal Taxation: A Constrained Optimization Framework for Tax Reform.
While optimal taxation theory provides clear prescriptions for tax design, translating these insights into actual tax codes remains difficult. Existing work largely offers theoretical characterizations of optimal systems, while practical implementation methods are scarce. Bridging this gap involves designing tax rules that meet theoretical goals, while accommodating administrative, distributional, and other practical constraints that arise in real-world reform. We develop a method casting tax reform as a constrained optimization problem by parametrizing the entire income tax code as a set of piecewise linear functions mapping tax-relevant inputs into liabilities and marginal rates. This allows users to impose constraints on marginal rate schedules, limits on income swings, and objectives like revenue neutrality, efficiency, simplicity, or distributional fairness that reflect both theoretical and practical considerations. The framework is computationally tractable for complex tax codes and flexible enough to accommodate diverse constraints, welfare objectives and behavioral responses. Whereas existing tools are typically used for ex-post `what-if' analysis of specific reforms, our framework explicitly incorporates real-world reform constraints and jointly optimizes across the full tax code. We illustrate the framework in several simulated settings, including a detailed reconstruction of the Dutch income tax system. For the Dutch case, we generate a family of reforms that smooth existing spikes in marginal tax rates to any desired cap, reduce the number of rules, and impose hard caps on income losses households can experience from the reform. We also introduce \texttt{TaxSolver}, an open-source package, allowing policymakers and researchers to implement and extend the framework.
-
Mathematical Foundation: Most tax codes can be defined as a simple system of equations that make it possible to solve tax reform as (linear) optimization problem.
-
Policy-Aligned Design: Linear optimization allows policymakers to formulate both hard guarantees that the reform has to adhere to, as well as objectives that are maximized within these set constraints. This makes optimization a practical tool that is aligned with the reality of policy work.
-
Systematic Approach: Our approach allows for a tax reform process that does not consist of ad-hoc tweaking of existing rules but reasons over the entire system and returns an optimal solution.
-
Real-World Application: We illustrate our approach by reforming various example systems, as well as a system representing the complexity and scale of a real-world income tax code.
- Python 3.11 or higher
- pip package manager
pip install git+https://github.com/Tax-Lab/TaxSolver.gitgit clone https://github.com/Tax-Lab/TaxSolver.git
cd TaxSolver
pip install -e .import os
import TaxSolver as tx
from TaxSolver.constraints.income_constraint import IncomeConstraint
from TaxSolver.constraints.budget_constraint import BudgetConstraint
from TaxSolver.data_wrangling.data_loader import DataLoader
from TaxSolver.data_wrangling.bracket_input import BracketInput
from TaxSolver.objective import BudgetObjective
# Load taxpayer data from a system with 6 brackets into TaxSolver format.
# In the bundled example file the after-tax income column is named "outcome_1".
dl = DataLoader(path=os.path.join("data", "example", "simple_simul_1000.xlsx"),
income_before_tax="income_before_tax",
income_after_tax="outcome_1")
# Initialize the solver
tax_solver = tx.TaxSolver(dl.households)
# Split input along inflection points to construct brackets
BracketInput.add_split_variables_to_solver(
tx=tax_solver,
target_var="income_before_tax",
inflection_points=[0, 25_000, 50_000, 75_000, 100_000, 125_000, 150_000],
group_vars=["k_everybody"]
)
# Define solver variables for the optimization
income_tax = tx.BracketRule(
name="income_before_tax_k_everybody",
var_name="income_before_tax",
k_group_var="k_everybody",
ub=1,
lb=0,
)
# Add solver variables to the solver
tax_solver.add_rules([income_tax])
# Define constraints for the optimization
income_constraint = IncomeConstraint(0.0001, dl.households.values()) # No one can experience income shocks of more than 0.01%
budget_constraint = BudgetConstraint(
"All_households", dl.households.values(), 0, 0 # The total tax revenue cannot decrease or increase
)
# Add constraints to the solver
tax_solver.add_constraints([income_constraint, budget_constraint])
# Add an objective to the optimization (required before solving)
tax_solver.add_objective(BudgetObjective(budget_constraint))
# Solve the optimization problem
tax_solver.solve()
# View results
print(tax_solver.rules_and_rates_table())- Tutorial: See
notebooks/example_notebook.ipynbandnotebooks/readme_notebook.ipynbfor walkthroughs. - Methods: See
paper/methods.mdfor the methodology underlyingTaxSolver.
TaxSolver/
├── src/TaxSolver/ # Main package
│ ├── tax_solver.py # Core solver orchestration
│ ├── rule.py # Tax/benefit rule definitions
│ ├── objective.py # Optimization objectives
│ ├── backend/ # Solver backends (CVXPY/HiGHS, Gurobi)
│ ├── constraints/ # Constraint definitions
│ ├── data_wrangling/ # Data loading and bracket inputs
│ └── population/ # Household and person models
├── paper/ # Academic paper and examples
├── tests/ # Test suite
├── notebooks/ # Notebooks
└── data/ # Example datasets
- Tax Rules: Define how income is taxed (flat, progressive, benefits)
- Constraints: Hard limits the reform must satisfy (budget neutrality, income bounds)
- Objectives: Goals to optimize (redistribution, efficiency, simplicity)
- Households: Units of analysis with income, demographics, and tax liabilities
If you use TaxSolver in your research, please cite:
@article{taxsolver2025,
title={Implementing Optimal Taxation: A Constrained Optimization Framework for Tax Reform},
author={Verhagen, M.D. and Schellekens, M. and Garstka, M.},
year={2025},
eprint={2508.03708},
archivePrefix={arXiv},
note={Software available at: https://github.com/Tax-Lab/TaxSolver.git}
}This project is licensed under the MIT License - see the LICENSE file for details.
We welcome contributions! Please see our Contributing Guidelines for details on how to submit pull requests, report issues, and suggest improvements.
- Issues: Report bugs and request features on GitHub Issues
- Documentation: Full documentation available at [project website] TODO
- Academic Paper: [Link to published paper] TODO
Mark Verhagen Menno Schellekens Michael Garstka