sdfx: a CAD package where the model is Go code
A simple CAD package using signed distance functions
At a glance
- What is it?
- sdfx models objects as signed distance functions written in Go and renders them to STL, 3MF, DXF and SVG, which makes constructive solid geometry and fillets far easier than a mesh-based modeller. The trade is that you are writing a program to make a shape, and the repository is currently between tagged releases.
- Who is it for?
- sdfx fits a maker who wants parametric, code-driven geometry, who already thinks in Go, and who wants fillets, chamfers and boolean operations without fighting a mesh modeller. It is the wrong tool for someone who wants to sketch a part by dragging handles in a GUI, and the wrong tool for a team that needs a vendor with a support contract.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 55 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The object is a function, not a mesh
The README describes sdfx as a simple CAD package written in Go, and it states the three properties that define it: objects are modelled with 2d and 3d signed distance functions, objects are defined with Go code, and objects are rendered to an STL or 3MF file to be viewed and/or 3d printed.
The first of those is the whole design. A signed distance function assigns a number to every point in space, the distance to the surface, negative inside and positive outside. A sphere is a formula, a box is a formula, and the space between them is another formula. Because the model is a function rather than a collection of triangles, the two operations that are painful in mesh modelling become arithmetic.
The second property is what makes it a Go package rather than a CAD application. There is no document to open and no history tree. You write a program that builds the shape, you run it, and the program writes a file. The repository layout reflects that division, with an `sdf` directory for the modelling core, a `render` directory for the output backends, an `obj` directory for the object definitions, a `mk` directory for making, and a `vec` directory for vector maths.
The audience is therefore a programmer, and the output is a file for a 3d printer or a viewer, not an editable CAD document.
Write, build, preview, print
The How To section is five steps, and reading them tells you what a session with sdfx looks like.
See the examples, write some Go code to define your own object, build and run the Go code, preview the output in a 3d file viewer such as the one at meshlab.net, and print the STL or 3MF file if you like it enough.
The loop that is worth optimising is steps three and four, because that is compile, run, open a file, look, adjust, repeat. The README points at two projects built to compress that loop: SDF Viewer Go and SDFX-UI, both by Yeicor, and it says they allow faster development iterations, replacing steps 3 and 4 until the final build.
So there are two working modes. The slow one is the documented path, write and build and inspect the exported file. The fast one is to point the editor at the live shape while you edit, and only fall back to the build-and-export cycle when you are ready to print. For a package whose whole pitch is that shapes are cheap to iterate, that difference in cycle time is the practical difference between the library being pleasant and the library being tedious.
Why distance functions, according to the author
The Why section gives four reasons, and they are worth quoting rather than paraphrasing because the third one is the most concrete.
The first is that SDFs make CSG easy. Constructive solid geometry, combining shapes by union, intersection and subtraction, is a matter of combining functions, and the README is blunt about the comparison: as a language Golang > OpenSCAD.
The third reason is the one that explains why the library exists at all. SDFs can easily do filleting and chamfering, and the README notes that this is hard to do with OpenSCAD. Rounding the edge where a cylinder meets a plate is trivial when the shape is a function of position, and painful when it is a set of triangles, because the fillet has to be built out of geometry.
The last reason is that SDFs are hackable to try out oddball ideas. That is a smaller claim than the others but it is the one that matters for a hobby project, and the gallery backs it up, with entries for a gyroid surface, a TrueType font rendering, an involute gear, a Geneva mechanism, an M-Square casting pattern and a Reddit CAD Challenge part.
The comparison with OpenSCAD is the reference point throughout. OpenSCAD is a declarative language for CSG, and sdfx is a general purpose language with a distance function library, so the trade is between a constrained modelling language and a programming language with more ceremony but more reach.
The dependency list is a list of output formats
The module file is a good map of what the package can produce, because each output format is a separate library.
The module is `github.com/deadsy/sdfx` and it requires Go 1.25.0. The direct dependencies cover the formats and the maths: `github.com/hpinc/go3mf` at 0.24.2 for 3MF output, `github.com/yofu/dxf` for DXF, `github.com/ajstarks/svgo` together with `github.com/golang/freetype` for SVG, `github.com/dhconnelly/rtreego` for 2D tree structures, `github.com/llgcode/draw2d` for 2D drawing, `gonum.org/v1/gonum` for numerics, and `golang.org/x/image` for image handling. `github.com/stretchr/testify` at 1.7.0 is the test library.
Two things follow. First, the mesh output that most people want, STL, is not in this list at all, which suggests it is written directly rather than delegated, while the less common formats are delegated to existing libraries. Second, the 2D side is a first-class citizen rather than an afterthought, since the topics list includes dxf and svg alongside stl and 3mf and there is a dedicated example for a 2D points distance field.
One more detail in the module file: there is a `github.com/qmuntal/opc` indirect dependency, which the go3mf library pulls in for the 3MF packaging format.
The examples directory is also the test matrix
There are dozens of example directories, and each one is a small Go program that builds a real object. The listing in the repository includes 3dp_nutbolt, angle, arrow, axochord, axoloti, beehive, benchmark, bezier, birdhouse, bjj, bolt_container, bucky, camshaft, cap, carburetor, challenge, cylinder_head, dc2test, delta, devo, draincover, drone, dust_collection, eurorack and extrusion, among others.
The Makefile treats them as a suite. The directory list is built by a wildcard:
DIRS = $(wildcard ./examples/*/.)and the test target runs the core package tests and then recurses into every example:
test:
cd sdf; go test; cd ..
for dir in $(DIRS); do \
$(MAKE) -C $$dir $@ || exit 1; \
doneThe `|| exit 1` is what makes it a real gate rather than a best effort, since one failing example stops the run. The `all clean hash` targets use the same loop, so a build failure in one example also stops the batch.
This is the part of the project that makes the format support believable. A library that claims to write STL, 3MF, DXF and SVG has a demonstration of each in the repository, and every one of them is compiled and tested on every run.
A cross-branch STL diff guards the renderer
The most interesting target in the Makefile is `stldiff`, and the comment above it explains why it exists. It is a cross-branch STL regression check: it renders every example at `master` and at HEAD, then compares the STL outputs, and it is to be used before landing a change that touches core rendering or SDF code, to confirm that no unrelated example's geometry was disturbed.
The target itself is small:
BASE ?= master
HEAD ?= HEAD
stldiff:
./tools/stldiff/run.sh $(BASE) $(HEAD)The two refs are overridable, and the comment gives the example of comparing a tagged release with a feature branch.
This matters more than it might look. A signed distance function library has a failure mode that unit tests cannot catch: a change to the maths that is numerically correct but shifts a surface by a fraction of a millimetre, which leaves every example building and every test passing while quietly changing every printed part. Comparing rendered geometry across two revisions catches that, and a library that prints physical objects needs that check. The tooling lives in a `tools/stldiff` directory, and the same `stldiff` name is used for the check, the script directory and the output comparison.
For a contributor, the practical rule is that a change to the `sdf` package should come with a `make stldiff` run before the pull request.
MIT licensed, with a gallery and a roadmap
The licence is MIT, with the LICENSE file at the root of the repository.
The repository is not archived and the last push was on 2026-08-29, and there are no GitHub releases, so there is no version to pin and the state of the project is the state of the master branch. For a package whose consumers are hobbyists and makers who vendor it into their own Go programs, that is a workable arrangement, and the module path in the go.mod is the way to depend on it.
The development section points at a roadmap document in the repository, docs/ROADMAP.md, and the repository root also holds a CLAUDE.md, a `.wip` directory, and the standard set of directories for the library, the renderers, the object definitions and the tools.
The gallery is the best argument for the approach, because the listed results are not simple primitives. There is a pottery wheel casting pattern, a cylinder head, an M-Square casting pattern, an Axoloti mount kit, TrueType font rendering, a gyroid surface, an icosahedron, an involute gear, a Wallaby camshaft, a Geneva mechanism, nuts and bolts, twisted and scaled extrusions, a bowl made with Bezier curves, extruded Bezier curves and a 2D points distance field. Several of those are objects that a mesh modeller makes painful, and the README's own argument is that SDFs make filleting and chamfering easy where OpenSCAD struggles. Judging by the gallery, that argument holds.
Editorial conclusion
sdfx fits a maker who wants parametric, code-driven geometry, who already thinks in Go, and who wants fillets, chamfers and boolean operations without fighting a mesh modeller. It is the wrong tool for someone who wants to sketch a part by dragging handles in a GUI, and the wrong tool for a team that needs a vendor with a support contract. Verify first which output format your slicer or CAM tool expects, since the renderers are separate libraries per format, and read the roadmap in docs/ROADMAP.md before planning around a feature you are hoping exists.
Frequently asked questions
What is sdfx and how are objects defined in it?
sdfx is a simple CAD package written in Go. Objects are modelled with 2d and 3d signed distance functions and defined with Go code, then rendered to an STL or 3MF file to be viewed or 3d printed.
Why use signed distance functions instead of a mesh modeller?
The README gives the reasons as SDFs making CSG easy, the preference for Golang over OpenSCAD, SDFs handling filleting and chamfering easily where OpenSCAD finds it hard, and SDFs being hackable for trying out unusual ideas.
Which file formats can sdfx export?
The module file shows the formats through its dependencies: go3mf for 3MF, the yofu dxf library for DXF, svgo together with freetype for SVG, and STL output written by the package itself. The examples gallery also shows 2D output.
How do I test changes to sdfx without breaking existing models?
The Makefile has a stldiff target that renders every example at master and at HEAD and compares the STL outputs, and the comment says to use it before landing a change that touches core rendering or SDF code. The refs are overridable with BASE and HEAD.
Is there a faster way to iterate on a shape than building and exporting?
The README points to SDF Viewer Go and SDFX-UI, which allow faster development iterations by replacing the build and preview steps until the final build.
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/deadsy-sdfx)Was this useful?