# NearestNeighbors.jl: 10 year anniversary, "recent" updates and developments

**URL:** https://discourse.julialang.org/t/nearestneighbors-jl-10-year-anniversary-recent-updates-and-developments/134518
**Category:** Community
**Created:** [December 12, 2025, 2:54pm UTC](https://discourse.julialang.org/t/nearestneighbors-jl-10-year-anniversary-recent-updates-and-developments/134518 "2025-12-12T14:54:24Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 12, 2025, 2:54pm UTC](https://discourse.julialang.org/t/nearestneighbors-jl-10-year-anniversary-recent-updates-and-developments/134518/1 "2025-12-12T14:54:24Z")

</div>

[NearestNeighbors.jl](https://github.com/KristofferC/NearestNeighbors.jl) is the first package I created with the initial commit now being (slightly over) 10 years ago.

In fact, doing a nearest neighbors query was the very first code I wrote in Julia (with the Julia LightTable plugin) when I was a teachers assistant in a Python course where  
we used k-d trees for an assignment and I wanted to experiment a bit with other languages.

The package has been mostly in maintenance mode for a while, but I recently added some new features that I would like to share. For more details you can look in the README of the package.

## Periodic boundary conditions

NearestNeighbors can now do searches assuming that points are periodically repeating within some bounding box. This is done by wrapping a tree and specifying the bounding-box extents:

```julia
using NearestNeighbors

kdtree = KDTree(data)

p_kdtree = PeriodicTree(kdtree, [0.0, 0.0], [1.0, 1.0])

```

The API is then identical to any other tree in NearestNeighbors.

## Self queries

It is now possible to do both range and knn self-searches across all points in a tree with `inrange_pairs` and `allknn`:

```julia-auto
julia> d = rand(3,10); tree = KDTree(d);

julia> range = 0.3

julia> inrange_pairs(tree, range) # all pairs (i, j) within a certain range
3-element Vector{Tuple{Int64, Int64}}:
(1, 6)
(3, 7)
(6, 8)

julia> k = 2

julia> idxs, dists = allknn(tree, k); # k neighbors to each point in tree
 
julia> idxs
10-element Vector{Vector{Int64}}:
[8, 6]
[6, 5]
[9, 7]
[9, 5]
[4, 2]
...

julia> dists
10-element Vector{Vector{Float64}}:
[0.16387521055240933, 0.0380628491898866]
[0.2848492080997025, 0.20752470954341026]
[0.15886092320279743, 0.08144735280130108]
[0.6523525478275332, 0.2623835541815712]
[0.2623835541815712, 0.20752470954341026]
...

```

## Parallel tree building

Trees are now built using multiple threads (when Julia is started with multiple threads available).  
As an example:

```julia

julia> @btime KDTree(rand(3, 10^6));
# 1 thread
197.647 ms (36 allocations: 84.34 MiB)
# 10 threads:
38.420 ms (25031 allocations: 86.86 MiB)

julia> @btime BallTree(rand(3, 10^6))
# 1 thread
240.852 ms (33 allocations: 86.41 MiB)
# 10 threads:
48.513 ms (30027 allocations: 88.92 MiB)

```

## Tree traversal

There is now an official API for traversing trees for some advanced use cases.

It extends AbstractTrees.jl so it works with the iterators defined in that package, but we also provide custom iterators because the AbstractTrees ones were order(s) of magnitude slower in some cases.

The two notebooks:

- [NearestNeighbors.jl/examples/kdtree\_illustration.ipynb at master · KristofferC/NearestNeighbors.jl · GitHub](https://github.com/KristofferC/NearestNeighbors.jl/blob/master/examples/kdtree_illustration.ipynb)

- [NearestNeighbors.jl/examples/balltree\_illustration.ipynb at master · KristofferC/NearestNeighbors.jl · GitHub](https://github.com/KristofferC/NearestNeighbors.jl/blob/master/examples/balltree_illustration.ipynb)

are examples of using this tree traversal API to illustrate the tree structures.

## Unit support

The package now works with unitful data:

```julia-auto
using Unitful, NearestNeighbors, StaticArrays
using Unitful.DefaultSymbols

tree = NearestNeighbors.KDTree([SVector(1m,2m,3m)]);

NearestNeighbors.nn(tree,[1m,2m,3m])
# (1, 0.0 m)

```

## Performance improvements

Various tweaks and changes have been made to improve performance.  
Below are links to PRs for anyone interested in the details:

Keep track of max distance from a point to a hyper rectangle, which can allow stopping traversal and adding all points:

- [use the maximum distance to hyper rectangle to add all points in the subtree for `inrange` calculations by KristofferC · Pull Request #215 · KristofferC/NearestNeighbors.jl · GitHub](https://github.com/KristofferC/NearestNeighbors.jl/pull/215)

Fewer square roots used for BallTree:

- [optimize some hypersphere checks for minkowski metrics by KristofferC · Pull Request #195 · KristofferC/NearestNeighbors.jl · GitHub](https://github.com/KristofferC/NearestNeighbors.jl/pull/195)
- [avoid some square rooting to check distances by KristofferC · Pull Request #197 · KristofferC/NearestNeighbors.jl · GitHub](https://github.com/KristofferC/NearestNeighbors.jl/pull/197)

Bumped default leaf size:

- [https://github.com/KristofferC/NearestNeighbors.jl/pull/198](https://github.com/KristofferC/NearestNeighbors.jl/pull/198)

`nn` is now non-allocating:

- [make `nn` non-allocating by having it "track" scalars by KristofferC · Pull Request #228 · KristofferC/NearestNeighbors.jl · GitHub](https://github.com/KristofferC/NearestNeighbors.jl/pull/228)

Improved type stability in outputs when tree is created with matrix data (and the dimensions of points are not statically known):

- [fix inferrability of return value with KDTree created from matrix of points by KristofferC · Pull Request #212 · KristofferC/NearestNeighbors.jl · GitHub](https://github.com/KristofferC/NearestNeighbors.jl/pull/212)

* * *

Thanks for reading and please open issues / PRs if you have issues or requests for improvements.

---

<div class="post-metadata">

### Author: ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)
#### Post date: [December 12, 2025, 3:00pm UTC](https://discourse.julialang.org/t/nearestneighbors-jl-10-year-anniversary-recent-updates-and-developments/134518/2 "2025-12-12T15:00:17Z")

</div>

Just to say thank you for the package, which I used for this:

[![](https://global.discourse-cdn.com/julialang/original/3X/8/a/8ab2a86cda195fb8669a4f9bf061f64797bfff41.jpeg "social networks") ](https://www.youtube.com/watch?v=8k-T9adzeEQ)

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [December 12, 2025, 4:55pm UTC](https://discourse.julialang.org/t/nearestneighbors-jl-10-year-anniversary-recent-updates-and-developments/134518/3 "2025-12-12T16:55:42Z")

</div>

Some nearest neighbors in 2025:

 ![images (1)](https://global.discourse-cdn.com/julialang/original/3X/0/b/0b1997e4ea7c3fef134400a79d8bc7980985843f.jpeg)

---

<div class="post-metadata">

### Author: ![kylebeggs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kylebeggs/32/43348_2.png) [@kylebeggs](https://discourse.julialang.org/u/kylebeggs)
#### Post date: [December 12, 2025, 4:56pm UTC](https://discourse.julialang.org/t/nearestneighbors-jl-10-year-anniversary-recent-updates-and-developments/134518/4 "2025-12-12T16:56:55Z")

</div>

This package is quite mature and stable (and awesome), are there plans to release v1.0?

---

<div class="post-metadata">

### Author: ![cgeoga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cgeoga/32/216186_2.png) [@cgeoga](https://discourse.julialang.org/u/cgeoga)
#### Post date: [December 12, 2025, 5:49pm UTC](https://discourse.julialang.org/t/nearestneighbors-jl-10-year-anniversary-recent-updates-and-developments/134518/5 "2025-12-12T17:49:42Z")

</div>

Thank you for all of your work on this package! It has been extremely important and useful for almost all of my applications and I am so grateful to have something so performant and stable in my back pocket.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 12, 2025, 7:00pm UTC](https://discourse.julialang.org/t/nearestneighbors-jl-10-year-anniversary-recent-updates-and-developments/134518/6 "2025-12-12T19:00:39Z")

</div>

> [@kylebeggs](#):
>
> This package is quite mature and stable (and awesome), are there plans to release v1.0?

There is a “road map” open for it [1.0 road map · Issue #180 · KristofferC/NearestNeighbors.jl · GitHub](https://github.com/KristofferC/NearestNeighbors.jl/issues/180). I’ve been trying to get as much in that is non-breaking first. But I think it is getting close to a 1.0 at least.

---

<div class="post-metadata">

### Author: ![will-davis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/will-davis/32/219982_2.png) [@will-davis](https://discourse.julialang.org/u/will-davis)
#### Post date: [December 16, 2025, 2:44am UTC](https://discourse.julialang.org/t/nearestneighbors-jl-10-year-anniversary-recent-updates-and-developments/134518/7 "2025-12-16T02:44:07Z")

</div>

Congratulations! I’m happy to have [my recent PR](https://github.com/KristofferC/NearestNeighbors.jl/pull/219) included into this 10 year journey!
