mirror of
https://github.com/zap-proto/dev.git
synced 2026-10-30 15:05:18 +00:00
* docs: tools section (pb2zap, zap2pb), zip server page, ZAP-only production story - content/docs/tools/: new Tooling nav group — the complete pb<->ZAP interop boundary. pb2zap (go/ast codemod off protobuf), zap2pb (the one sanctioned protobuf import: Marshal/Unmarshal/Equal/ AppendMessage, v0.2.0), and the migration path over the existing schema/codegen pages. - content/docs/zip.mdx: the ZAP-native application server — one Listen verb (ZAP primary, HTTP secondary), typed handlers with REST/OpenAPI/MCP projections, Mount composition, and the hanzoai/cloud case: sub-1,000-line compose root hosting ~75K LOC of subsystems (76:1). - why-zap: scrub the unmeasured benchmark tables (per the benchmarks-page policy), replace with mechanism arguments and the ZAP-only-in-production account: zero gRPC, protobuf confined to the four-function zap2pb boundary at the OTLP edge. - ecosystem: add zip/pb2zap/zap2pb rows; quick-start + index: link the new pages, drop the unmeasured 5-20x claim. * fix(build): alias MDX collections to regenerated docs/, drop frozen .docs snapshot next.config.mjs and tsconfig.json pointed @hanzo/docs-mdx:collections/* at .docs/ — a snapshot frozen on Jun 1 — while the MDX plugin regenerates docs/ on every build. Result: no page added since the snapshot (schema, codegen, rpc, capabilities, and this PR%27s tools/zip) was ever emitted; the site silently served 37 routes instead of 45. Alias both resolvers at docs/ and remove .docs. --------- Co-authored-by: Hanzo Dev <[email protected]>
130 lines
7.7 KiB
Plaintext
130 lines
7.7 KiB
Plaintext
---
|
|
title: Why ZAP?
|
|
description: What ZAP replaces, what it buys you, and the production stack that runs it with zero gRPC and zero protobuf.
|
|
---
|
|
|
|
# Why ZAP?
|
|
|
|
ZAP replaces **both halves** of the conventional RPC stack — protobuf (serialization) and gRPC (transport + RPC) — with one layer. This page explains the mechanism, compares the alternatives honestly, and shows what a stack looks like when the replacement is complete: a real production deployment with zero gRPC and protobuf confined to one four-function file.
|
|
|
|
## The problem
|
|
|
|
Modern distributed systems inherit four costs from their RPC framework:
|
|
|
|
1. **Serialization overhead** — JSON and protobuf require an encode/decode step on every hop
|
|
2. **Transport lock-in** — most frameworks are welded to a single transport (gRPC to HTTP/2)
|
|
3. **Bolted-on trust** — auth is per-layer (TLS *and* tokens *and* API keys), consensus is a separate integration
|
|
4. **Two artifacts per contract** — a schema *and* a framework config, each drifting independently
|
|
|
|
## How ZAP solves these
|
|
|
|
### Zero-copy serialization
|
|
|
|
ZAP's wire format is directly usable in memory. There is no parsing step — data is accessed in place from the buffer.
|
|
|
|
```
|
|
Traditional RPC:
|
|
Wire -> Parse -> Memory Object -> Use
|
|
|
|
ZAP:
|
|
Wire -> Use (directly)
|
|
```
|
|
|
|
Measured numbers live on the [benchmarks page](/docs/benchmarks) — every table there is reproducible from [zap-proto/bench](https://github.com/zap-proto/bench), and claims that can't be traced to a checked-in harness don't get published. The mechanism argument stands on its own: object-mode access has no decode step to pay for, which is why it leads every mode in the harness.
|
|
|
|
### Transport flexibility
|
|
|
|
ZAP abstracts the transport layer:
|
|
|
|
| Transport | Latency | Reliability | Use Case |
|
|
|-----------|---------|-------------|----------|
|
|
| TCP | Low | Guaranteed | Default choice |
|
|
| UDP | Lowest | Best-effort | Real-time telemetry |
|
|
| Unix Socket | Lowest | Guaranteed | Same-host IPC |
|
|
| WebSocket | Medium | Guaranteed | Browser clients |
|
|
|
|
Switching transports requires no code changes:
|
|
|
|
```go
|
|
// TCP (default)
|
|
client, _ := zap.Dial("tcp://localhost:9000")
|
|
|
|
// Unix socket
|
|
client, _ := zap.Dial("unix:///var/run/zap.sock")
|
|
|
|
// WebSocket
|
|
client, _ := zap.Dial("ws://localhost:9000/rpc")
|
|
```
|
|
|
|
On the server side, [zip](/docs/zip) takes the same idea further: one `Listen` verb, address scheme selects the transport, ZAP primary and HTTP secondary over the same routes.
|
|
|
|
### One trust model
|
|
|
|
Authentication is bound to the transport — mutual [post-quantum KEM](/docs/post-quantum) identity, not TLS-plus-tokens — and authority is expressed as [**capabilities**](/docs/capabilities): references the holder can call but cannot forge, transferable to a third peer, revocable without rotating keys. [The capability mailbox example](/docs/examples/capability-mailbox) shows what this makes possible that bearer tokens structurally cannot express. Optional [BFT consensus](/docs/consensus) rides the same wire.
|
|
|
|
### First-class code generation
|
|
|
|
One `.zap` schema is the entire contract — structs, RPC surface, stable opcodes:
|
|
|
|
```bash
|
|
zap generate calculator.zap --lang=go --out=./gen
|
|
```
|
|
|
|
Generation emits a zero-copy View/Builder per struct plus a typed client and server per interface — the [Schema Language](/docs/schema) and [Code Generation](/docs/codegen) pages are the references. The [tools section](/docs/tools) covers the migration path off protobuf.
|
|
|
|
## ZAP instead of gRPC + protobuf
|
|
|
|
gRPC and protobuf are two products you adopt together and pay for separately. ZAP is one layer:
|
|
|
|
| Concern | gRPC + protobuf | ZAP |
|
|
|---------|-----------------|-----|
|
|
| Serialization | protobuf — encode/decode every hop | zero-copy — the in-memory layout *is* the wire layout |
|
|
| Transport | HTTP/2 only | TCP, UDP, Unix, WebSocket; [pluggable](/docs/zip#transport-is-a-value-not-a-method) |
|
|
| Schema | `.proto` + ordinals + separate service config | one `.zap` file — structs + interface + opcodes |
|
|
| Auth | TLS at the edge, tokens in-band | identity-bound transport, PQ KEM, capabilities |
|
|
| Browser | requires grpc-web proxy | native WebSocket |
|
|
| Streaming | bidirectional | bidirectional + promise pipelining |
|
|
| Consensus | separate integration | built-in, optional |
|
|
|
|
**Choose gRPC when**: you need its ecosystem — existing proto contracts with external partners, off-the-shelf interceptor middleware, teams fluent in it.
|
|
|
|
**Choose ZAP when**: you control both ends of the wire and want one wire format, one trust model, and no serializer between layers.
|
|
|
|
## ZAP-only in production
|
|
|
|
This is not a roadmap claim. The Hanzo AI + Lux Network stack runs ZAP-native today, with **zero gRPC and zero protobuf in application code**:
|
|
|
|
- **One binary.** [hanzoai/cloud](https://github.com/hanzoai/cloud) composes IAM, KMS, gateway, commerce, AI, and a dozen more subsystems into a single Go binary. The compose root is under 1,000 lines of [zip](/docs/zip) hosting ~75,000 lines of subsystem code — a 76:1 ratio of product over framework shim.
|
|
- **One wire contract per service.** Every RPC surface is a `.zap` schema — structs plus stable opcodes. [hanzoai/tasks](https://github.com/hanzoai/tasks) (`schema/tasks.zap`) states it the way every service does: *"This is the one and only wire contract. Nothing on this wire speaks protobuf, gRPC, or any temporal.io-branded framing."*
|
|
- **One protobuf touchpoint.** Observability is the industry edge that still speaks protobuf (OTLP/OpAMP). The stack's entire protobuf surface is [zap2pb](/docs/tools/zap2pb) — one file, four functions. Spans are OTLP-protobuf payloads shipped over ZAP frames to the collector's ZAP receiver; no OTLP-over-gRPC, no second protobuf import anywhere.
|
|
- **Mechanical migration.** [pb2zap](/docs/tools/pb2zap) rewrote the unambiguous protobuf construction sites; humans restructured the read paths it reported.
|
|
|
|
The same dispatch generalizes upward: Hanzo and Lux run services as ZAP-native plugin VMs — ZAP is the dispatch surface, Lux consensus orders it, zapdb persists it. Deployments and their numbers are tracked on the [ecosystem page](/docs/ecosystem).
|
|
|
|
## When to use ZAP
|
|
|
|
- **High-throughput services**: financial systems, game backends, real-time analytics
|
|
- **Low-latency requirements**: trading systems, live collaboration, IoT
|
|
- **Distributed consensus**: blockchain nodes, distributed databases, leader election
|
|
- **Polyglot environments**: services in Go, Rust, and TypeScript communicating seamlessly
|
|
- **Agent infrastructure**: [MCP](/docs/protocols/mcp) and [A2A](/docs/protocols/a2a) ride the ZAP wire natively
|
|
|
|
## When not to use ZAP
|
|
|
|
- **Simple public REST APIs**: standard HTTP may be all you need
|
|
- **Contracts you don't own**: if external partners mandate proto/gRPC contracts, you keep them — though [zap2pb](/docs/tools/zap2pb) shows how narrow that edge can be
|
|
- **Browser-only products**: if browsers are your only client, GraphQL or plain HTTP may fit better
|
|
|
|
## Performance
|
|
|
|
Every published number is on the [benchmarks page](/docs/benchmarks), reproducible from the harness in [zap-proto/bench](https://github.com/zap-proto/bench). The honest summary: ZAP wins modestly at small payloads, ties in the middle, and the strongest arguments today are mechanism, not microseconds — one wire format under every protocol, PQ at the transport, capabilities instead of tokens.
|
|
|
|
## Summary
|
|
|
|
1. **One layer** replaces protobuf + gRPC — zero-copy wire, typed RPC, transport choice
|
|
2. **One trust model** — identity-bound transport, capabilities, optional BFT
|
|
3. **One schema** per service — `.zap`, with a [complete toolchain](/docs/tools) on and off it
|
|
4. **Proven in production** — a real stack runs ZAP-only, with protobuf confined to four functions
|
|
|
|
If you control both ends of your wire, ZAP removes an entire layer of your stack. The [quick start](/docs/quick-start) takes five minutes.
|