#type-inference #generics #node #visual

nodety

Easy to use library for node editor types, generics, inference and validation

2 releases

Uses new Rust 2024

new 0.1.1 Mar 9, 2026
0.1.0 Mar 9, 2026

#381 in Web programming

MIT/Apache

280KB
5K SLoC

Crates.io Documentation dependency status Codecov

Nodety

Generics, type inference, and validation for visual node editors.

Nodety gives your node graph a type system comparable to TypeScript. Define node signatures like <T, U>(Array<T>, (T) -> (U)) -> (Array<U>), wire them up, and let nodety infer T = Integer, U = String automatically.

Features

  • Generics & inference<T>(T) -> (T)
  • Conditional typesT extends String ? String : Never
  • Unions & intersections"a" | "b", { a: Int } & { b: String }
  • Keyof & index accesskeyof { a: Int }, { a: Int }["a"]
  • Variadic ports (inputs & outputs)(...Integer) -> (Array<Integer>)
  • Rank-N polymorphism(<T>(T) -> (T)) -> ()
  • User-defined type operations<A, B>(A, B) -> (A * B) (e.g. SI units)
  • Propagating tags — enforce constraints like const-correctness across the graph
  • Detailed diagnostics — validation errors pinpoint the exact edge/port with subtyping traces

Quick start

[dependencies]
nodety = "0.1"
// Mapper Example:
// Generic mapper node that infers the source type from an input
// array and the output from a mapper node signature.
//
// here nodety infers that
// T = Integer
// U = String
//
// |- Array source -----------|               |- <T, U>Map ----------------|
// |           Array<Integer> | ------------> | Array<T>          Array<U> |
// |--------------------------|               |                            |
//                                    /-----> | (T) -> (U)                 |
// |- Mapper -----------------|       |       |----------------------------|
// |    (Integer) -> (String) | ------/
// |--------------------------|

use nodety::{Nodety, demo_type::DemoType, inference::InferenceConfig};
use nodety::type_expr::node_signature::NodeSignature;
use std::str::FromStr;

let mut nodety = Nodety::<DemoType>::new();

let source = "() -> (Array<Integer>)".parse::<NodeSignature<_>>().unwrap();
let mapper = "() -> ((Integer) -> (String))".parse::<NodeSignature<_>>().unwrap();
let map    = "<T, U>(Array<T>, (T) -> (U)) -> (Array<U>)".parse::<NodeSignature<_>>().unwrap();

let src_id = nodety.add_node(source).unwrap();
let map_id_fn = nodety.add_node(mapper).unwrap();
let map_id = nodety.add_node(map).unwrap();

nodety.add_edge(src_id, map_id, 0, 0);
nodety.add_edge(map_id_fn, map_id, 0, 1);

let inference = nodety.infer(InferenceConfig::default());
let errors = nodety.validate(&inference);
assert!(errors.is_empty());

// T = Integer, U = String

Cargo features

Feature Default Description
parser yes Parse signatures and type expressions from strings
serde no Serialize / deserialize types with serde
json-schema no JSON Schema generation via schemars
wasm no wasm-bindgen support (enables serde)
tsify no TypeScript type generation (enables wasm)
proptest no Arbitrary impls for property testing

Minimum Supported Rust Version (MSRV)

The MSRV is 1.85.0 (Rust edition 2024).

Documentation

See the crate docs for the full guide — types, scopes, notation, and more.

Contributing

Found a bug? Please open an issue with a minimal reproduction. Including a failing test case is especially helpful and will speed up fixes.

Feature requests and pull requests are also welcome.

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.

Dependencies

~2.2–3.5MB
~58K SLoC