Good ergonomics shouldn't cost you speed or safety.
The common wisdom is that you trade developer experience for performance and safety. Node and TypeScript when you want to move fast, Rust when it has to hold up. I've never fully bought it. A lot of my open-source work is me picking at that line to see how much of the tradeoff is real and how much is just habit.
Toni: NestJS ideas on a Rust floor
Toni is a Rust web framework built around the one thing I missed most coming from NestJS: its decorator and module structure, the part that keeps a big Node codebase navigable. It runs on Tokio and Hyper and keeps that same organization on top of Rust's type system.
The structure was never the slow part of NestJS. The runtime under it was. Toni keeps the structure and swaps the runtime.
winston-rs
winston-rs is structured logging for Rust, modeled on Node's Winston: multiple transports, structured JSON, configurable levels. Rust didn't have a logger with that ergonomics when I needed one, so I wrote it.
Scalars, contributed upstream
I contributed four scalars to the graphql-scalars library: ULID, GeoJSON, Countries, and Cuid2, each with full serialization, parsing, and validation. They were missing upstream, so I added them.
In practice
winston-rs
↗Structured logging for Rust, modeled on Node's Winston: multiple transports, structured JSON output, configurable levels. Rust didn't have a logger with that ergonomics when I needed one, so I wrote it.
Toni
↗A Rust web framework that ports NestJS's decorator and module structure onto Rust's type system, on top of Tokio and Hyper. Same way of organizing code, Rust underneath.
graphql-scalars
↗Four scalars contributed upstream to the graphql-scalars library: ULID for sortable unique IDs, GeoJSON for geospatial validation, Countries for ISO 3166-1 alpha-2 codes, and Cuid2 for collision-resistant IDs. Each ships with full serialization, parsing, and validation.
I build these because I'd rather use them than keep wishing they existed.