spacecurve: space-filling curves as a Rust library, a renderer and a web playground
A library for drawing space-filling curves like the Hilbert Curve.
At a glance
- What is it?
- spacecurve is a Rust workspace holding a library for generating and working with space-filling curves such as the Hilbert curve, a command line tool and GUI called scurve for drawing them, and a WebAssembly playground built with egui. The library is MIT licensed, uses the 2024 edition of Rust, and treats missing documentation as a warning.
- Who is it for?
- Adopt spacecurve if you need to generate or visualise space-filling curves, either as a library for indexing and inverting grid coordinates or as a tool for producing images of them. Skip it if all you need is a Z-order or Morton code, since that is a handful of lines to write yourself.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 53 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What a space-filling curve is, and why the ordering matters
The README opens with the definition, and it is worth keeping in view because the library is really about the discrete version of it. A space-filling curve is a continuous surjection from the unit interval to the unit hypercube for a dimension of two or more. In discrete spaces this becomes an ordering of grid cells that visits every cell, and the README draws the distinction that decides which curve you want. Some orderings preserve adjacency, with the Hilbert curve named as the example, while others trade adjacency for simplicity, with Morton or Z-order named as the example. That trade is the practical content of the library. A Hilbert curve visits neighbouring cells in neighbouring positions in the path, so a contiguous run of the index corresponds to a contiguous region of the grid, which is what you want when you are caching or chunking. A Morton code is simpler to compute and to decode, but a contiguous run of the index does not correspond to a compact region. Everything else in the project, the renderer, the colour maps, the sorting visualisation, follows from the properties of the ordering itself. The library and the tools are published on crates.io as spacecurve and scurve, with documentation on docs.rs, both under the MIT licence.
The library API in twenty lines
The example in the README is the whole public surface in miniature, and it reads as an index and inverse index pair.
// 2D Hilbert curve on an 8x8 grid (order 3)
let curve = spacecurve::curve_from_name("hilbert", 2, 8)?;
println!(
"{}D Hilbert length: {} cells",
curve.dimensions(),
curve.length()
);
let index = 10;
let point = curve.point(index);
println!("Point at index {index}: {:?}", point);
let round_trip = curve.index(&point);
println!("Index for {:?}: {round_trip}", point);
assert_eq!(round_trip, index);Four things are visible. The curve is obtained by name, dimension and size, so a curve is a named algorithm instantiated for a given dimensionality and grid resolution, and the error return tells you the name was not recognised or the arguments were not valid. The dimensions and length accessors report what you asked for, with the length being the number of cells in the grid. The point method maps an index in the ordering to a coordinate, and the index method is its inverse, and the assertion at the end is the property that matters, since a point and its index must round trip exactly. That round trip is the property any application built on a space-filling curve depends on, because it is what lets you store a position as a scalar key and recover the position later.
One workspace, three published crates
The repository is a Cargo workspace with the members given as the crates directory plus an xtask, and the workspace version is 0.2.0 under the 2024 edition of Rust.
[workspace]
resolver = "2"
members = [ "crates/*", "xtask" ]The workspace dependencies list names the three local packages, the spacecurve library itself, the scurve GUI and an egui-img package, each given as a path with a matching version, so the crates are versioned together in the workspace even though they are published separately.
[workspace.dependencies]
spacecurve = { path = "crates/spacecurve", version = "0.2.0" }
scurve-gui = { path = "crates/scurve-gui", version = "0.2.0" }
egui-img = { path = "crates/egui-img", version = "0.2.0" }So the project is three things. The library is the one you depend on from Rust code. The scurve tool is a command line program and graphical application for generating images of space-filling curves, installed with a single cargo command.
cargo install scurveAnd the playground is a separate GUI, written in Rust with egui and compiled to WebAssembly, so it runs in the browser. The README shows a link to the hosted playground and an image of a three dimensional curve viewer, which is the clearest illustration of what the tool is for, since a three dimensional curve is much easier to grasp when you can rotate it. The workspace also carries a web build profile that optimises for size rather than speed, since a WebAssembly payload is downloaded over a network.
[profile.wasm-release]
inherits = "release"
opt-level = "z" # Optimize for sizeThe lint configuration is the clearest statement of the project's standards
The workspace carries a long list of clippy lints enabled at warn level, and reading it tells you more about how the author works than any prose in the repository would. The rust lints start with missing_docs as a warning, so every public item is expected to carry documentation, and the clippy list is extensive enough to be worth reading in groups. Style lints include absolute_paths, use_self, needless_pass_by_value, redundant_clone, redundant_pub_crate and needless_pass_by_ref_mut. Naming and hygiene lints include many_single_char_names, self_named_module_files and wildcard_dependencies. Structure lints include branches_sharing_code, items_after_statements, comparison_chain and multiple_inherent_impl. There are two project-specific rules that stand out. ignore_without_reason requires every allow attribute to carry a justification, and tests_outside_test_module requires tests to live in a test module rather than scattered in the file, which is a stricter convention than most Rust projects follow. The clippy.toml file adds the configuration valued lints, with cognitive_complexity, excessive_nesting and too_many_lines as warnings, so a function that grows too large or too branchy is reported. There is a commented out unused_crate_dependencies rule with a note explaining the workflow it was used for, enabling it briefly, running clippy without tests and examples, fixing the unused dependencies and disabling it again. The repository also carries a rustfmt-nightly.toml, so the formatting configuration requires a nightly formatter, and a clippy.toml of its own.
The web build, the tooling directories and the agent files
The top level of the repository shows a project that has been set up for automated work rather than just for a developer at a keyboard. There is a Cargo.toml and Cargo.lock, an xtask directory, which in Rust conventionally holds custom build and maintenance commands, and a smoketest/ directory, which suggests a lightweight test that runs against the built artefacts rather than a full unit test suite. There are several files that are instructions for coding agents, with an AGENTS.md, a CLAUDE.md, a GEMINI.md and an.agents.md, plus a DEV.md, an EVALS.md and an.edev.toml. There is also a.codex/ directory, a.mcp.json file and a.cargo/ directory, which together indicate that the author drives the project with agent tooling and has wired in the Model Context Protocol configuration. A.mcp.json at the root of a repository is a machine readable server definition, so the intent is that an agent working in this checkout can call tools the project needs. The Cargo manifest also carries a patch section that redirects one dependency to a local path, which is a common pattern when a dependency is developed alongside the project.
[patch.crates-io]
tmcp = { path = "/Users/cortesi/git/public/tmcp/crates/tmcp" }That patch points at a path outside the repository on the author's machine, so a fresh clone will not resolve it as-is, which is a practical note for anyone trying to build the workspace themselves. The assets/ directory holds the images used in the README, and the repository is MIT licensed with the author given as Aldo Cortesi and the manifest homepage pointing back at the repository itself. The last push to the repository was on 2026-08-31, the project is not archived, and there are no GitHub releases, so the crates.io versions are the release record.
The blog posts explain the ideas behind the features
The README is unusually clear that the project is driven by writing. Development on spacecurve and its ancestors is usually spurred along by posts on the author's blog, and some of the features are documented and illustrated in those posts. The first is a portrait of the Hilbert curve, and the image in the README header is the output of the tool, with a caption naming the exact command that produced it. The second post is about generating colour maps with space-filling curves, which is a use case worth pausing on, since it means the ordering itself is the data, and mapping a scalar value to a colour by walking the curve gives a mapping where nearby values land in nearby cells. The third post is about the Hilbert curve combined with sorting algorithms and what that produces, which is the classic demonstration of a space-filling curve as a sort order. The header image caption is a small but useful piece of documentation, since it tells you that the command shown produced the exact picture above it, and a reader can reproduce it.
The community section points to a Discord server for contributions and ideas, and the badge at the top of the README links to the same place. The repository description itself is minimal, a library for drawing space-filling curves like the Hilbert curve, and the workspace description is fuller, a space-filling curves library and visualization tools, with keywords covering space-filling, curve, hilbert, z-order and morton and categories of algorithms and graphics.
Where spacecurve is the wrong choice
The first limit is that the README is short and the documentation is thin, so a user has to read the source and the blog posts to learn which curves are implemented and what their properties are. The example uses the name hilbert and the keywords mention z-order and morton, but the registry of available names is not documented in the README, so you cannot tell from the front page what you can ask for, and the error return from curve_from_name is where you find out. The second is that the library operates on a fixed grid size, since the curve is constructed for a given size and the length is that many cells, which means a size that is not a power of two is likely unsupported for the algorithms that require it, and the README does not state the constraint. A library that indexes into a fixed grid is also not a library for streaming an arbitrarily large one. The third is the toolchain weight, since this is Rust, the project uses the 2024 edition, so a recent compiler is needed, and the workspace includes an xtask, a smoketest directory and a set of agent instruction files, which makes the build more involved than a single crate. The fourth is that the WebAssembly playground is a separate compiled artefact rather than something you get from the library, so if you want to embed a curve viewer in your own web page you are writing that integration yourself. And the fifth is the licensing ambiguity in the repository listing, which records the licence as unknown even though the README badge and the workspace manifest both say MIT, so the authoritative statement is the manifest and the LICENSE file rather than the listing.
Editorial conclusion
Adopt spacecurve if you need to generate or visualise space-filling curves, either as a library for indexing and inverting grid coordinates or as a tool for producing images of them. Skip it if all you need is a Z-order or Morton code, since that is a handful of lines to write yourself. Verify first which crate you want, since the library, the renderer and the GUI are separate published packages, and that the curve names you pass to the library are the ones it registers.
Frequently asked questions
What does the spacecurve library provide?
It provides implementations of space-filling curves and the operations needed to use them, which for a discrete curve means an ordering of grid cells that visits every cell. A curve is created by name, dimension and grid size with spacecurve::curve_from_name, and you can ask for its dimensions and length, map an index to a point with point, and map a point back to an index with index, with the round trip holding exactly.
What are the three parts of the spacecurve project?
The spacecurve crate is the library, published on crates.io with documentation on docs.rs. The scurve tool is a command line program and GUI for generating images of space-filling curves, installed with cargo install scurve. The third is a playground, a GUI written in Rust with egui and compiled to WebAssembly so it can be visited in the browser.
Why does the spacecurve workspace enable so many clippy lints?
The workspace turns on a long list of lints at warn level, including missing_docs, and project specific rules such as ignore_without_reason, which requires every allow attribute to carry a justification, and tests_outside_test_module, which requires tests to live in a test module. The clippy.toml adds cognitive_complexity, excessive_nesting and too_many_lines, so a function that grows too branchy or too long is reported, and the manifest requires Rust edition 2024 with resolver 2.
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/cortesi-spacecurve)