Open-source project
JCash/voronoi avatar
JCash/voronoi

jc_voronoi builds 2D Voronoi diagrams in C from a single header

A C implementation for creating 2D Voronoi/Delauney diagrams

735 stars98 forksCMIT

At a glance

What is it?
JCash/voronoi is a header-only C implementation of Fortune's sweep algorithm that produces clipped edges and cells with ordered edge lists, and it ships through Homebrew, npm as a WebAssembly package, or as one file you paste into your project. The author built it after an earlier generator was slow and sometimes wrong, and the comparison table in the README says exactly which properties it was aiming for.
Who is it for?
Adopt jc_voronoi if you need 2D Voronoi or Delaunay output inside a C or C++ program and want clipped edges, cells with ordered edge lists, a custom allocator and a single file you can vendor, since the library is header-only and has no external dependencies.
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 90 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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Fortune's sweep algorithm in one vendored file

jc_voronoi is described as a fast, header-only C implementation for creating 2D Voronoi diagrams from a point set, and the algorithm is named: it uses Fortune's sweep algorithm. The header-only design is the defining constraint, and it is also the source of the library's appeal. There is no library file to build and no external dependency to resolve, and the README lists small code with a single source file, no external dependencies, readable code, and both a single and a double floating point implementation among its goals. The author explains the motivation directly: the previous 2D Voronoi generator in use was taking too much time in their application and sometimes produced errors, so the project set out to combine the good properties of the alternatives rather than copy one of them. It is a personal tool turned into a library, and the README is candid that it was largely done for fun.

The comparison table is really a specification of the goals

The README includes a feature comparison against five other implementations, named voronoi++, boost, fastjet, d3-delaunay and jcv. The table is worth reading carefully because it doubles as the author's own list of what he wanted. For jcv, the ticked properties are edge clip, generate edges, generate cells, cell edges not flipped, cell edges in counter-clockwise order, easy relaxation, custom allocator and Delaunay generation. Two of those are unusual enough to be the reason to pick this library. Cell edges that are not flipped and are ordered counter-clockwise remove a class of bug from code that walks cell boundaries. A custom allocator lets you plug the table's allocations into a pool you already manage, which matters in a game engine or a simulation that runs many diagrams in a frame. Easy relaxation means the vertices can be nudged toward a more even spacing without reimplementing the solver.

Installing through Homebrew, npm, or a copy of one file

On macOS the headers and the CMake package metadata come from the project tap:

sh
brew install JCash/tap/jc-voronoi

A CMake project then consumes the installed header-only target:

cmake
find_package(jc_voronoi CONFIG REQUIRED)
target_link_libraries(your_app PRIVATE jc_voronoi::jc_voronoi)

If CMake does not find the Homebrew prefix automatically, the README says to configure with -DCMAKE_PREFIX_PATH set to the output of brew --prefix jc-voronoi. For browser and JavaScript use there is a separate npm package that installs the ES module, the WebAssembly runtime, a worker and TypeScript declarations:

sh
npm install jc-voronoi

and the JavaScript entry point is a single import:

js
import { loadVoronoi } from "jc-voronoi";

const voronoi = await loadVoronoi();

The JavaScript API and examples live in README_JS.md in the repository. Packagers can also set JC_VORONOI_VERSION when configuring so that the installed CMake package carries version metadata, while an ordinary source build does not need a version.

Exactly one translation unit emits the implementation

The C integration is a two line pattern, and the rule about it is absolute. Add src/jc_voronoi.h to your project and emit its implementation from exactly one C or C++ translation unit:

C
#define JC_VORONOI_IMPLEMENTATION
#include "jc_voronoi.h"

Other translation units include jc_voronoi.h without defining JC_VORONOI_IMPLEMENTATION. This is the classic single header library convention, and getting it wrong produces duplicate symbols at link time rather than a subtle bug, which is a fair trade for a library you can vendor with a copy operation. The supported dialects are C99 and later, which the README lists as C99, C11, C17 and C23, and on compilers that use the pre-standard name for C23 you select c2x. The header can also be included from C++, so a mixed language project can share one implementation.

The bundled example app is the fastest way to see output

Since the library is header-only there is nothing to build, but the repository includes src/main.c, an example app that generates a Voronoi diagram and writes it to a PNG or SVG file. On macOS and Linux the README assumes clang is installed and the flow is the same:

sh
./scripts/compile.sh
./build/main -n 100 -r 3 -w 1024 -h 768 -o example.svg

The example generates 100 random sites, applies three relaxation passes and writes a 1024 by 768 example.svg into the current directory, and the same flags work under Windows from an x64 Native Tools Command Prompt, using scripts\compile_cl.bat and build\main.exe. The documentation also explains that the tool exposes options for image size, relaxation, input files and SVG output, reachable through the help flag. If you want the examples and the test suite rather than just the header, the CMake configuration turns them on with JC_VORONOI_BUILD_EXAMPLES and JC_VORONOI_BUILD_TESTS, and the tests are then run through ctest.

The WebAssembly package is the same C code, not a port

Version tags automatically publish a browser-ready WebAssembly package on the GitHub Releases page. The package contains jc_voronoi.wasm, Emscripten's ES-module loader, the JavaScript API and an optional one-shot worker, and there is an interactive WebAssembly demo that is rebuilt from the dev branch. The interesting design decision is in the data path. For site, cell and edge information the library generates an ergonomic diagram, and the result is copied once into a compact JavaScript-owned ArrayBuffer, after which object access reads that buffer without calling back into WebAssembly. That is a deliberate boundary: the expensive computation happens once, and the per-object reads afterwards are plain JavaScript array access. The low level entry point returns edges as a Float32Array of x0, y0, x1, y1 pairs:

js
import { loadVoronoi } from "./voronoi.js";

const voronoi = await loadVoronoi();
const edges = voronoi.edges(
  [{ x: 10, y: 20 }, { x: 80, y: 30 }, { x: 40, y: 90 }],
  100,
  100,
);
// Float32Array: x0, y0, x1, y1 for each edge

One behaviour to know about in the higher level API is that asking for a cell by index can return null when the input site was pruned, so the result has to be checked before use.

Two branches, rapid releases, and a repository that shows its work

The project develops on the dev branch, which is the default branch, with master also carrying a build badge, and the WebAssembly demo is rebuilt from dev, so the two branches serve different audiences. The release history is fast: v0.10.0 on 2026-07-22, then v0.10.1 and v0.10.2 on the same day, 2026-07-25, with the last push also on 2026-07-25. That cadence suggests active work, and the repository is correspondingly transparent about it, carrying BENCHMARKS.md, MIGRATION_GUIDE.md, CHANGELOG.md, a benchmark directory, a test directory, a site directory with a Hugo setup for the documentation, and two planning documents named plan_degenerate_inputs.md and plan_optimizations.md. The presence of a plan for degenerate inputs is a good sign of honesty about the library's weak spots, and it tells you where to look before you rely on it with coincident or collinear points.

Editorial conclusion

Adopt jc_voronoi if you need 2D Voronoi or Delaunay output inside a C or C++ program and want clipped edges, cells with ordered edge lists, a custom allocator and a single file you can vendor, since the library is header-only and has no external dependencies. Do not adopt it if you want a maintained guarantee of correct output across degenerate inputs, because the repository carries its own plans for degenerate inputs and optimizations, and do not expect the JavaScript package to be a separate implementation, since it wraps the same C code in WebAssembly. Before you integrate, build the bundled example with the CMake options for examples and tests, check the relaxation behaviour against your own point sets, and read the migration guide if you are moving from an earlier version.

Frequently asked questions

How do I use jc_voronoi in a C project?

Add src/jc_voronoi.h to your project and define JC_VORONOI_IMPLEMENTATION in exactly one C or C++ translation unit, then include the header normally in every other translation unit. The library is header-only, so nothing has to be compiled or linked as a separate library file.

Which C standards does jc_voronoi support?

The source supports C99 and later, which the README lists as C99, C11, C17 and C23. On compilers that use the pre-standard name for C23 you select c2x, and the header can also be included from C++.

Can I use jc_voronoi from JavaScript or in a browser?

Yes. The npm package jc-voronoi installs the ES module, the WebAssembly runtime, a worker and TypeScript declarations, and version tags publish a browser-ready WebAssembly package with jc_voronoi.wasm and the Emscripten loader. The JavaScript API and examples are in README_JS.md.

What does the example program in jc_voronoi do?

src/main.c is an example app that generates a Voronoi diagram and writes it to a PNG or SVG file. The documented run generates 100 random sites, applies three relaxation passes and writes a 1024 by 768 example.svg, and the full option set is available through the help flag.

How do I build the jc_voronoi examples and tests?

Configure with cmake -S . -B build and the options JC_VORONOI_BUILD_EXAMPLES=ON and JC_VORONOI_BUILD_TESTS=ON, then build and run the tests with ctest --test-dir build. The default CMake build produces no library file because the library is header-only.

Official sources

  1. Issues
  2. JCash/voronoi on GitHub
  3. License: MIT
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jcash-voronoi.svg)](https://hysenlabs.com/projects/jcash-voronoi)

Was this useful?