# BoxPacker: 3D bin packing with weight as a fourth dimension

> BoxPacker is a PHP library that solves the 3D bin packing problem with weight as an extra constraint, so given items and a catalogue of boxes it works out how many cartons you need and what goes in each. It also fills a single container as densely as possible, and ships a 3D visualiser.

**dvdoug/BoxPacker** — 4D bin packing / knapsack problem solver

- Repository: https://github.com/dvdoug/BoxPacker
- Stars: 661 · Forks: 167
- Language: PHP
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/dvdoug-boxpacker

## The problem the library actually solves

BoxPacker is described as an implementation of the 3D bin packing problem with weight as a fourth constraint. The question it answers is a concrete operational one: given items and a catalogue of boxes, how many cartons do you need, and what goes in each? That is a shipping desk question rather than a research question, and the framing explains why the library exists at all. The same engine can also fill a single container, described as a pallet, a trailer or an ocean box, as densely as possible and leave the rest unpacked, which is the load planning version of the same computation. The typical uses are listed as three: e-commerce cartonization and shipping cost calculation, warehouse box selection, and one container load planning. The weight constraint is what separates this from a plain geometry packer, and it is the constraint that makes a result usable, since a van that fits the boxes but exceeds the weight limit is not a solution.

## Your own objects, with no wrapper layer

One of the listed features is that you use your own Item and Box objects, with no wrapper DTOs. For a PHP library in this space, that is a design decision worth a paragraph, because the alternative is that the solver defines its own item class and you translate everything into it, then translate the result back. That translation layer is where the bugs live, since the dimensions, the weight and the constraints usually do not map one to one, and a solver that insists on its own shape forces a conversion you cannot validate. Working with your own objects also means the input and the output stay in the vocabulary of your domain, and for an e-commerce catalogue where an item already has a length, a width, a height and a weight, that is a real reduction in friction. The trade-off is that the library's own types are not part of the public surface, so the flexibility is bought at the cost of a less conventional API.

## Rotation, weight balancing and the other constraints

The constraint list in the README is what tells you whether the solver matches your problem. Rotation is supported in three modes: any way up, keep-flat, or none, which is the first question to ask about any packing problem, since a fragile item or one with a printed label cannot simply be turned. Weight limits are enforced, and there is automatic weight balancing across cartons, which is the feature that distinguishes a packer that treats weight as a separate pass from one that treats it as a fourth dimension. Then there is limited box stock, so the catalogue is not infinite, which matters when a warehouse has forty of one box size and none of another. Linked items are supported, so two products that must travel together can be constrained. And custom placement rules are supported, which is the extension point for whatever constraint your business has that nobody else has thought of. Read that list against your own requirements before anything else, because a packer that is missing one of these is not usable for you regardless of how well it solves the rest.

## Coordinates and the visualiser

The output includes packed x, y and z coordinates for every item, along with a 3D visualiser. Those two things belong together, and the reason is worth stating. A packing that is only a list of which items go in which carton tells you the number of cartons, which is the shipping cost question, but it does not tell you whether the packing is physically loadable, whether the heavy items ended up at the bottom, or whether an item is buried in the middle of a carton where you cannot get at it. The coordinates let you check all of that yourself, and the visualiser exists to make that check quick, since reading coordinates in the abstract is how packing bugs stay hidden. The top level of the repository has a `visualiser/` directory for this, alongside `src/` for the library itself, `tests/` for unit tests, and a `features/` directory with a `behat.dist.php` configuration, so the behaviour is covered by both unit tests and acceptance tests written in a readable feature style.

## Installation and the PHP floor

The library is installed with Composer, and the README states the requirement plainly, requiring PHP 8.2 or newer:

```bash
Requires PHP 8.2+. `composer require dvdoug/boxpacker`
```

That is the whole installation story, and the fact that the library is on Packagist with a download count and a current version badge suggests it is used in the wild rather than being a weekend experiment. The documentation lives at boxpacker.io with a stable version on Read the Docs, and the repository carries a `.readthedocs.yaml` file to build it. The PHP 8.2 floor is the modern part of the picture, and it is worth noting that a floor that high buys you enums, readonly properties and better type inference, which in a library full of value objects and small classes is more than a cosmetic gain.

## The release line and the project infrastructure

The version history shows a project on a regular cadence with a clear major version structure. Version 4.1.1 was released on 2025-07-21, 4.2.0 on 2026-07-05 and 4.3.0 on 2026-08-09, and the last push was on 2026-10-17. The repository carries the standard set of quality tooling for a PHP project of this kind, with a `.php-cs-fixer.dist.php` configuration for code style, a `phpunit.xml.dist` for the test runner, a `behat.dist.php` for the acceptance tests, a `composer.json`, a `CHANGELOG.md`, and a `docs/` directory alongside the `src/`, `tests/` and `visualiser/` directories. The build is reported through a GitHub Actions CI badge and a Scrutinizer code quality badge, and the licence is MIT with a `license.txt` file in the repository, which for a library you are likely to embed in a commercial application is the practical permission you want. The topics on the repository name the problem rather than the domain, with bin packing, boxpacker, the knapsack problem and PHP.

## Where this is the wrong choice

The limits are worth naming, and most of them are about scope rather than quality. First, this is a geometry solver, not a logistics planner. It answers which box and where, and it does not answer which vehicle, in what order, or by what route, so a delivery planning problem is out of scope. Second, the search is a heuristic, so the answer is a good packing rather than a proven optimal one, and for a problem where optimality matters, such as cutting stock in a manufacturing context, a different class of solver is the right tool. Third, the input has to be clean. Dimensions and weights come from your catalogue, and a catalogue with a missing weight or a dimension recorded in the wrong unit produces a packing that is confidently wrong, so the data quality burden sits with you and the library will not tell you that a value is suspect. Fourth, the coupling is to boxes rather than to containers of arbitrary shape, so if your shipping unit has an irregular footprint, a pallet with a fixed deck size, or a vehicle with awkward internal geometry, the model does not describe it. Fifth, and this is a PHP library in a world where much of the logistics tooling is written in Python, so if your surrounding stack is Python, adopting it means a service boundary or a rewrite.

## Conclusion

BoxPacker fits a PHP shop that needs to decide which carton each order goes in, how many cartons a batch needs, or how to load a pallet or trailer, since it takes your own item and box objects and returns a packing rather than a data structure you have to model yourself. It is the wrong choice for a scheduling problem with time windows, a route planning problem or anything where the geometry is not the constraint, and the wrong choice if you need a solver that is guaranteed optimal rather than good. Before you adopt it, check your PHP version, since 8.2 or newer is required, and decide how you will use the 3D visualiser, since the packing coordinates are the interesting output and a diagram is what makes them usable. The last push was on 2026-10-17 with version 4.3.0 released on 2026-08-09, under the MIT licence.

## FAQ

### What problem does BoxPacker solve?

It implements the 3D bin packing problem with weight as a fourth constraint, taking items and a catalogue of boxes and working out how many cartons are needed and what goes in each. The same engine can fill a single container such as a pallet, trailer or ocean box as densely as possible and leave the rest unpacked.

### How do I install BoxPacker?

The README states the requirement of PHP 8.2 or newer and the Composer command `composer require dvdoug/boxpacker`. The package is on Packagist and the documentation is at boxpacker.io.

### Does BoxPacker support rotating items and weight limits?

Yes. Rotation is supported in three modes, any way up, keep-flat, or none. Weight limits are enforced, and the README lists automatic weight balancing across cartons, limited box stock, linked items, custom placement rules, and packed x, y and z coordinates with a 3D visualiser.

## Sources

- [dvdoug/BoxPacker on GitHub](https://github.com/dvdoug/BoxPacker)
- [Issues](https://github.com/dvdoug/BoxPacker/issues)
- [License: MIT](https://github.com/dvdoug/BoxPacker/blob/master/LICENSE)
- [README](https://github.com/dvdoug/BoxPacker/blob/master/README.md)
- [Releases](https://github.com/dvdoug/BoxPacker/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/dvdoug-boxpacker
