Jacquard: A Better Rust ATProtocol Crate
The ATProtocol ecosystem has a problem. The libraries that exist? They make things harder than they need to be.
Jacquard takes a different approach. Its tagline says it plainly: "A better Rust ATProto crate."
The Philosophy
"Jacquard is simpler because it is designed in a way which makes things simple that almost every other atproto library seems to make difficult."
That's not marketing speak. It's the actual design principle.
Other libraries require you to understand the protocol's quirks before you can do anything. Jacquard abstracts those quirks away—not by hiding them, but by making the common path actually simple.
Zero-Copy Deserialization
The technical innovation that makes this possible: zero-copy deserialization.
Types like Post<'_> borrow data directly from the response buffer using CowStr<'_> (copy-on-write strings). No allocations. No copying.
// Zero-copy: borrow from the owned buffer
let output: R::Output<'_> = response.parse()?;
// Owned: convert to 'static via IntoStatic
let output: R::Output<'static> = response.into_output()?;
The IntoStatic trait (which is derivable) converts borrowed types to owned when you need them long-lived. You choose when to pay the allocation cost.
Just .send() It
One method for any endpoint. No restrictive enums. No predefined record sets.
let agent: Agent<_> = Agent::from(session);
let timeline = agent
.send(&GetTimeline::new().limit(5).build())
.await?
.into_output()?;
Whatever ATProtocol API you need to call, just .send() it.
The library doesn't force you into a specific pattern. You can use the stateful Agent for convenience, or drop down to stateless primitives when you need control.
Modular Architecture
Jacquard is split into focused crates:
| Crate | Purpose |
|-------|---------|
| jacquard | Main crate—you usually want this one |
| jacquard-common | Core types: DIDs, handles, at-URIs, NSIDs, TIDs, CIDs |
| jacquard-api | Generated bindings from 646 lexicon schemas |
| jacquard-oauth | ATProtocol OAuth implementation |
| jacquard-repo | Repository primitives: MST, commits, CAR I/O |
| jacquard-identity | DID and handle resolution |
| jacquard-lexicon | Lexicon parsing and code generation |
| jacquard-derive | Procedural macros for lexicon types |
Use as much or as little as you need. The batteries are included, but they're replaceable.
What People Are Saying
The testimonials from real users:
"the most straightforward interface to atproto I've encountered so far." — @offline.mountainherder.xyz
"It has saved me a lot of time already! Well worth a few beers and or microcontrollers" — @baileytownsend.dev
"This is what your library allowed me to do in an hour!!! Thank you!!!" — @desertthunder.dev
Real Projects Using It
This isn't a toy library. It's running production code:
- Tranquil PDS — A personal data server implementation
- Weaver — Long-form writing platform on ATProtocol
- skywatch-phash-rs — Perceptual hashing for image deduplication
- Tangled repository — Git hosting on ATProtocol
- wisp.place — CLI tool
- PDS MOOver — Another PDS implementation
The maintainer, Orual (@nonbinary.computer), built Weaver on top of Jacquard. They eat their own dog food.
Code Generation That's Actually Nice
Recent versions include a completely overhauled code generation pipeline:
- Tracks types used within each file
- Generates import blocks automatically
- Organizes output with public API at the top, internal details at the bottom
- Conditionally generates short paths when types are unambiguous
The generated code isn't just functional—it's readable.
The atproto! Macro
Like serde_json has json!, Jacquard has atproto!:
let aspect_obj = atproto! {{
"width": width,
"height": height
}};
Compact, readable, and type-checked.
Why This Matters
Better APIs make better ecosystems.
ATProtocol is still young. The tooling that emerges now will shape how developers experience the protocol for years.
Jacquard's approach—making the hard things easy, the common things simple, and the complex things possible—is exactly what a young ecosystem needs.
Getting Started
[dependencies]
jacquard = "0.11"
Or check out the repository:
https://tangled.org/nonbinary.computer/jacquard
The docs are good. The examples are real. The code is production-ready.
Thanks to @nonbinary.computer for building something that makes the hard things easy.