OpenCAMLib turns 3D models into CNC toolpaths with two cutter algorithms
open source computer aided manufacturing algorithms library
At a glance
- What is it?
- OpenCAMLib is a C++ library for generating 3D toolpaths for mills and lathes, with bindings for Python, Node.js and the browser through emscripten. It ships a drop-cutter and a push-cutter algorithm, five cutter types, and pre-built binaries for six platforms, but its Python package metadata and its release tags disagree about which version is current.
- Who is it for?
- Adopt OpenCAMLib if you are writing CAM software and need correct 3D toolpath geometry for mills and lathes, especially for the browser or Python, where the drop-cutter algorithm is the reason it exists. Do not adopt it expecting a complete CAM package, since it computes toolpaths and does not simulate the machine or drive it, and note that the Node.js build is described as not 100 percent feature complete.
- Can I use it commercially?
- Yes, with conditions. LGPL-2.1 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 6 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A geometry library, not a CAM program
OpenCAMLib, abbreviated ocl, is a library for creating 3D toolpaths for CNC machines such as mills and lathes. It is written in C++ and has bindings for Python, Node.js and the browser.
That boundary is worth stating at the start, because the name invites a wrong assumption. OpenCAMLib computes where the cutter goes. It does not read a drawing, it does not simulate the machine, it does not generate G-code, and it does not know what stock you are cutting. If you want a program that takes a STEP file and produces G-code for a specific controller, this is a component you would build on rather than the application you would run.
The description in the repository metadata calls it an open source computer aided manufacturing algorithms library, and that word algorithms is the accurate one. The homepage is the author's own site, anderswallin.net/CAM, and the package metadata lists Anders Wallin as the author and Koen Schmeets as a maintainer, with the Project URL pointing at the GitHub repository.
The use case that justifies the library is geometry. A three axis mill moving a ball end mill through a freeform surface has to solve, at every step, where the spherical tool touches the model. That is a root finding problem on a moving surface, and getting it wrong means gouging the part or rubbing the tool. A library that implements it once, correctly and with tests, saves every CAM project from implementing it again, and that is the whole argument for the project.
The classifer in the package metadata says Development Status :: 4 - Beta, and the Intended Audience classifier says Manufacturing. It is a beta library for people who build CAM software, not a tool for people who use it.
Drop-cutter and push-cutter are two different physical models
The README names the supported algorithms, and there are two of them, and the difference between them is the physical model of the cut rather than an implementation detail.
The drop cutter algorithm drops a cutter, positioned at a predefined (x,y) location, until it touches the 3D model. The cutter is treated as a vertical cylinder of some radius falling onto the surface. This is the right model for a flat end mill, and for any case where the tool axis is parallel to the model normal and the engagement is dominated by the side of the tool.
The push-cutter is used to create a waterline toolpath that follows the shape of the model at a constant z-height in the xy-plane. The tool is not dropped, it is pushed sideways along the contour at a fixed height, and the contact is computed between the tool's spherical profile and the model's section at that height. That is the right model for a ball end mill finishing a surface at a constant depth, which is what a waterline or contour pass is.
So the choice is not a preference between two implementations of the same thing. It is a choice of which contact geometry describes your cut, and picking the wrong one produces a toolpath that misses the surface in some places or cuts into it in others.
Both algorithms accept the same set of cutter types, and the README lists them: CylCutter for a flat end mill, BallCutter for a ball end mill, BullCutter for a radius end mill, ConeCutter for a tapered end mill, and CompositeCutter for combinations of the above, that is compound tools.
The CompositeCutter is worth a note. A tool with a flat body and a ball tip is a real thing in finishing work, and modelling it as one object with a piecewise profile is different from approximating it with either a cylinder or a sphere. The presence of a composite type in the list tells you the library was written by someone who has watched real cutters rather than by someone modelling them abstractly.
Pre-built binaries across six platforms, and the version confusion around them
OpenCAMLib provides pre-compiled C++, Node.js and Python libraries for Windows, macOS and Linux, with ia32 and x64 on Windows, x86_64 and arm64 on macOS, and x86_64 and aarch64 on Linux.
The three distributions have different names and different homes. The Python library is called opencamlib and is hosted on PyPI, with precompiled libraries available for Python v3.9 up to v3.14. The Node.js plus emscripten library is called @opencamlib/opencamlib and is hosted on npm, with precompiled libraries available for Node-API v3 and up. The C++ library is called libocl and is hosted on the GitHub releases page.
The Python install is one command:
pip install opencamlibOn some platforms pip is called pip3, and the README notes you might have to run pip3 install opencamlib instead. It also warns that pip and pip3 install into the system installation of Python, and if you want a package in a custom Python installation that is not in your $PATH, for example the Python which comes with Blender, you install it with /path/to/your/custom/python -m pip install opencamlib.
That last case has a dedicated recipe, and it is a good one to know about because FreeCAD and Blender both have a Python console. If you do not know where Python is but you have access to its interpreter, you can run the install from inside the console:
import sys; import subprocess; subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'opencamlib'])The JavaScript library goes the other way. It works in Node.js and in the browser by leveraging emscripten and WASM, and installs with npm install --save @opencamlib/opencamlib, or yarn add @opencamlib/opencamlib.
There is one caveat the README attaches to the JavaScript library specifically: it is not 100 percent feature complete and lacking some functionality still. That sentence is attached to the npm install paragraph, so it is the browser and Node build that carries the caveat, not the C++ library.
The version reporting is messier than the install story. The pyproject records version = "2022.12.18" while the repository listing shows a newer release, 2023.01.11, dated 2023-01-11, alongside 2022.12.18 and 2022.12.17. So the Python package on PyPI may not correspond to the newest C++ release, and anyone linking both should check rather than assume.
Building from source needs Boost headers, CMake and a C++ compiler
The README is direct about when to build rather than download: if there are no pre-compiled libraries for your platform or architecture, or you want to customize or package opencamlib, that is the path. If you are having trouble with a pre-compiled library, the README asks you to report it.
The dependency list is short because only Boost headers are used, and Boost itself does not need to be compiled. You need a C++ compiler that supports at least C++ 14, Git, CMake at least version 3.18, and the Boost headers. Building the Python bindings additionally requires Python development headers, and pybind11 is installed automatically when building the package with pip.
The C++ build is the simplest of the three, and the sequence is the standard CMake out of source pattern:
git clone https://github.com/aewallin/opencamlib
cd opencamlib
mkdir build
cd build
cmake .. -D BUILD_CXX_LIB="ON"
cmake --build . # try make --parallel for a faster build if you have a multi-core machine
cmake --install .The cmake --build line carries a practical note in a trailing comment: try make --parallel for a faster build if you have a multi-core machine. And when Boost is not in a standard location, you can add the -D BOOST_ROOT=/path/to/boost option to the cmake command.
There is a helper script for the whole thing. The README points to install.sh as a script that helps with installation of dependencies and building the OpenCAMLib libraries, and suggests taking a look at it first. You can run ./install.sh --help to look at the available options, or inspect its source code to find out more.
The dependency installation commands per platform are also given. On Ubuntu:
sudo apt install -y git cmake curl build-essential libboost-dev python3-dev python3-pipAnd on macOS:
brew install git cmake curl boost pythonFor Windows, the README lists Visual Studio Build Tools, Git and CMake, installable by downloading the installers or by using a package manager.
For the browser build, the emscripten SDK is cloned and activated with ./emsdk install latest followed by ./emsdk activate latest, and the repository ships examples/ subdirectories for cpp, emscripten, nodejs and python, which is the fastest way to see what a working integration looks like in each binding.
CMake integration and the LGPL terms
For a C++ project, the integration story is a find_package. The project installs an OpenCAMLibConfig.cmake which, if your project uses CMake, allows you to use find_package(OpenCAMLib REQUIRED). There is a working example of that in the repository at examples/cpp/test/CMakeLists.txt.
That is the standard and correct way to consume a C++ library with CMake, and the fact that the project ships the config file rather than making users write find_library calls is a sign of care.
The licence is LGPL version 2.1, which the README dates: from August 2018 OpenCAMLib is released under LGPL license. The README badge points at the GNU LGPL 2.1 page, and the COPYING file at the repository root is the licence text, with the pyproject referring to it as license = { file = "COPYING" }.
LGPL 2.1 is a weak copyleft licence, and the practical question for a CAM vendor is what it obliges you to do. In outline, if you distribute a binary that incorporates the library, you must provide the library source and allow recipients to relink against a modified version of it, and you must keep the notices intact. Using the library in your own application is generally fine without turning your application into a derivative work, and dynamically linking is the straightforward case. The package metadata also declares the License :: OSI Approved :: MIT License classifier, which does not match the LGPL text in the COPYING file, so the classifier is wrong and the COPYING file is what governs. That mismatch is a small defect worth knowing about before you answer a compliance questionnaire.
These are the terms as the licence states them and they are a licensing note rather than legal advice.
The build system for the Python package is scikit-build-core, with pybind11 as the other build requirement, and the wheel packages the src/pythonlib/opencamlib directory. The cibuildwheel configuration builds for cp38 through cp314 and skips musllinux and 32-bit manylinux, which matches the stated range of pre-built Python libraries from 3.9 upward.
Where OpenCAMLib is the wrong tool
The first limit is scope. It computes toolpaths and stops there. If you need a full CAM workflow, with file import, tool library management, workholding, fixturing, G-code output and machine simulation, you need one of the established CAM packages and OpenCAMLib becomes a component inside it, if it is used at all.
The second limit is the algorithm count. Two algorithms and five cutter types is a focused library, not a comprehensive one. There is no roughing strategy library, no 2D pocket or contour routines, no drilling, no toolpath filtering, no arc fitting, no collision checking and no gouge avoidance. The drop cutter and push cutter are what you get.
The third is the release cadence and the version mismatch. The newest tag in the repository listing is 2023.01.11 from January 2023, the pyproject version field says 2022.12.18, and the last push was on 2026-10-17 with the repository not archived. So code is being changed on master while the released versions are years old, and a project that consumes the library has to decide whether to track master or to pin a release and live with it. A library whose stable releases stopped in 2023 but whose master branch is still being touched is a decision point, not a settled dependency.
The fourth is the browser build, which the README says is not 100 percent feature complete. Since the Python and Node packages wrap the same C++ core, an incomplete emscripten build also means the WASM path is not a drop-in substitute for the native one.
The alternative to weigh is a CAM kernel rather than a toolpath library. OpenCAMLib is a set of algorithms with bindings, deliberately small and legible, and you can read the C++ source to know exactly what the toolpath means. A full CAM kernel gives you a complete pipeline with a post processor and a machine simulator, at the cost of a much larger dependency and a licensing conversation. The difference in approach is that OpenCAMLib is the geometry you would otherwise have to write, and the established packages are the application around it. If you are building a CAM product, you want the former and probably a bit of the latter; if you are machining a part this month, you want the latter and none of this.
Editorial conclusion
Adopt OpenCAMLib if you are writing CAM software and need correct 3D toolpath geometry for mills and lathes, especially for the browser or Python, where the drop-cutter algorithm is the reason it exists. Do not adopt it expecting a complete CAM package, since it computes toolpaths and does not simulate the machine or drive it, and note that the Node.js build is described as not 100 percent feature complete. Verify first which pre-built binary matches your platform and Python version, that the version in the Python package matches the C++ library you link against, and that the LGPL obligations suit how you intend to distribute it.
Frequently asked questions
How do I install the OpenCAMLib Python package?
Run pip install opencamlib, or pip3 install opencamlib on platforms where pip is called that. For a custom Python installation not on your $PATH, use /path/to/your/custom/python -m pip install opencamlib, and from inside a FreeCAD or Blender Python console you can run the same install through subprocess.
Which toolpath algorithms does OpenCAMLib implement?
Two. The drop cutter drops a cutter positioned at a predefined x,y location until it touches the 3D model, and the push cutter creates a waterline toolpath that follows the model at a constant z-height in the xy-plane. Both accept the cutter types CylCutter, BallCutter, BullCutter, ConeCutter and CompositeCutter.
How do I use OpenCAMLib from a CMake C++ project?
The project installs an OpenCAMLibConfig.cmake, so your CMakeLists.txt can use find_package(OpenCAMLib REQUIRED). The pre-compiled C++ library is called libocl and is hosted on the GitHub releases page, and a working example sits at examples/cpp/test/CMakeLists.txt.
What do I need to build OpenCAMLib from source?
A C++ compiler supporting at least C++ 14, Git, CMake version 3.18 or later, and the Boost headers, which are used header-only and do not need compiling. The Python bindings also need Python development headers, and pybind11 is installed automatically when building with pip. An install.sh script handles dependencies and the build, and ./install.sh --help lists its options.
What licence is OpenCAMLib released under and what are the limitations of the JavaScript build?
The library is licensed under LGPL version 2.1, with the terms in the COPYING file at the repository root, though the package metadata carries a mismatched MIT classifier. The README states that the Node.js and browser library, installed as @opencamlib/opencamlib from npm, is not 100 percent feature complete and is still lacking some functionality.
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/aewallin-opencamlib)Was this useful?