# Roadmap

zig-nostr is a protocol library in Zig, the native apps that prove it on real
product surfaces, and the docs around both. This is what has shipped, and what comes next.

No dates.

## Shipped

- **Library core**: secp256k1 keys and BIP-340 Schnorr signatures (bitcoin-core's
libsecp256k1), the NIP-01 event model, NIP-19/21 encoding, NIP-06 derivation, and NIP-49
key storage. Passes the full official BIP-340 test-vector suite.
- **Transport and outbox**: RFC 6455 WebSocket, a relay connection state machine with NIP-01
subscriptions, a live TCP/TLS dialer, and NIP-65 relay lists (kind 10002), the routing people
call the outbox model, with zero hardcoded relays.
- **Local-first store**: a zero-copy, memory-mapped LMDB event store with a bounded,
newest-first planner for NIP-01 filters. [Sub-millisecond feeds](/performance) that stay
flat as the store grows.
- **Signer protocol**: NIP-44 v2 encryption, the NIP-46 remote-signing ("bunker") protocol
over kind 24133, and NIP-42 client authentication.
- **Windows, search and fuzzing in the library**: it builds for macOS, Linux and Windows, on
x86_64 and aarch64, with CI that builds and tests on all three. The filter carries the NIP-50
`search` field, which the local store applies too. The parsers that read bytes someone else
wrote have fuzz targets, and the two crashes the first run found are fixed.
- **[Notary](/notary)**, the native remote signer. Your key lives in a local daemon, it hands
you a `bunker://` URL, and nothing gets signed quietly. A downloadable app for
macOS and Linux. On macOS it stays in the menu bar and shows its window only when a request
needs a decision.
- **[deed](/deed)**, the fastest and smallest nostr command line: keys, events, NIP-19 codes, NIP-44, relay queries
and publishing, and a local store that later runs read without a network. It builds for
macOS, Linux and Windows.
- **[Plaza](/plaza)**, the flagship client. Browse as a guest, sign in three ways (including a NIP-46 bunker), and read a follow feed (your kind 3 list) that renders from disk before the network answers. Reposts from people you follow appear in it, hashtags open a page of their notes, and relay hints are carried in the addresses it copies and the replies, quotes, reposts and likes it publishes. A long-form article (NIP-23) opens in a reader. Search finds people by name, from the profiles on your machine first and then from three NIP-50 search relays. A picture can be added from a file to a note, an avatar or a banner, and uploads go to a Blossom server from your list. A note marked sensitive (NIP-36) is covered until you press Show, and the composer can add a content warning. A relay that asks who you are (NIP-42) is answered once you allow it, per relay and per account. Every profile field is editable, deleting your own note is there, and something Plaza cannot draw shows a card naming its kind.
- **Places**: a link opens somebody's corner of Nostr, their relays and what they serve, and
while you are in one you see it rather than your own feed. Visit, enter to keep it on a
rail, or leave. A community can carry several feeds and switch between them, and one that
states a colour is drawn in it. The format is fiatjaf's
Hallway universe object, and the field names are his exactly, so a document written for
one is read the same way by the other.
- **Docs and benchmarks**: this site, the [NIP-support table](/nips), and reproducible
[performance numbers](/performance).
- **Reach**: following somebody means seeing them. Plaza reads the NIP-65 relay lists (kind
10002) of the people you follow, works out which relays reach the most of them, connects to
the ones you are not already on, and asks each relay only about the people who write there.
Anybody no chosen relay carries is asked of your own relays, so nobody falls through. What
you post goes where your own list says it should, and scrolling past what is on disk asks
the relays for older notes.

## What comes next

### The library from other languages

A C ABI over the library: keys, events, NIP-19, NIP-44, relay reads and the local store, with a C header. On top of it, Swift bindings published as a Swift package. The C ABI and the Swift package are both tested in CI.

### Notary on Windows

Notary packaged for Windows, so the library, deed and Notary are each tested in CI on Windows, macOS and Linux.

### deed for agents

`deed mcp` serves deed's verbs over the Model Context Protocol, so an agent can read relays, query the local store and verify events. Anything that signs goes through a NIP-46 signer that asks first.

### An app engine

I am extracting the non-visual parts of Plaza into an engine. That is sync (subscriptions, filling the local store, paging back), relay and outbox routing, and signer sessions, both embedded and remote NIP-46. It also holds a cache for profiles, follow lists and relay lists, and content parsing that turns a note into structured data: mentions, hashtags, links, media and nostr: references.

The engine has no views and no UI templates. An app receives data and draws its own interface. Plaza moves onto the engine, and each part gets a guide on this site.

### More apps, and Plaza 1.0

New small apps on the engine, each with its own interface, unlike Plaza's. And Plaza 1.0.

### Android

A proof of concept that uses the library through the C ABI to read a feed into a local store on a phone. It is a proof of concept, not a store release.

### Everything you do on the first day

Zaps you can send, not only verify. Plaza shows the receipts of other people's zaps, and sending one is not built.

### An app worth leaving open

Nothing Plaza knows leaves the window today: no notification reaches you, and once the people
you follow run dry there is nothing else to read.

Notifications at the level of the system, which a native app holding live relay connections
can do with no server in the middle. Feeds with more than one shape: a single
relay, a saved relay set, follow packs as real events rather than a hardcoded list. A store
you can see and reclaim, because Plaza keeps everything it has ever ingested and gives you no
way to see how large that has grown. Muting a word, a hashtag or a thread, and for an
afternoon rather than forever. An update path, so people who installed are not stranded on
whatever version they downloaded. Keyboard operation of what Tab does not yet reach, a light theme, and type that
scales.

Places go further: the entered list as an encrypted event so it follows you between
machines, notifications labelled with which place they came from, a way to find a place that
is not somebody handing you a link, and a publishing path the two clients share rather than
a document somebody has to republish by hand. A place link does nothing on a machine without
Plaza, so getplaza.social will resolve the same address in a browser.

And a NIP-47 wallet connection, with an approval surface in Notary so a payment is something
you agree to rather than something that happens.

### What the local store was for

Everything Plaza does reads from a database on your own disk, and the only thing it can search there today is people. Finding a note you read some time ago, by words you remember, with the network off, is the thing a client without a local store cannot offer.

Private messages: NIP-17, gift wrapped per NIP-59 (a kind 13 seal inside a kind 1059 wrap),
on the local store, signing through Notary, published only to the recipient's kind 10050 DM
relays. The seal's conversation key derives from the identity key, so the signer has to do the
NIP-44 work; Notary and the library already do, and it is Plaza's own NIP-46 client that has to
learn to ask for it.

NIP-71 video that actually plays, which in a renderer with no browser means platform
decode and compositing rather than an embed. And NIP-60 wallets with NIP-61 nutzaps, Cashu
ecash sent to a pubkey: a Lightning zap needs an LNURL provider the recipient signed up for
in advance, and an account four clicks old has none, so this is what makes a new person
payable at all.

### Groups, other machines, and the library at 1.0

Groups: NIP-29, on relays that support it. Every event carries an `h` tag with the group id,
joining is a kind 9021 request, and the relay hosting the group is the authority on who is in
it. Gated on what a relay declares in its NIP-11 document.

Other platforms. Linux ships, for x86_64 and aarch64, with the same one-line installer macOS
has. Off macOS the toolkit renders through a software rasteriser with no platform text
provider, so Plaza draws every glyph itself and carries its own colour emoji face; the two
renderer gaps that made that unusable are fixed and filed upstream. What is still open there
is coverage: the bundled faces carry Latin and Cyrillic, so every other script, Greek
included, is drawn as a solid block until a broader face ships. Shaping is a second problem
behind it: the reference rasteriser reads no GSUB or GPOS, so Arabic and the Indic scripts
would still be wrong with a perfect face. Windows is covered by the library and by deed, which
build there and are tested in CI. Notary for Windows is listed above. Plaza is not packaged for Windows.

And the library at 1.0. It has been pre-1.0 on purpose while the API moved underneath it.
Everything above lands there first, so by the time the rest of this is done the parts worth
freezing have stopped moving.

## What this deliberately does not do

Naming these is half of a roadmap, because each looks obviously worth doing until
you price it.

- **Multi-account.** It taxes every feature after it: per-account stores, relay pools,
notification state, and switching without a reconnect storm. A read-only "view as" answers
most of the real demand.
- **Set-reconciliation sync (NIP-77) in Plaza.** The library and deed already sync with it. In Plaza, relay support is thin and the protocol is easy to get subtly wrong, and per-relay cursors capture most of the benefit against a store that already answers a feed query in under a millisecond.
- **A proof of work difficulty slider (NIP-13) in Plaza.** The library mines, and deed's `event --pow` uses it. Reading proof of work is cheap: count the leading zero bits of the event id and honour the target committed in the `nonce` tag. A slider is not, and none of the mainstream relays I checked ask for any difficulty, so the setting would buy background mining, a cancel path and per-kind policy for nothing. Mining when a relay actually asks, through `min_pow_difficulty` in its NIP-11 document or an `OK` rejection that starts `pow:`, needs no setting at all.
- **NIP-96 HTTP file storage.** Supporting both upload paths looks like broader
compatibility. NIP-96 carries an `unrecommended` banner in its own spec and the NIPs index
strikes it through as replaced by Blossom, so uploads go to Blossom and nowhere
else.
- **Web-of-trust distance filtering.** Computed over a store that holds only what you
happened to sync, the graph is wrong in a way that changes between launches, so the same
reply appears and disappears for reasons nobody can explain.
