This page documents the public solver subpath exports from or-tools-wasm.
The package is ESM only:
import { CpSat } from 'or-tools-wasm/cp-sat';
import { initRouting, RoutingIndexManager, RoutingModel } from 'or-tools-wasm/routing';Most solver runtimes are loaded lazily. Browser solves use the package worker bridge by default so the main thread stays responsive. Browser pages still need cross-origin isolation headers; see Browser requirements.
Import:
import {
CpModel,
CpSolver,
CpSolverSolutionCallback,
CpSat,
Domain,
LinearExpr,
sum,
weightedSum,
type CpModelProto,
type SatParameters,
} from 'or-tools-wasm/cp-sat';CP-SAT exposes two public API layers:
- A high-level Python-like model builder around
CpModelandCpSolver. - The proto-first
CpSatAPI for callers that build or serializeCpModelProtoobjects directly.
Prefer the high-level API for application code, and use CpSat when you need
direct generated protobuf access.
const model = new CpModel();
const x = model.newIntVar(0, 10, 'x');
const y = model.newIntVar(0, 10, 'y');
model.add(x.plus(y.times(2)).eq(14));
model.maximize(x.plus(y));
const solver = new CpSolver();
solver.parameters.numSearchWorkers = 4;
const status = await solver.solve(model);
console.log(solver.statusName(status));
console.log(solver.value(x), solver.value(y), solver.objectiveValue());The high-level CP-SAT API uses explicit expression methods because JavaScript does not support Python-style operator overloading. For example:
x.plus(y.times(2)).eq(29)instead ofx + 2 * y == 29x.le(10),x.lt(10),x.ge(0),x.gt(0),x.ne(y)x.not()orx.negated()for Boolean negation
Most high-level methods are exported in idiomatic camelCase, with snake_case aliases for Python parity where useful. Some PascalCase aliases are also present for compatibility with existing OR-Tools examples.
new CpModel(model?: CpModelProto)
Creates a high-level model. Passing an existing proto clones it into a wrapper.
Common variable methods:
newIntVar(lb, ub, name?)new_int_var(lb, ub, name?)NewIntVar(lb, ub, name?)newIntVarFromDomain(domain, name?)new_int_var_from_domain(domain, name?)NewIntVarFromDomain(domain, name?)newBoolVar(name?)new_bool_var(name?)NewBoolVar(name?)newConstant(value, name?)new_constant(value, name?)NewConstant(value, name?)getIntVarFromProtoIndex(index)get_int_var_from_proto_index(index)getBoolVarFromProtoIndex(index)get_bool_var_from_proto_index(index)getIntervalVarFromProtoIndex(index)get_interval_var_from_proto_index(index)
Model/proto helpers:
name: model name getter/setter.proto()/Proto(): returns the mutableCpModelProto.clone(): returns a newCpModelwrapper around a cloned proto.removeAllNames()remove_all_names()validate(): Promise<string>: returns''for a valid model, otherwise the native validation message.modelStats(): stringhasObjective(): booleangetOrMakeIndexFromConstant(value)get_or_make_index_from_constant(value)getOrMakeVariableIndex(variable)get_or_make_variable_index(variable)isBooleanValue(value)/is_boolean_value(value)isBooleanIndex(index)literalReferences(literals)
Linear constraints and objectives:
add(bound: BoundedLinearExpr | boolean)Add(bound)addLinearConstraint(expression, lb, ub)add_linear_constraint(expression, lb, ub)AddLinearConstraint(expression, lb, ub)addEquality(left, right)minimize(expression)Minimize(expression)maximize(expression)Maximize(expression)
Logical constraints:
addBoolOr(literals)add_bool_or(literals)AddBoolOr(literals)addBoolAnd(literals)add_bool_and(literals)AddBoolAnd(literals)addBoolXor(literals)add_bool_xor(literals)AddBoolXOr(literals)addAtLeastOne(literals)add_at_least_one(literals)addAtMostOne(literals)add_at_most_one(literals)addExactlyOne(literals)add_exactly_one(literals)addImplication(left, right)add_implication(left, right)addMapDomain(variable, booleanVariables, offset?)add_map_domain(variable, booleanVariables, offset?)
Integer and table constraints:
addAllDifferent(expressions)AddAllDifferent(expressions)addElement(index, expressions, target)addAllowedAssignments(expressions, tuples)addForbiddenAssignments(expressions, tuples)addAutomaton(expressions, startingState, finalStates, transitions)addCircuit(arcs)addMultipleCircuit(arcs)addInverse(direct, inverse)addMaxEquality(target, expressions)add_max_equality(target, expressions)addMinEquality(target, expressions)add_min_equality(target, expressions)addAbsEquality(target, expression)add_abs_equality(target, expression)addDivisionEquality(target, numerator, denominator)add_division_equality(target, numerator, denominator)addModuloEquality(target, expression, modulo)add_modulo_equality(target, expression, modulo)addMultiplicationEquality(target, expressions)add_multiplication_equality(target, expressions)
Scheduling constraints:
newIntervalVar(start, size, end, name?)new_interval_var(start, size, end, name?)newFixedSizeIntervalVar(start, size, name?)new_fixed_size_interval_var(start, size, name?)newOptionalFixedSizeIntervalVar(start, size, isPresent, name?)new_optional_fixed_size_interval_var(start, size, isPresent, name?)newOptionalIntervalVar(start, size, end, isPresent, name?)new_optional_interval_var(start, size, end, isPresent, name?)addNoOverlap(intervals)add_no_overlap(intervals)AddNoOverlap(intervals)addNoOverlap2D(xIntervals, yIntervals)add_no_overlap_2d(xIntervals, yIntervals)AddNoOverlap2D(xIntervals, yIntervals)addCumulative(intervals, demands, capacity)add_cumulative(intervals, demands, capacity)addReservoirConstraint(times, levelChanges, minLevel, maxLevel, activeLiterals?)
Search and hints:
addDecisionStrategy(expressions, variableSelectionStrategy, domainReductionStrategy)addHint(variable, value)addAssumption(literal)addAssumptions(literals)clearAssumptions()
The high-level package exports:
IntVar,BoolVar,NotBoolVarLinearExpr,BoundedLinearExpr,BoundedLinearExpressionFlatIntExpr,FlatFloatExprIntervalVar,ConstraintDomainValueError,RuntimeError,ArithmeticError,NotImplementedErrorsum(values),weightedSum(values, coeffs),term(variable, coeff)object_is_a_true_literal(literal),object_is_a_false_literal(literal)rebuild_from_linear_expression_proto(proto, modelProto)- camelCase aliases:
objectIsATrueLiteral,objectIsAFalseLiteral,rebuildFromLinearExpressionProto - types:
LinearExprLike,LiteralLike
Expression helpers:
LinearExpr.constant(value)LinearExpr.from(value)LinearExpr.affine(expression, coeff, offset)LinearExpr.sum(values)/LinearExpr.Sum(values)LinearExpr.weightedSum(values, coeffs)LinearExpr.weighted_sum(values, coeffs)LinearExpr.WeightedSum(values, coeffs)LinearExpr.term(variable, coeff)/LinearExpr.Term(variable, coeff)plus(value, coeff?),minus(value),times(coeff),neg()eq(value),ne(value),le(value),lt(value),ge(value),gt(value)toProto()isInteger()/is_integer()hasFloatingPointTerms()toString()andrepr()for display/debug parity with Python-style teststoFloatObjective(maximize?)
Unsupported Python-style operation methods such as abs(), div(),
truediv(), mod(), and the __pow__/bitwise helpers throw
NotImplementedError with guidance to use the matching CpModel constraint
method instead.
IntVar supports:
name,model_proto,expr()plus(value, coeff?),minus(value),times(coeff),neg()eq(value),ne(value),le(value),lt(value),ge(value),gt(value)isInteger()/is_integer()isBoolean()/is_booleannegated()for Boolean variablesdebugString(),repr(),toString()- Python-style helper aliases used by parity tests:
__add__,__mul__,__lt__,__gt__,__abs__,__div__,__truediv__,__mod__, and unsupported bitwise/power helpers.
BoolVar extends IntVar with:
literalIndexnot()
NotBoolVar supports:
variable,model,index,name,model_protonot()/negated()expr()plus(value, coeff?),minus(value),times(coeff),neg()isInteger()/is_integer()repr(),toString()
FlatIntExpr and FlatFloatExpr support:
varscoeffsoffsetexpr()plus(value),minus(value),times(coeff)repr(),toString()
BoundedLinearExpr supports:
expressionlowerBoundupperBounddomaintoString()
BoundedLinearExpression builds a BoundedLinearExpr from an expression and a
Domain.
Domain supports:
new Domain(lower, upper)new Domain(value)Domain.fromFlatIntervals(intervals)Domain.from_flat_intervals(intervals)Domain.fromIntervals(intervals)Domain.from_intervals(intervals)Domain.fromValues(values)Domain.from_values(values)flatIntervals
Constraint supports:
modelindexnamewithName(name)with_name(name)onlyEnforceIf(literals)
IntervalVar supports:
modelindexnamemodel_protostartExpr()sizeExpr()endExpr()presenceLiterals()repr(),toString()
new CpSolver()
High-level solver wrapper. It delegates to the proto-first CpSat runtime while
keeping the latest decoded response for Python-like result helpers.
solver.parameters
Mutable SatParameters object merged into every solve() call unless raw
parameters are passed.
solver.solve(model, paramsOrCallback?, callbacks?): Promise<CpSolverStatus | undefined>
Solves a CpModel. The second argument can be:
- a
SatParametersobject - raw
Uint8Arrayparameter bytes - a
CpSolverSolutionCallback null
Result helpers:
response()responseStats()solutionInfo()statusName(status?)value(expression)floatValue(expression)booleanValue(literal)objectiveValue()bestObjectiveBound()
Response properties:
response_protosolve_logobjective_valuebest_objective_boundwall_time/wallTimeuser_timedeterministic_timenum_booleans/numBooleansnum_conflicts/numConflictsnum_branches/numBranchesnum_integersnum_binary_propagationsnum_integer_propagations
Callbacks:
solver.bestBoundCallback = (bound) => {}solver.logCallback = (message) => {}- Python-style aliases:
best_bound_callback,log_callback
CpSolverSolutionCallback can be subclassed or assigned an
onSolutionCallback() method. During a callback, use value(), floatValue(),
booleanValue(), objectiveValue, bestObjectiveBound, and wallTime.
class Printer extends CpSolverSolutionCallback {
onSolutionCallback() {
console.log(this.value(x));
}
}
await solver.solve(model, new Printer());Build or serialize a CpModelProto, validate it, then solve it:
const modelBytes = await CpSat.createModel(model);
const validation = await CpSat.validate(modelBytes);
if (!validation.ok) throw new Error(validation.message);
const result = await CpSat.solve(modelBytes, {
numSearchWorkers: 4,
logSearchProgress: true,
});CpSat.createModel(model: CpModelProto): Promise<Uint8Array>
Encodes a JSON-like CpModelProto object into binary protobuf bytes. The input
uses the generated TypeScript CpModelProto shape from OR-Tools.
CpSat.validate(model: Uint8Array): Promise<{ ok: boolean; message: string }>
Runs native CP-SAT model validation. ok is false when OR-Tools rejects the
model; message contains the native validation message.
CpSat.solve(model: Uint8Array, params?: Uint8Array | SatParameters | null, callbacks?: CpSatSolveCallbacks): Promise<CpSatSolveResult>
Solves a binary CpModelProto. params can be binary SatParameters, a
JSON-like SatParameters object, or null. The returned CpSatSolveResult
contains:
response: decodedCpSolverResponse | nullbytes: raw binaryCpSolverResponse
callbacks may contain:
onSolution(response, bytes): called for intermediate solutions when enabled by compatible solver parameters.onBestBound(bound): called on best-bound updates.onLog(message): called for solver log output.
CpSat.solveRaw(model: Uint8Array, params?: Uint8Array | null): Promise<Uint8Array>
Low-level solve that returns raw CpSolverResponse bytes and accepts only raw
parameter bytes.
CpSat.cancelSolve(): Promise<void>
Requests cancellation of the active CP-SAT solve.
CpSat.getSchemas(): Promise<{ cp_model: string; sat_parameters: string; linear_solver?: string; optional_boolean?: string }>
Returns embedded .proto schemas. CP-SAT always returns cp_model and
sat_parameters; MPSolver-related schemas may be present when fetched through
the worker path.
CpSat.loadModule(): Promise<unknown>
Loads the CP-SAT WebAssembly module directly. This is mostly an escape hatch;
normal application code should use solve().
CpSat.setWorkerBridgeEnabled(enabled: boolean): void
Alias for the shared package worker bridge control.
CpSat.isWorkerBridgeEnabled(): boolean
Alias for the shared package worker bridge state.
The package exports generated CP-SAT protobuf types and enums, including:
CpModelProtoCpSolverResponseSatParametersCpSolverStatusDecisionStrategyProto_DomainReductionStrategyDecisionStrategyProto_VariableSelectionStrategy
It also re-exports the generated cp_model symbols, so generated nested
message types are available from the package entrypoint.
Import:
import {
Assignment,
BoundCost,
DefaultRoutingModelParameters,
initRouting,
LocalSearchMetaheuristic,
RoutingIndexManager,
RoutingModel,
RoutingSearchStatus,
DefaultRoutingSearchParameters,
FirstSolutionStrategy,
} from 'or-tools-wasm/routing';Initialize the routing runtime before constructing routing objects when using the direct runtime path. In browser worker-bridge mode this is a no-op, but awaiting it keeps the same code portable across runtimes:
await initRouting();
const manager = new RoutingIndexManager(distanceMatrix.length, 1, 0);
const routing = new RoutingModel(manager);
const transit = routing.RegisterTransitCallback((from, to) => {
return distanceMatrix[manager.IndexToNode(from)][manager.IndexToNode(to)];
});
routing.SetArcCostEvaluatorOfAllVehicles(transit);
const params = DefaultRoutingSearchParameters();
params.firstSolutionStrategy = FirstSolutionStrategy.PATH_CHEAPEST_ARC;
const assignment = await routing.SolveWithParameters(params);The Routing API is a high-level wrapper around the compiled OR-Tools Routing runtime. It keeps Python-style method names for parity with upstream examples and tests.
initRouting(): Promise<void>
Loads the routing WebAssembly runtime for direct solves. Construction of
RoutingIndexManager or RoutingModel before this resolves will throw on
direct runtime paths.
Constructors:
new RoutingIndexManager(numLocations, numVehicles, depot)
new RoutingIndexManager(numLocations, numVehicles, starts, ends)Methods:
indexToNode(index): Promise<number>nodeToIndex(node): Promise<number>indexToNodeSync(index): numbernodeToIndexSync(node): numberIndexToNode(index): numberNodeToIndex(node): numberGetNumberOfNodes(): numberGetNumberOfVehicles(): numberGetNumberOfIndices(): numberGetStartIndex(vehicle): numberGetEndIndex(vehicle): numberdelete(): void
Properties:
ready: Promise<void>numLocations: numbernumVehicles: numberstarts: number[]ends: number[]depot: number
Construction:
const routing = new RoutingModel(manager, parameters?);Callbacks and costs:
RegisterTransitCallback((fromIndex, toIndex) => number): numberRegisterTransitMatrix(matrix: number[][]): numberRegisterUnaryTransitCallback((fromIndex) => number): numberRegisterUnaryTransitVector(values: number[]): numberSetArcCostEvaluatorOfAllVehicles(evaluatorIndex): voidGetArcCostForVehicle(fromIndex, toIndex, vehicle): number
Dimensions:
AddDimension(transitIndex, slackMax, capacity, fixStartCumulToZero, name): booleanAddDimensionWithVehicleCapacity(transitIndex, slackMax, capacities, fixStartCumulToZero, name): booleanAddDimensionWithVehicleTransits(transitIndices, slackMax, capacity, fixStartCumulToZero, name): booleanAddConstantDimension(value, capacity, fixStartCumulToZero, name): [number, boolean]AddVectorDimension(values, capacity, fixStartCumulToZero, name): [number, boolean]AddMatrixDimension(matrix, capacity, fixStartCumulToZero, name): [number, boolean]GetDimensionOrDie(name): RoutingDimension
Search and assignments:
Solve(): Promise<Assignment | null>SolveWithParameters(parameters): Promise<Assignment | null>solveWithParametersSync(parameters): Assignment | nullSolveFromAssignmentWithParameters(assignment, parameters): Promise<Assignment | null>ReadAssignmentFromRoutes(routes, ignoreInactiveIndices): AssignmentCloseModelWithParameters(parameters): voidstatus(): RoutingSearchStatus
Route structure and model helpers:
Start(vehicle): numberEnd(vehicle): numberIsEnd(index): booleanNextVar(index): numberVehicleVar(index): RoutingVehicleVarvehicles(): numberAddDisjunction(indices, penalty?): numberAddPickupAndDelivery(pickup, delivery): voidAddAtSolutionCallback(callback): voidGetAutomaticFirstSolutionStrategy(): FirstSolutionStrategyGetNumberOfDecisionsInFirstSolution(parameters): numberGetNumberOfRejectsInFirstSolution(parameters): numberCostVar(): { Max(): number }solver(): { Parameters(): { trace_propagation: boolean }; LocalSearchProfile(): string; Add(...): void }delete(): void
NextVar(index) returns an opaque next-variable handle represented by the
index. Pass that value to assignment.Value(...). VehicleVar(index) returns
an opaque vehicle-variable handle for solver constraints.
Advanced assignment helpers are also exposed for parity with the current wrapper implementation:
assignmentObjectiveValue(): numbernextValue(index): numberdimensionCumulValue(dimensionName, index): number
These helpers read values from the current assignment state and are usually
used through Assignment.
routing.solver().Add(...) accepts the routing constraint objects currently
needed for pickup-and-delivery parity. JavaScript does not support Python-style
operator overloading, so constraints are explicit objects:
routing.AddPickupAndDelivery(pickupIndex, deliveryIndex);
routing.solver().Add({
type: 'routingVehicleEquality',
left: routing.VehicleVar(pickupIndex),
right: routing.VehicleVar(deliveryIndex),
});
const distance = routing.GetDimensionOrDie('distance');
routing.solver().Add({
type: 'routingCumulLessOrEqual',
left: distance.CumulVar(pickupIndex),
right: distance.CumulVar(deliveryIndex),
});Supported solver constraint object shapes:
{ type: 'routingVehicleEquality', left: routing.VehicleVar(...), right: routing.VehicleVar(...) }{ type: 'routingCumulLessOrEqual', left: dimension.CumulVar(...), right: dimension.CumulVar(...) }
Unknown constraint objects are ignored by the compatibility shim.
CumulVar(index): RoutingCumulVarHasSoftSpanUpperBounds(): booleanSetSoftSpanUpperBoundForVehicle(boundCost, vehicle): voidGetSoftSpanUpperBoundForVehicle(vehicle): BoundCostHasQuadraticCostSoftSpanUpperBounds(): booleanSetQuadraticCostSoftSpanUpperBoundForVehicle(boundCost, vehicle): voidGetQuadraticCostSoftSpanUpperBoundForVehicle(vehicle): BoundCost
CumulVar(index) returns an opaque cumul-variable handle for assignment reads
and solver constraints.
new BoundCost(bound = 0, cost = 0)Fields:
bound: numbercost: number
ObjectiveValue(): numberValue(indexOrVar): numberMin(indexOrVar): number
For NextVar(index), pass the returned value into assignment.Value() to get
the next index. For dimensions, pass dimension.CumulVar(index).
DefaultRoutingSearchParameters(): RoutingSearchParametersDefaultRoutingModelParameters(): RoutingModelParametersFindErrorInRoutingSearchParameters(params): stringBOOL_FALSE,BOOL_TRUE,BOOL_UNSPECIFIED
RoutingSearchParameters currently exposes the subset used by the bridge:
firstSolutionStrategy?: FirstSolutionStrategysolution_limit?: numberlocal_search_operators?: Record<string, unknown>local_search_metaheuristic?: LocalSearchMetaheuristic
RoutingModelParameters exposes:
solver_parameters.CopyFrom(value): voidsolver_parameters.trace_propagation: booleansolver_parameters.profile_local_search: boolean
FindErrorInRoutingSearchParameters(params) returns an empty string when the
supported parameter subset is valid.
FirstSolutionStrategy contains:
UNSETAUTOMATICPATH_CHEAPEST_ARCPATH_MOST_CONSTRAINED_ARCEVALUATOR_STRATEGYSAVINGSSWEEPCHRISTOFIDESALL_UNPERFORMEDBEST_INSERTIONPARALLEL_CHEAPEST_INSERTIONSEQUENTIAL_CHEAPEST_INSERTIONLOCAL_CHEAPEST_INSERTIONLOCAL_CHEAPEST_COST_INSERTIONGLOBAL_CHEAPEST_ARCLOCAL_CHEAPEST_ARCFIRST_UNBOUND_MIN_VALUE
LocalSearchMetaheuristic contains:
UNSETGUIDED_LOCAL_SEARCH
RoutingSearchStatus contains:
ROUTING_NOT_SOLVEDROUTING_SUCCESSROUTING_PARTIAL_SUCCESS_LOCAL_OPTIMUM_NOT_REACHEDROUTING_FAILROUTING_FAIL_TIMEOUTROUTING_INVALIDROUTING_INFEASIBLEROUTING_OPTIMAL
Import:
import { initMPSolver, MPSolver, MPSolverParameters } from 'or-tools-wasm/mp-solver';Initialize before constructing solvers:
await initMPSolver();
const solver = MPSolver.CreateSolver('GLOP'); // or 'CLP' / 'GLPK_LP' for LP backends
if (!solver) throw new Error('LP backend unavailable');
const x = solver.NumVar(0, solver.infinity(), 'x');
const y = solver.NumVar(0, solver.infinity(), 'y');
const c = solver.Constraint(-solver.infinity(), 14, 'c');
c.SetCoefficient(x, 1);
c.SetCoefficient(y, 2);
solver.Objective().SetCoefficient(x, 3);
solver.Objective().SetCoefficient(y, 1);
solver.Objective().SetMaximization();
const status = await solver.Solve();initMPSolver(): Promise<void>
Loads the MPSolver WebAssembly runtime for direct solves. When the browser
worker bridge is enabled, model objects use bridge-backed handles and
initMPSolver() is a no-op.
OptimizationProblemType contains OR-Tools MPSolver problem type ids, including
GLOP_LINEAR_PROGRAMMING, CLP_LINEAR_PROGRAMMING, PDLP_LINEAR_PROGRAMMING,
SAT_INTEGER_PROGRAMMING, GLPK_LINEAR_PROGRAMMING,
SCIP_MIXED_INTEGER_PROGRAMMING, GLPK_MIXED_INTEGER_PROGRAMMING,
CBC_MIXED_INTEGER_PROGRAMMING, BOP_INTEGER_PROGRAMMING,
KNAPSACK_MIXED_INTEGER_PROGRAMMING, and
others. Only problem types compiled into the WebAssembly runtime will be supported at runtime; use
MPSolver.SupportsProblemType().
The default package runtime currently includes GLOP, CLP, and GLPK_LP for
continuous linear programming, plus SAT, GLPK, SCIP, CBC, BOP, and
KNAPSACK for integer linear programming through MPSolver.
MPSolverResultStatus contains OPTIMAL, FEASIBLE, INFEASIBLE,
UNBOUNDED, ABNORMAL, MODEL_INVALID, and NOT_SOLVED.
Basis status values are returned by basis_status() and are also exposed as
static constants on MPSolver: FREE, AT_LOWER_BOUND, AT_UPPER_BOUND,
FIXED_VALUE, and BASIC.
Static helpers:
CreateSolver(solverId): MPSolver | nullInfinity(): numberSupportsProblemType(problemType): booleanParseSolverType(solverId): OptimizationProblemType | nullParseAndCheckSupportForProblemType(solverId): OptimizationProblemType | nullgetLinearSolverSchemas(): Promise<LinearSolverSchemas>createModelRequest(request): Promise<Uint8Array>createSolutionResponse(response): Promise<Uint8Array>decodeSolutionResponse(bytes): Promise<MPSolverSolutionResponse>solveModelRequest(request): Promise<MPSolverProtoSolveResult>
Construction:
new MPSolver(name, problemType)Core model methods:
Name(): stringProblemType(): OptimizationProblemTypeIsMIP()/IsMip(): booleanClear(): voidinfinity(): numberNumVariables(): numberNumConstraints(): numbervariable(index): MPVariablevariables(): MPVariable[]constraint(index): MPConstraintconstraints(): MPConstraint[]LookupVariableOrNull(name): MPVariable | nullLookupVariable(name): MPVariable | nullLookupConstraintOrNull(name): MPConstraint | nullLookupConstraint(name): MPConstraint | nullObjective(): MPObjective
Variables:
Var(lb, ub, integer, name): MPVariableNumVar(lb, ub, name): MPVariableIntVar(lb, ub, name): MPVariableBoolVar(name): MPVariable
Constraints:
Constraint(): MPConstraintConstraint(name): MPConstraintConstraint(lb, ub, name?): MPConstraintRowConstraint(...): same overloads asConstraint
Solving and solution loading:
Solve(parameters?): Promise<MPSolverResultStatus>SolveWithProto(options?): Promise<MPSolverProtoSolveResult & { loaded: boolean }>LoadSolutionFromProto(response?, tolerance?): Promise<boolean>exportModelProto(): Promise<Uint8Array>exportModelRequestProto(options?): Promise<Uint8Array>VerifySolution(tolerance, logErrors): booleanReset(): voidInterruptSolve(): booleanNextSolution(): boolean
Options and output:
EnableOutput(): voidSuppressOutput(): voidOutputIsEnabled(): booleanSetTimeLimit(milliseconds): voidset_time_limit(milliseconds): voidtime_limit(): numberSetNumThreads(numThreads): booleanGetNumThreads(): numberSetSolverSpecificParametersAsString(parameters): booleanGetSolverSpecificParametersAsString(): stringSolverVersion(): stringComputeConstraintActivities(): number[]ComputeExactConditionNumber(): numberSetHint(variables, values): voidExportModelAsLpFormat(obfuscate): stringExportModelAsMpsFormat(fixedFormat, obfuscate): stringWallTime()/wall_time(): numberIterations()/iterations(): numbernodes(): numberdelete(): void
SolutionValue()/solution_value(): numberunrounded_solution_value(): numberReducedCost()/reduced_cost(): numberbasis_status(): numberindex(): numbername(): stringLb(): numberUb(): numberSetBounds(lb, ub): voidSetLb(lb)/SetLB(lb): voidSetUb(ub)/SetUB(ub): voidInteger(): booleanSetInteger(integer): voidbranching_priority(): numberSetBranchingPriority(priority): void
SetCoefficient(variable, coefficient): voidGetCoefficient(variable): numberClear(): voidindex(): numbername(): stringLb(): numberUb(): numberSetBounds(lb, ub): voidSetLb(lb)/SetLB(lb): voidSetUb(ub)/SetUB(ub): voidDualValue()/dual_value(): numberbasis_status(): numberis_lazy(): booleanset_is_lazy(laziness): void
Clear(): voidSetCoefficient(variable, coefficient): voidGetCoefficient(variable): numberSetOffset(offset): voidAddOffset(offset): voidOffset()/offset(): numberSetOptimizationDirection(maximize): voidSetMinimization(): voidSetMaximization(): voidValue(): numberBestBound(): numbermaximization(): booleanminimization(): boolean
Use new MPSolverParameters() and pass it to solver.Solve(parameters).
SetDoubleParam(param, value): voidGetDoubleParam(param): numberResetDoubleParam(param): voidSetIntegerParam(param, value): voidGetIntegerParam(param): numberResetIntegerParam(param): voidReset(): voiddelete(): void
Parameter enums:
DoubleParam:RELATIVE_MIP_GAP,PRIMAL_TOLERANCE,DUAL_TOLERANCEIntegerParam:PRESOLVE,LP_ALGORITHM,INCREMENTALITY,SCALINGPresolveValues:PRESOLVE_OFF,PRESOLVE_ONLpAlgorithmValues:DUAL,PRIMAL,BARRIERIncrementalityValues:INCREMENTALITY_OFF,INCREMENTALITY_ONScalingValues:SCALING_OFF,SCALING_ON
The dedicated Knapsack API mirrors
ortools.algorithms.python.knapsack_solver.KnapsackSolver and uses the
MPSolver WebAssembly runtime.
import {
initKnapsack,
KnapsackSolver,
KnapsackSolverType,
setWorkerBridgeEnabled,
} from 'or-tools-wasm/knapsack';
setWorkerBridgeEnabled(true);
await initKnapsack();
const solver = new KnapsackSolver(
KnapsackSolverType.KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER,
'knapsack',
);
solver.init(
[360, 83, 59, 130],
[[7, 0, 30, 22]],
[50],
);
const profit = await solver.solve();
const selected = [0, 1, 2, 3].filter((item) => solver.best_solution_contains(item));
console.log(profit, selected, solver.is_solution_optimal());initKnapsack(): Promise<void> loads the shared MPSolver/Knapsack runtime for
direct solves. When the browser worker bridge is enabled, it is a no-op and the
solve path runs through the worker bridge.
KnapsackSolverType exposes the upstream solver ids:
KNAPSACK_BRUTE_FORCE_SOLVERKNAPSACK_64ITEMS_SOLVERKNAPSACK_DYNAMIC_PROGRAMMING_SOLVERKNAPSACK_MULTIDIMENSION_CBC_MIP_SOLVERKNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVERKNAPSACK_MULTIDIMENSION_SCIP_MIP_SOLVERKNAPSACK_MULTIDIMENSION_XPRESS_MIP_SOLVERKNAPSACK_MULTIDIMENSION_CPLEX_MIP_SOLVERKNAPSACK_DIVIDE_AND_CONQUER_SOLVERKNAPSACK_MULTIDIMENSION_CP_SAT_SOLVER
KnapsackSolver supports init() / Init(), solve() / Solve(),
best_solution_contains() / BestSolutionContains(),
is_solution_optimal() / IsSolutionOptimal(), set_use_reduction() /
SetUseReduction(), and set_time_limit() / SetTimeLimit().
The MPSolver frontend also exposes
KNAPSACK_MIXED_INTEGER_PROGRAMMING, MPSolver.CreateSolver('KNAPSACK'), and
the proto solve path for knapsack-shaped 0-1 models.
The dedicated Set Cover API mirrors
ortools.set_cover.python.set_cover for weighted set covering models,
solution invariants, and heuristic searches. It uses its own Set Cover
WebAssembly runtime.
import {
GreedySolutionGenerator,
initSetCover,
SetCoverInvariant,
SetCoverModel,
setWorkerBridgeEnabled,
} from 'or-tools-wasm/set-cover';
setWorkerBridgeEnabled(true);
await initSetCover();
const model = new SetCoverModel();
model.add_empty_subset(2.0);
model.add_element_to_last_subset(0);
model.add_empty_subset(2.0);
model.add_element_to_last_subset(1);
model.add_empty_subset(1.0);
model.add_element_to_last_subset(0);
model.add_element_to_last_subset(1);
const inv = new SetCoverInvariant(model);
const greedy = new GreedySolutionGenerator(inv);
if (await greedy.next_solution()) {
console.log(inv.cost(), inv.export_solution_as_proto().subset);
}initSetCover(): Promise<void> loads the Set Cover runtime for direct solves.
When the browser worker bridge is enabled, it is a no-op and heuristic search
calls run through the worker bridge.
SetCoverModel exposes Python-style methods and properties:
- properties:
name,num_elements,num_subsets,num_nonzeros,fill_rate,subset_costs,columns,rows,row_view_is_valid,all_subsets SubsetRange(): number[]ElementRange(): number[]set_name(name): voidadd_empty_subset(cost): voidadd_element_to_last_subset(element): voidadd_element_to_subset(element, subset): voidset_subset_cost(subset, cost): voidcreate_sparse_row_view(): voidsort_elements_in_subsets(): voidcompute_feasibility(): booleanresize_num_subsets(numSubsets): voidreserve_num_elements_in_subset(numElements, subset): voidexport_model_as_proto(): SetCoverModelProtoimport_model_from_proto(proto): voidcompute_cost_stats(),compute_row_stats(),compute_column_stats()compute_row_deciles(),compute_column_deciles()
SetCoverInvariant exposes:
initialize(),clear(),model()cost(): numbernum_uncovered_elements(): numberis_selected(): boolean[]coverage(): number[]num_free_elements(): number[]num_coverage_le_1_elements(): number[]compute_coverage_in_focus(focus): number[]is_redundant(): boolean[]trace(): SetCoverDecision[],clear_trace(),compress_trace()clear_removability_information(),newly_removable_subsets(),newly_non_removable_subsets()load_solution(solution): voidcheck_consistency(consistency): booleancompute_is_redundant(subset): booleanrecompute(): voidselect(subset, consistency): booleandeselect(subset, consistency): booleanexport_solution_as_proto(): SetCoverSolutionResponseimport_solution_from_proto(proto): void
consistency_level / ConsistencyLevel exposes
COST_AND_COVERAGE, FREE_AND_UNCOVERED, and REDUNDANCY.
Solution generators and searches expose next_solution() and
set_max_iterations():
TrivialSolutionGeneratorRandomSolutionGeneratorGreedySolutionGeneratorElementDegreeSolutionGeneratorLazyElementDegreeSolutionGeneratorSteepestSearchGuidedLocalSearchGuidedTabuSearch
GuidedTabuSearch also exposes set_lagrangian_factor(),
get_lagrangian_factor(), set_epsilon(), get_epsilon(),
set_penalty_factor(), get_penalty_factor(), set_tabu_list_size(), and
get_tabu_list_size(). TabuList, clear_random_subsets(), and
clear_most_covered_elements() are available for compatibility with the
Python wrapper surface.
Model and solution proto helpers are object-based in the browser-oriented
runtime: use export_model_as_proto() / import_model_from_proto() and
export_solution_as_proto() / import_solution_from_proto(). File-based
helpers such as read_set_cover_proto(), write_set_cover_proto(),
read_orlib_scp(), read_orlib_rail(), and read_fimi_dat() are exported for
API discoverability but throw because package consumers do not share a native
OR-Tools filesystem.
Set Cover is single-threaded in this package. It supports the shared browser worker bridge, so UI code can run heuristic searches off the main thread, but there is no solver thread-count parameter.
The dedicated RCPSP API provides a Python-like parser surface for
ortools.scheduling.python.rcpsp and a higher-level TypeScript project
scheduling builder that compiles to CP-SAT scheduling constraints.
import {
initRcpsp,
RcpspModelBuilder,
setWorkerBridgeEnabled,
} from 'or-tools-wasm/rcpsp';
setWorkerBridgeEnabled(true);
await initRcpsp();
const project = new RcpspModelBuilder('house_project')
.add_resource({ name: 'crew', capacity: 3 })
.add_activity({ name: 'site', duration: 3, demands: { crew: 2 }, successors: ['frame'] })
.add_activity({ name: 'permit', duration: 2, demands: { crew: 1 }, successors: ['wire'] })
.add_activity({ name: 'frame', duration: 4, demands: { crew: 2 }, successors: ['inspect'] })
.add_activity({ name: 'wire', duration: 2, demands: { crew: 1 }, successors: ['inspect'] })
.add_activity({ name: 'inspect', duration: 1, demands: { crew: 1 } })
.build();
const result = await project.solve({ numWorkers: 4, maxTimeInSeconds: 5 });
console.log(result.statusName, result.makespan, result.tasks);initRcpsp(): Promise<void> is a compatibility no-op. RCPSP currently reuses
the CP-SAT solve path instead of loading a separate native runtime; calling
solve() loads or uses the CP-SAT runtime as needed.
RcpspModelBuilder exposes:
add_resource({ name, capacity, renewable? })add_activity({ name, duration, demands?, successors? })build(): RcpspProblem
RcpspProblem exposes:
RcpspProblem.from_proto(proto)/fromProto(proto)RcpspProblem.from_psplib(text)/fromPsplib(text)- properties:
name,resources,tasks,horizon export_model_as_proto()/exportModelAsProto()to_cp_sat_model()/toCpSatModel()solve(params?: SatParameters): Promise<RcpspSolveResult>
RcpspSolveResult contains:
statusandstatusNamemakespanobjectiveValue- scheduled
taskswithname,start,end,duration,demands, andsuccessors - the generated
CpModel,starts,ends, andmakespanVarfor callers that need the lower-level CP-SAT model path
RcpspParser mirrors the upstream Python wrapper shape with problem() and
parse_string(). parse_file() is exported for API discoverability but throws
in this browser-oriented package because consumers do not share a native
OR-Tools filesystem; pass file contents to parse_string() instead.
The CP-SAT-backed builder supports the standard renewable-resource RCPSP case:
activities, durations, precedence constraints, renewable resource capacities,
and makespan minimization. RCPSP/Max delays, resource-investment objectives, and
consumer/producer instances are parsed as proto data but rejected by
to_cp_sat_model() / solve() until those variants have a dedicated model
translation.
The dedicated Network Flow API mirrors the Python graph wrappers for
SimpleMaxFlow, SimpleMinCostFlow, and SimpleLinearSumAssignment.
import { initNetworkFlow, SimpleMaxFlow, setWorkerBridgeEnabled } from 'or-tools-wasm/network-flow';
setWorkerBridgeEnabled(true);
await initNetworkFlow();
const maxFlow = new SimpleMaxFlow();
const arcs = maxFlow.add_arcs_with_capacity(
[0, 0, 0, 1, 1, 2, 2, 3, 3],
[1, 2, 3, 2, 4, 3, 4, 2, 4],
[20, 30, 10, 40, 30, 10, 20, 5, 20],
);
const status = await maxFlow.solve(0, 4);
if (status === SimpleMaxFlow.OPTIMAL) {
console.log(maxFlow.optimal_flow(), maxFlow.flows(arcs));
}initNetworkFlow(): Promise<void> loads the graph WebAssembly runtime for
direct solves. When the browser worker bridge is enabled, it is a no-op and
graph solves run through the worker bridge.
SimpleMaxFlow exposes Python-style snake_case methods and camelCase aliases:
- status constants:
OPTIMAL,POSSIBLE_OVERFLOW,BAD_INPUT,BAD_RESULT add_arc_with_capacity(tail, head, capacity): numberadd_arcs_with_capacity(tails, heads, capacities): number[]set_arc_capacity(arc, capacity): voidset_arcs_capacity(arcs, capacities): voidnum_nodes()/numNodes(): numbernum_arcs()/numArcs(): numbertail(arc),head(arc),capacity(arc): numbersolve(source, sink): Promise<number>optimal_flow()/optimalFlow(): numberflow(arc): numberflows(arcs): number[]get_source_side_min_cut()/getSourceSideMinCut(): number[]get_sink_side_min_cut()/getSinkSideMinCut(): number[]
SimpleMinCostFlow exposes:
- status constants:
NOT_SOLVED,OPTIMAL,FEASIBLE,INFEASIBLE,UNBALANCED,BAD_RESULT,BAD_COST_RANGE,BAD_CAPACITY_RANGE add_arc_with_capacity_and_unit_cost(tail, head, capacity, unitCost): numberadd_arcs_with_capacity_and_unit_cost(tails, heads, capacities, unitCosts): number[]set_arc_capacity(arc, capacity): voidset_arc_capacities(arcs, capacities): voidset_node_supply(node, supply): voidset_nodes_supplies(nodes, supplies): voidnum_nodes(),num_arcs(),tail(arc),head(arc),capacity(arc)supply(node),unit_cost(arc)/unitCost(arc)solve(): Promise<number>solve_max_flow_with_min_cost()/solveMaxFlowWithMinCost(): Promise<number>optimal_cost()/optimalCost(): numbermaximum_flow()/maximumFlow(): numberflow(arc): numberflows(arcs): number[]
SimpleLinearSumAssignment exposes:
- status constants:
OPTIMAL,INFEASIBLE,POSSIBLE_OVERFLOW add_arc_with_cost(leftNode, rightNode, cost): numberadd_arcs_with_cost(leftNodes, rightNodes, costs): number[]num_nodes()/numNodes(): numbernum_arcs()/numArcs(): numberleft_node(arc)/leftNode(arc): numberright_node(arc)/rightNode(arc): numbercost(arc): numbersolve(): Promise<number>optimal_cost()/optimalCost(): numberright_mate(leftNode)/rightMate(leftNode): numberassignment_cost(leftNode)/assignmentCost(leftNode): number
Network Flow algorithms are single-threaded in this package. They support the shared browser worker bridge, so UI code can run graph solves off the main thread, but there is no solver thread-count parameter.
Import:
import { GScipParameters, GlpkParameters, initMathOpt, MathOpt, MathOptModel, MathOptObjective } from 'or-tools-wasm/mathopt';Initialize, build a model, and solve:
await initMathOpt();
const model = MathOpt.Model('basic');
const x = model.addVariable({ lowerBound: 0, upperBound: 1, name: 'x' });
const y = model.addVariable({ lowerBound: 0, upperBound: 2, name: 'y' });
model.addLinearConstraint({
upperBound: 1.5,
terms: [MathOpt.linearTerm(x), MathOpt.linearTerm(y)],
});
model.maximize([MathOpt.linearTerm(x, 2), MathOpt.linearTerm(y)]);
const result = await MathOpt.solve(model, { solverType: MathOpt.SolverType.GLOP });initMathOpt(): Promise<void>
Loads the MathOpt WebAssembly runtime. When the browser worker bridge is enabled, it initializes the MathOpt worker runtime instead.
Static constructors and aliases:
MathOpt.Model(name?): MathOptModelMathOpt.SolverTypeMathOpt.LinearExpressionMathOpt.QuadraticExpressionMathOpt.QuadraticTermKeyMathOpt.VarEqVarMathOpt.BoundedExpressionMathOpt.LowerBoundedExpressionMathOpt.UpperBoundedExpressionMathOpt.LPAlgorithmMathOpt.EmphasisMathOpt.GScipEmphasisMathOpt.GScipMetaParamValueMathOpt.GScipParametersMathOpt.GlopParametersMathOpt.PdlpParametersMathOpt.PdlpOptimalityNormMathOpt.PdlpSchedulerTypeMathOpt.PdlpRestartStrategyMathOpt.PdlpLinesearchRuleMathOpt.GlpkParametersMathOpt.SolveInterrupterMathOpt.IncrementalSolverMathOpt.SolveParametersMathOpt.ModelSolveParametersMathOpt.SparseVectorFilterMathOpt.SolutionHintMathOpt.setWorkerBridgeEnabled(enabled): voidMathOpt.isWorkerBridgeEnabled(): booleanMPSolver.setWorkerBridgeEnabled(enabled): voidMPSolver.isWorkerBridgeEnabled(): booleanPdlp.setWorkerBridgeEnabled(enabled): voidPdlp.isWorkerBridgeEnabled(): booleanNetworkFlow.setWorkerBridgeEnabled(enabled): voidNetworkFlow.isWorkerBridgeEnabled(): booleanRoutingModel.setWorkerBridgeEnabled(enabled): voidRoutingModel.isWorkerBridgeEnabled(): boolean
Top-level value exports:
initMathOptMathOptsetWorkerBridgeEnabledisWorkerBridgeEnabledisWorkerBridgeAvailableterminateWorkerBridgeterminateLoadedRuntimeThreadsMathOptModelMathOptObjectiveMathOptIndicatorConstraintMathOptSolveInterrupterMathOptIncrementalSolverMathOptSolveParametersMathOptModelSolveParametersMathOptSparseVectorFilterMathOptSolutionHintMathOptSolverTypeMathOptLPAlgorithmMathOptEmphasisGScipEmphasisGScipMetaParamValuePdlpOptimalityNormPdlpSchedulerTypePdlpRestartStrategyPdlpLinesearchRuleGScipParametersGlopParametersPdlpParametersGlpkParameters
Top-level type exports:
MathOptDualSolutionResultMathOptDualRayResultMathOptBasisResultMathOptIndicatorConstraintOptionsMathOptLinearConstraintMathOptLinearConstraintMatrixEntryMathOptLinearTermMathOptModelSolveParametersOptionsMathOptPrimalSolutionResultMathOptPrimalRayResultMathOptSolutionResultMathOptSolutionHintOptionsMathOptSolveInterrupterLikeMathOptSolveOptionsMathOptSolveParametersOptionsMathOptSolveResultMathOptSparseVectorFilterInputMathOptSparseVectorFilterOptionsMathOptVariableMathOptVariableOptionsGScipParametersOptionsGlopParametersOptionsGlpkParametersOptionsPdlpParametersOptions
Solving:
MathOpt.solve(model, options?): Promise<MathOptSolveResult>MathOpt.encodeSolveRequest(model, options?): Uint8Arraynew MathOpt.IncrementalSolver(model, solverType?, options?)incrementalSolver.solve(options?): Promise<MathOptSolveResult>incrementalSolver.Solve(options?): Promise<MathOptSolveResult>incrementalSolver.close(): Promise<void>
MathOptSolveOptions:
solverType?: MathOptSolverType | keyof typeof MathOptSolverTyperemoveNames?: booleaninterrupter?: MathOptSolveInterruptermessageCallback?: (messages: string[]) => voidmsg_cb?: (messages: string[]) => voidparameters?: Uint8Array | MathOptSolveParameters | MathOptSolveParametersOptionssolveParameters?: Uint8Array | MathOptSolveParameters | MathOptSolveParametersOptionsmodelParameters?: Uint8Array | MathOptModelSolveParameters | MathOptModelSolveParametersOptionstimeLimitSeconds?: numberthreads?: numberiterationLimit?: numbernodeLimit?: numbercutoffLimit?: numberobjectiveLimit?: numberbestBoundLimit?: numbersolutionLimit?: numberenableOutput?: booleanrandomSeed?: numberabsoluteGapTolerance?: numberrelativeGapTolerance?: numbersolutionPoolSize?: numberlpAlgorithm?: MathOptLPAlgorithm | keyof typeof MathOptLPAlgorithmpresolve?: MathOptEmphasis | keyof typeof MathOptEmphasiscuts?: MathOptEmphasis | keyof typeof MathOptEmphasisheuristics?: MathOptEmphasis | keyof typeof MathOptEmphasisscaling?: MathOptEmphasis | keyof typeof MathOptEmphasisgscip?: GScipParameters | GScipParametersOptions | Uint8Arrayglop?: GlopParameters | GlopParametersOptions | Uint8ArraycpSat?: SatParameters | Uint8Arraypdlp?: PdlpParameters | PdlpParametersOptions | Uint8Arrayglpk?: GlpkParameters | GlpkParametersOptions | Uint8Array
Snake-case aliases are accepted for proto-shaped names where they are useful
for Python/protobuf parity, for example time_limit_seconds,
relative_gap_tolerance, remove_names, cp_sat, and
compute_unbound_rays_if_possible.
removeNames / remove_names omits model, variable, linear constraint, and
indicator constraint names from the encoded ModelProto, matching upstream
MathOpt solve(remove_names=True) behavior for models with duplicate names.
messageCallback / msg_cb receives batched solver log lines after the WASM
solve returns. Passing a message callback enables solver output capture and
also stores the captured lines on MathOptSolveResult.messages.
MathOpt.SolveInterrupter mirrors the upstream one-shot interrupter shape for
MathOpt solves. Call interrupt() before passing it as interrupter to request
early termination; the result exposes the corresponding termination limit.
MathOpt.solve(model, options?) is the stateless/full solve path. It encodes
the current model into a SolveRequest, solves it, and does not keep a native
solver handle for later reuse. Use MathOpt.encodeSolveRequest(model, options?)
when you need the raw proto-oriented request bytes.
MathOpt.IncrementalSolver keeps a native MathOpt solver handle alive across
solves. Construct it with the MathOptModel instance you intend to mutate, then
call solve() after each model edit:
const model = MathOpt.Model('rolling_lp');
const x = model.addVariable({ lowerBound: 0, upperBound: 1, name: 'x' });
model.maximize([{ variable: x, coefficient: 2 }]);
const solver = new MathOpt.IncrementalSolver(model, MathOpt.SolverType.GLOP, {
presolve: MathOpt.Emphasis.OFF,
});
let result = await solver.solve();
x.upperBound = 3;
result = await solver.solve(); // sends the bound update to the native solver
await solver.close();Tracked incremental updates include variable bounds/integrality, linear
constraint bounds, objective changes, new/deleted variables and linear
constraints, matrix coefficient changes, and new/deleted indicator constraints.
Constructor options are used as defaults for every solve; per-call solve()
options override those defaults except for the solver type, which is fixed by
the incremental solver. Solve() is an alias for solve(). close() releases
the native handle and is safe to call more than once.
solve() accepts the same solve options as MathOpt.solve(), including
message callbacks, SolveParameters, ModelSolveParameters, backend-specific
parameters, and pre-interrupted solve interrupters. If a backend rejects an
incremental model update but can solve the current full model, the wrapper
recreates the native solver and solves from that current full model. This keeps
callers on one API for backends with limited update support, while still
surfacing errors from invalid full models. Duplicate names are rejected for
incremental solvers unless removeNames / remove_names is set.
ModelSolveParameters can request a filtered result. This is a result-size
filter, not a separate partial optimization model: the solver still optimizes
the full model, but only selected vectors are returned.
const result = await MathOpt.solve(model, {
solverType: MathOpt.SolverType.GLOP,
modelParameters: MathOpt.ModelSolveParameters.onlySomePrimalVariables([x]),
});For finer control, pass filters directly:
const result = await solver.solve({
modelParameters: new MathOpt.ModelSolveParameters({
variableValuesFilter: { elements: [x, y], filterByIds: true },
dualValuesFilter: { elements: [demand], filterByIds: true },
reducedCostsFilter: { skipZeroValues: true },
}),
});The non-incremental MathOpt.solve() and proto-oriented encodeSolveRequest()
paths remain available alongside MathOpt.IncrementalSolver.
Backend-specific parameter wrappers encode the corresponding upstream MathOpt solver-specific proto fields:
GScipParameters: emphasis, meta parameters, raw SCIP bool/int/long/real/char/string maps, output controls,numSolutions, andobjectiveLimitGlopParameters:useScaling,maxTimeInSeconds,useDualSimplex, andusePreprocessingPdlpParameters: termination criteria, threading/sharding, scheduler, logging, restart, rescaling, linesearch, trust-region, and feasibility-polishing controlsGlpkParameters:computeUnboundRaysIfPossible
cpSat accepts a SatParameters-shaped object for the commonly used MathOpt
CP-SAT backend fields currently encoded by this package (numWorkers,
maxTimeInSeconds, randomSeed, and logging flags), or raw Uint8Array proto
bytes for advanced callers.
parameters / solveParameters, modelParameters, and each backend parameter
option may be raw serialized proto bytes. This preserves a proto escape hatch
for fields that do not yet have ergonomic TypeScript wrappers.
MathOpt.SolveParameters wraps the same solver-independent fields accepted by
MathOptSolveOptions, so callers can either pass flat solve options or an
explicit parameter object.
MathOpt.ModelSolveParameters encodes model-specific solve controls:
variableValuesFilter/variable_values_filterdualValuesFilter/dual_values_filterreducedCostsFilter/reduced_costs_filterquadraticDualValuesFilter/quadratic_dual_values_filterinitialBasis/initial_basisas rawBasisProtobytessolutionHints/solution_hintsbranchingPriorities/branching_prioritieslazyLinearConstraints,lazyLinearConstraintIds, and snake-case aliasesonlySomePrimalVariables(variables)/only_some_primal_variables(variables)as convenience constructors for filtering returned primal variable values
MathOpt.SparseVectorFilter accepts skipZeroValues, filterByIds, and
either numeric ids or model elements with an id. MathOpt.SolutionHint
accepts primal variable values and dual linear constraint values.
GlpkParameters mirrors the upstream MathOpt GLPK-specific solve parameters:
computeUnboundRaysIfPossible?: booleancompute_unbound_rays_if_possible?: boolean
GLPK is single-threaded in this package. MathOpt GLPK solves reject
threads > 1; omit threads or pass threads: 1.
MathOptSolveResult:
terminationReason: stringterminationLimit: string | nullsolveTimeSeconds: number | nullprimalBound: number | nulldualBound: number | nullprimalStatus: string | nulldualStatus: string | nullprimalOrDualInfeasible: booleanobjectiveValue: number | nullvariableValues: Record<string, number>variableValuesById: Record<number, number>solutions: MathOptSolutionResult[]primalRays: MathOptPrimalRayResult[]dualRays: MathOptDualRayResult[]messages: string[]rawResponse: Uint8Arraysolve_time(): number | nullbest_objective_bound(): number | nullhas_primal_feasible_solution(): booleanhas_dual_feasible_solution(): booleanhas_ray(): booleanhas_dual_ray(): booleanhas_basis(): booleanbounded(): booleanobjective_value(): numbervariable_values(): Record<string, number>variable_values(variable): numbervariable_values(variables): number[]reduced_costs(): Record<string, number>reduced_costs(variable): numberreduced_costs(variables): number[]dual_values(): Record<string, number>dual_values(linearConstraint): numberdual_values(linearConstraints): number[]ray_variable_values(): Record<string, number>ray_variable_values(variable): numberray_variable_values(variables): number[]ray_reduced_costs(): Record<string, number>ray_reduced_costs(variable): numberray_reduced_costs(variables): number[]ray_dual_values(): Record<string, number>ray_dual_values(linearConstraint): numberray_dual_values(linearConstraints): number[]variable_status(): Record<string, string>variable_status(variable): stringvariable_status(variables): string[]constraint_status(): Record<string, string>constraint_status(linearConstraint): stringconstraint_status(linearConstraints): string[]
MathOptSolutionResult:
primalSolution: MathOptPrimalSolutionResult | nulldualSolution: MathOptDualSolutionResult | nullbasis: MathOptBasisResult | null
MathOptPrimalSolutionResult:
objectiveValue: number | nullvariableValues: Record<string, number>variableValuesById: Record<number, number>feasibilityStatus: string
MathOptDualSolutionResult:
objectiveValue: number | nulldualValues: Record<string, number>dualValuesById: Record<number, number>reducedCosts: Record<string, number>reducedCostsById: Record<number, number>feasibilityStatus: string
MathOptPrimalRayResult:
variableValues: Record<string, number>variableValuesById: Record<number, number>
MathOptDualRayResult:
dualValues: Record<string, number>dualValuesById: Record<number, number>reducedCosts: Record<string, number>reducedCostsById: Record<number, number>
MathOptBasisResult:
variableStatus: Record<string, string>variableStatusById: Record<number, string>constraintStatus: Record<string, string>constraintStatusById: Record<number, string>basicDualFeasibility: string
Solver type enum:
GSCIPGUROBIGLOPCP_SATPDLPGLPKOSQPECOSSCSHIGHSSANTORINIXPRESS
The default package runtime currently includes GLOP, GLPK, GSCIP,
CP_SAT, and PDLP. Other enum values are exported for API/proto parity but
return an unavailable-solver error unless a custom build links the corresponding
native backend.
Expression helpers:
linearTerm(variable, coefficient?)quadraticTerm(firstVariable, secondVariable, coefficient?)linearExpression(terms?, offset?)quadraticExpression(linearTerms?, quadraticTerms?, offset?)asFlatLinearExpression(input)asFlatQuadraticExpression(input)fastSum(inputs)multiplyLinearExpressions(lhs, rhs)evaluateExpression(expression, variableValues)boundedExpression(lowerBound, expression, upperBound)lowerBoundedExpression(lowerBound, expression)upperBoundedExpression(expression, upperBound)eq(lhs, rhs)ne(lhs, rhs)throws, because!=constraints are unsupported.le(lhs, rhs)ge(lhs, rhs)completeUpperBound(lowerBounded, upperBound)completeLowerBound(lowerBound, upperBounded)variableEq(lhs, rhs)variableNe(lhs, rhs)
These helpers are available as MathOpt.* static methods. Some helper classes
are exposed as MathOpt.LinearExpression, MathOpt.QuadraticExpression, etc.,
rather than as top-level value exports.
Variables:
addVariable(options?): MathOptVariableadd_variable(options?): MathOptVariableaddIntegerVariable(options?): MathOptVariableadd_integer_variable(options?): MathOptVariableaddBinaryVariable(options?): MathOptVariableadd_binary_variable(options?): MathOptVariabledeleteVariable(variable): voiddelete_variable(variable): voidvariablesList(): MathOptVariable[]variables(): MathOptVariable[]getNumVariables()/get_num_variables(): numbergetNextVariableId()/get_next_variable_id(): numberensureNextVariableIdAtLeast(id): voidensure_next_variable_id_at_least(id): voidhasVariable(id)/has_variable(id): booleangetVariable(id, validate?): MathOptVariable | undefinedget_variable(id, { validate }?): MathOptVariable
Linear constraints:
addLinearConstraint(options?): MathOptLinearConstraintadd_linear_constraint(options?): MathOptLinearConstraintdeleteLinearConstraint(constraint): voiddelete_linear_constraint(constraint): voidlinearConstraints()/linear_constraints(): MathOptLinearConstraint[]getNumLinearConstraints()/get_num_linear_constraints(): numbergetNextLinearConstraintId()/get_next_linear_constraint_id(): numberensureNextLinearConstraintIdAtLeast(id): voidensure_next_linear_constraint_id_at_least(id): voidhasLinearConstraint(id)/has_linear_constraint(id): booleangetLinearConstraint(id, validate?): MathOptLinearConstraint | undefinedget_linear_constraint(id, { validate }?): MathOptLinearConstraintcolumnNonzeros(variable)/column_nonzeros(variable): MathOptLinearConstraint[]rowNonzeros(constraint)/row_nonzeros(constraint): MathOptVariable[]linearConstraintMatrixEntries()/linear_constraint_matrix_entries(): MathOptLinearConstraintMatrixEntry[]
Indicator constraints:
addIndicatorConstraint(options?): MathOptIndicatorConstraintadd_indicator_constraint(options?): MathOptIndicatorConstraint
MathOptLinearConstraintMatrixEntry contains:
linearConstraint/linear_constraint: MathOptLinearConstraintvariable: MathOptVariablecoefficient: number
Objective and encoding:
objective: MathOptObjectivemaximize(terms, offset?): voidminimize(terms, offset?): voidmaximizeLinearObjective(terms, offset?): voidmaximize_linear_objective(terms, offset?): voidminimizeLinearObjective(terms, offset?): voidminimize_linear_objective(terms, offset?): voidsetObjective(terms, isMaximize, offset?): voidset_objective(terms, is_maximize, offset?): voidsetLinearObjective(terms, isMaximize, offset?): voidset_linear_objective(terms, is_maximize, offset?): voidsetQuadraticObjective(terms, isMaximize, offset?): voidset_quadratic_objective(terms, is_maximize, offset?): voidvariableName(id): stringlinearConstraintName(id): stringencodeModelProto(): Uint8Array
MathOptVariableOptions:
lb?: numberub?: numberisInteger?: booleanis_integer?: booleanlowerBound?: numberupperBound?: numberinteger?: booleanname?: string
addLinearConstraint() accepts:
lb?: numberub?: numberexpr?: number | MathOptVariable | MathOptLinearTerm | linear expressionlowerBound?: numberupperBound?: numberterms?: MathOptLinearTerm[]expression?: number | MathOptVariable | MathOptLinearTerm | linear expressionname?: string
It also accepts MathOpt.boundedExpression(), MathOpt.lowerBoundedExpression(),
and MathOpt.upperBoundedExpression() results.
addIndicatorConstraint() accepts:
indicator?: MathOptVariableactivateOnZero?: booleanactivate_on_zero?: booleanimpliedConstraint?: MathOpt.boundedExpression()/lowerBoundedExpression()/upperBoundedExpression()implied_constraint?: ...lb/lowerBoundandub/upperBoundexpr/expressionterms?: MathOptLinearTerm[]name?: string
Indicator constraints are encoded into ModelProto.indicator_constraints and
are supported by linked MathOpt backends that accept them, such as GSCIP.
Properties:
id: numbername: stringlowerBound/lower_boundupperBound/upper_boundinteger/is_integer
Methods:
equals(other): booleantoString(): stringassertLive(): void
Properties:
id: numbername: stringlowerBound/lower_boundupperBound/upper_bound
Methods:
setCoefficient(variable, coefficient): voidset_coefficient(variable, coefficient): voidgetCoefficient(variable): numberget_coefficient(variable): numberterms(): MathOptLinearTerm[]asBoundedLinearExpression(): MathOptBoundedExpression<MathOptLinearExpression>as_bounded_linear_expression(): MathOptBoundedExpression<MathOptLinearExpression>equals(other): booleantoString(): stringassertLive(): void
Properties:
isMaximize/is_maximizeoffsetname
isMaximize / is_maximize and offset are writable. name is read-only and
is currently the empty string for the primary objective.
Methods:
clear(): voidsetLinearCoefficient(variable, coefficient): voidset_linear_coefficient(variable, coefficient): voidgetLinearCoefficient(variable): numberget_linear_coefficient(variable): numberlinearTerms()/linear_terms(): MathOptLinearTerm[]setQuadraticCoefficient(firstVariable, secondVariable, coefficient): voidset_quadratic_coefficient(firstVariable, secondVariable, coefficient): voidgetQuadraticCoefficient(firstVariable, secondVariable): numberget_quadratic_coefficient(firstVariable, secondVariable): numberquadraticTerms()/quadratic_terms(): MathOptQuadraticTerm[]
MathOptLinearExpression
- Construct from a number, variable, linear term, iterable of terms, or another expression.
- Properties:
offset,terms. - Methods:
add(input),subtract(input),multiply(coefficient),evaluate(variableValues),toString().
MathOptQuadraticExpression
- Construct from linear inputs plus optional quadratic terms.
- Properties:
offset,linearTerms,quadraticTerms. - Methods:
add(input),subtract(input),multiply(coefficient),evaluate(variableValues),toString().
MathOptQuadraticTermKey
- Construct from two variables in the same model.
- Properties:
firstVariable,secondVariable. - Methods:
equals(other),toString().
MathOptVarEqVar
- Returned by
MathOpt.variableEq(lhs, rhs)when two different live variables belong to the same model. - Properties:
firstVariable/first_variable,secondVariable/second_variable. - Method:
assertNotBoolean(): never.
Bounded expression classes represent constraints produced by eq, le, and
ge:
MathOptBoundedExpressionMathOptLowerBoundedExpressionMathOptUpperBoundedExpression
They expose lowerBound/lower_bound, upperBound/upper_bound, and
toString(). MathOptBoundedExpression also exposes expression and
assertNotBoolean(). MathOptLowerBoundedExpression exposes expression,
toBoundedExpression(upperBound), and assertNotBoolean().
MathOptUpperBoundedExpression exposes expression,
toBoundedExpression(lowerBound), and assertNotBoolean().
Import:
import { initPdlp, Pdlp, QuadraticProgram } from 'or-tools-wasm/pdlp';PDLP exposes the primal-dual hybrid gradient solver for LP and convex diagonal quadratic programs.
const qp = new QuadraticProgram({
objectiveVector: [1, 2],
variableLowerBounds: [0, 0],
variableUpperBounds: [10, 10],
});
const result = await Pdlp.primalDualHybridGradient(qp, {
terminationCriteria: { iterationLimit: 1000 },
});initPdlp(): Promise<void>
Loads the PDLP WebAssembly runtime for direct solves. The Pdlp async helpers
will initialize the runtime automatically if needed, but initPdlp() is
available for explicit direct-runtime warmup. When the browser worker bridge is
enabled, initPdlp() is a no-op and PDLP helper calls run through the worker
bridge.
Constructor:
new QuadraticProgram(input?: QuadraticProgramInput)Fields are available in both camelCase and snake_case:
problemName/problem_nameobjectiveOffset/objective_offsetobjectiveScalingFactor/objective_scaling_factorobjectiveVector/objective_vectorobjectiveMatrixDiagonal/objective_matrix_diagonalconstraintMatrix/constraint_matrixconstraintLowerBounds/constraint_lower_boundsconstraintUpperBounds/constraint_upper_boundsvariableLowerBounds/variable_lower_boundsvariableUpperBounds/variable_upper_boundsvariableNames/variable_namesconstraintNames/constraint_names
Methods:
resizeAndInitialize(numVariables, numConstraints): voidresize_and_initialize(numVariables, numConstraints): voidsetObjectiveMatrixDiagonal(values): voidset_objective_matrix_diagonal(values): voidclearObjectiveMatrix(): voidclear_objective_matrix(): voidtoBytes(): Uint8Array
Sparse matrix input accepts either:
{ numRows?: number; numColumns?: number; entries?: Array<{ row: number; column: number; value: number }> }or a dense number[][].
Constructor:
new PrimalAndDualSolution({ primalSolution?: number[]; dualSolution?: number[] })Fields are also exposed as primal_solution and dual_solution.
Pdlp.QuadraticProgramPdlp.PrimalAndDualSolutionvalidateQuadraticProgramDimensions(qp): Promise<void>validate_quadratic_program_dimensions(qp): Promise<void>isLinearProgram(qp): Promise<boolean>is_linear_program(qp): Promise<boolean>qpFromMpModelProto(proto, options?): Promise<QuadraticProgram>qp_from_mpmodel_proto(proto, relaxIntegerVariables?, includeNames?): Promise<QuadraticProgram>qpToMpModelProto(qp): Promise<Uint8Array>qp_to_mpmodel_proto(qp): Promise<Uint8Array>primalDualHybridGradient(qp, params?, initialSolution?): Promise<PdlpSolverResult>primal_dual_hybrid_gradient(qp, params?, initialSolution?): Promise<PdlpSolverResult>
PdlpSolveParams supports camelCase and snake_case forms:
terminationCriteria.iterationLimitterminationCriteria.simpleOptimalityCriteria.epsOptimalRelativeterminationCriteria.simpleOptimalityCriteria.epsOptimalAbsoluteterminationCheckFrequencylInfRuizIterationsl2NormRescaling
PdlpSolverResult contains:
primalSolution/primal_solutiondualSolution/dual_solutionreducedCosts/reduced_costssolveLog/solve_log
solveLog contains terminationReason / termination_reason and
iterationCount / iteration_count.
The CP-SAT, MathOpt, Routing, MPSolver, Knapsack, Network Flow, Set Cover, RCPSP, and PDLP paths can use the shared worker bridge. Worker bridge availability is independent of solver threading support; for example GLPK, BOP, Knapsack, Set Cover, and Network Flow are single-threaded but can still run through the worker bridge for UI responsiveness, while RCPSP uses CP-SAT and can also accept CP-SAT thread settings. CP-SAT, SAT, SCIP/GSCIP, CBC, and other threaded-capable paths can also accept solver thread settings. Prefer the shared package controls:
import { isWorkerBridgeEnabled, setWorkerBridgeEnabled } from 'or-tools-wasm/cp-sat';
setWorkerBridgeEnabled(true);
isWorkerBridgeEnabled();Solver-specific aliases are also exposed for existing call sites:
CpSat.setWorkerBridgeEnabled(true);
MathOpt.setWorkerBridgeEnabled(true);
MathOpt.isWorkerBridgeEnabled();
MPSolver.setWorkerBridgeEnabled(true);
Pdlp.setWorkerBridgeEnabled(true);
RoutingModel.setWorkerBridgeEnabled(true);The worker bridge defaults on in browser main-thread builds and defaults off in non-browser runtimes. Non-browser callers normally use direct runtime paths unless they explicitly enable the bridge.
The package exports generated CP-SAT model and response types from
generated/cp_model, plus SatParameters from generated/sat_parameters.
These are large generated definitions matching OR-Tools protobuf schemas. Use
them to type JSON-like model and parameter objects passed to CpSat.createModel
and CpSat.solve.
For raw protobuf workflows, use the schema helpers:
CpSat.getSchemas()MPSolver.getLinearSolverSchemas()
Objects backed by native WebAssembly handles expose delete() when explicit
cleanup is supported:
RoutingIndexManager.delete()RoutingModel.delete()MPSolver.delete()MPSolverParameters.delete()
For long-running applications that create many native objects, call delete()
when a model is no longer needed.