Phoenix
Phoenix is the web client you open when you want Nostr to feel less like a protocol demo and more like a real social app, while still keeping the raw Nostr questions close enough to inspect.
A familiar room with Snort in the walls
Phoenix is easy to misunderstand if you only see the little directory tagline. NostrApps compresses it into the phrase "Make Nostr sexy", and that is memorable, but it is also too small for what is actually sitting behind the door. Phoenix is not a cute wrapper around one timeline. It is the Phoenix face of Snort, a long-running Nostr web client whose GitHub repository describes the project as a "Feature packed nostr web UI" and whose public homepage now points at `phoenix.social`.
That Snort lineage matters because it tells you what kind of app you are looking at. Phoenix is not trying to be a single-purpose tool like a signer, a relay monitor or a publishing helper. It is a full social client. You can read a feed, follow people, open profiles, inspect events, search, receive notifications, send messages, browse media, manage relays, use a wallet, work through onboarding and handle Nostr links. The app wants to be a room you can actually stay in.
The familiar surface is the point. A lot of Nostr software asks the reader to fall in love with architecture before the first useful action. Phoenix goes the other way. It gives you a web social client with recognizable affordances first: tabs, profiles, posts, messages, search, notifications and settings. Then, if you look one layer lower, the Nostr questions are still there. Which key is signing? Which relays are used? Which app tag is attached to the event? What happens to media? Can another client read the result?
That makes Phoenix a good test of a very practical Nostr idea: a client can feel like ordinary software without becoming a closed account silo. If you only want to scroll, Phoenix will let you scroll. If you want to understand the stack, it gives you enough clues to keep asking better questions.
Phoenix is a brand and a configuration
The repo is still called `v0l/snort`. The release assets still carry Snort names. The documentation is still the Snort documentation. Phoenix appears in the code as a configuration file, and that is not a weakness. It is actually one of the more honest things about the project. The file `packages/app/config/phoenix.json` sets `appName` to Phoenix, `appTitle` to `Phoenix - Nostr`, `hostname` to `phoenix.social`, `nip05Domain` to `phoenix.social`, and the public directory to `public/phoenix`. It also gives Phoenix its own icon and default relay mix.
That is how mature web clients often work. The product name you see in the browser can be a configured deployment of a larger codebase. Phoenix therefore should not be read as a separate code universe from Snort. It is a Snort deployment with Phoenix identity, Phoenix default relays and Phoenix product framing.
The default relays are not hidden in a slogan. The Phoenix config names `wss://relay.phoenix.social/` as read and write, adds `wss://relay.damus.io/` and `wss://nos.lol/` as read/write relays, and keeps `wss://nostr.wine/` as read-only. If you are new to Nostr, this is where the social product becomes infrastructure. Your feed is not pulled from one company database. It is assembled through relays, and those relay choices affect discovery, latency, redundancy and what your client can see.
Phoenix also enables Nostr addresses and push notifications in the config, while disabling the Snort subscription, deck, zap pool and community-leader features. That gives the deployment a personality. It is not the maximal Snort switchboard. It is a public-facing social client tuned around a familiar root feed, Nostr identity, notifications and approachable use.
What you can actually do there
The route table tells a better story than any marketing paragraph. Phoenix has root tabs for following, for-you, followed-by-friends, conversations, discover, trending notes, trending hashtags, topics, media, follow sets and relay feeds. It has profile pages under `/p/:id`, event and thread pages under `/e/:id`, notifications, search, list feeds, messages, wallet pages, onboarding and settings. A catch-all route handles Nostr links, so the client can receive a bech32 entity and decide how to render it.
As a reader, that means Phoenix is built for more than the short-note feed. The v0.4.0 release added a discover page with DVM-powered trending posts and content suggestions, support for media note kinds 20, 21 and 22, a dedicated media tab, follow sets, Nests audio rooms, NIP-119 compatibility, auto-translate behavior and table rendering in markdown. Those are not random features thrown at a wall. They show a client trying to keep up with Nostr as it expands beyond "Twitter clone" habits.
The note composer and event handling sit inside a stack that knows about profiles, follows, metadata, reactions, reposts, zaps, long-form content, lists, file metadata, application handlers, data vending machines and wallet flows. The README lists a broad NIP surface, including NIP-07, NIP-23, NIP-46, NIP-47, NIP-50, NIP-53, NIP-55, NIP-65, NIP-78, NIP-89, NIP-90, NIP-94, NIP-96 and NIP-98. You should not read that list as a promise that every corner is equally polished. You should read it as a map of the product's ambition: Phoenix wants the ordinary social screen to be connected to a lot of the wider protocol.
The interesting part is how this feels when you use it. A normal user sees tabs and posts. A Nostr-aware user sees event kinds, relay choices, NIP-05 handles, profile loaders, app-specific data, client tags and wallet connections. Phoenix tries to serve both without forcing the beginner to read specifications before posting a note.
Login is where the web client gets serious
Every Nostr web client has a trust problem. If the browser app holds your private key, the browser app can sign as you. If you paste an `nsec` into every attractive client you test, the number of places that can lose your identity grows with your curiosity. Phoenix does not make that problem vanish, but the code shows a serious attempt to support several login styles rather than pretending one method fits every person.
The login store has session types for private key login, public-key read-only mode, NIP-07 browser signers, NIP-46 remote signers, `nostr_os`, and NIP-55 Android signer support. In `createPublisher`, the app chooses an event publisher based on the session. A private-key session signs locally. A NIP-07 session uses `Nip7Signer`. A NIP-55 session uses `Nip55Signer`. A NIP-46 session builds a `Nip46Signer` from a `bunker://` URL and opens an OAuth-style popup if the signer emits an `oauth` event. A `nostr_os` session uses the local `window.nostr_os` interface.
The account store is also multi-account. It saves sessions in local storage, tracks the active account, restores encrypted key storage payloads, rebuilds user state and initializes app data with preferences. New private-key sessions can be created from BIP39-generated entropy. The onboarding path broadcasts a new contact list, a relay list metadata event and a profile metadata event to the configured relays. In Nostr terms, that means Phoenix does not only create a key; it tries to give the new key enough social and relay context to be usable.
There is a blunt caution here. Phoenix is a web client, and a web client that stores or uses signing material is still part of your attack surface. If you already have a strong signer setup, use it. If you are just exploring, do not paste a valuable key into any web app casually. But compared with a naive "paste key, hope" client, Phoenix has a more complete sign-in story: read-only public key mode, browser signing, remote signing through NIP-46, Android signer support and local multi-account state.
Relays, cache and the feed under the floor
The first thing Phoenix does at startup is set its client tag through NIP-89. The code assigns `EventBuilder.ClientTag` to a tag with the configured app name and a kind 31990 app-profile address. That means Phoenix can mark events as being published through Phoenix. NIP-89 says client tags have privacy implications and clients should let users opt out, so this is not a trivial badge. It is provenance, but it is also a small trail of app usage.
Phoenix then initializes the WASM and relay worker path when available, preloads follows, asks the Snort system to preload the social graph, adds cached profile metadata to fuzzy search, and deletes older local relay data for selected event kinds after thirty days. Under the visible feed, the app is doing the dull but important work of cache, query and profile management.
The Snort docs explain the underlying library set as a TypeScript suite for Nostr applications. `@snort/system` is the Nostr protocol implementation with relay management, querying and caching. `@snort/system-react` provides React hooks and components. `@snort/shared` handles shared utilities. `@snort/wallet` handles Lightning wallet integration. `@snort/worker-relay` is a browser-worker relay built on `sqlite-wasm`, so local event handling can behave like a relay-backed cache rather than a loose pile of arrays.
That architecture is why Phoenix feels bigger than its tagline. It is a monorepo built with Bun. The root build script compiles the shared, system, system-react, wallet, worker-relay, bun-sqlite-relay and app packages. The app package itself uses TypeScript, React 19, Vite 7, React Router, Workbox, zod, noble cryptography packages, Blossom, LiveKit, charts, markdown parsing and a long list of supporting libraries. That does not automatically make it good. It does mean the project has moved beyond a small hobby page into an ecosystem client with real moving parts.
The relay model underneath is NIP-65-aware. NIP-65 defines the `kind:10002` relay list metadata event so clients can advertise where a user generally writes and where they read mentions. Phoenix writes relay metadata during onboarding, uses configured default relays, and keeps the outbox/relay problem close to the user settings. That is the part of Nostr many casual reviews miss: a beautiful feed is only as useful as the relay graph that feeds it.
Media, live rooms and the wallet edge
The v0.4.0 release is the best place to understand how Phoenix has grown past plain text notes. It added media note support for kinds 20, 21 and 22, created a media tab, added Nests audio room integration and replaced NIP-96 uploads with Blossom. That last change is important. NIP-96 describes HTTP file storage integration for Nostr, while Blossom uses HTTP servers and signed authorization flows around blobs. In the Phoenix code, the Blossom helper signs upload, mirror, list, delete and report actions through the active Nostr publisher.
This matters for a reader because media is where Nostr stops feeling abstract. Text notes are tiny. Photos, videos and other files need somewhere to live. Phoenix can publish social events that reference media, but the file itself is not magically stored by every Nostr relay. Blossom gives the client a path for authenticated blob storage, while Nostr events carry the social and metadata layer around it.
The wallet edge is similar. Phoenix is not trying to be your Lightning node. It includes wallet support through `@snort/wallet`, including Nostr Wallet Connect. The settings page accepts a NWC config string, and the `NostrConnectWallet` class parses `nostrwalletconnect://` and `nostr+walletconnect://` URIs, connects to the relay named by the wallet connection, requests wallet info, and sends encrypted commands for methods such as `get_info`, `pay_invoice`, `get_balance`, `make_invoice` and `list_transactions` when supported.
NIP-47 frames Nostr Wallet Connect as a way for a client to access a remote Lightning wallet through a standard protocol without using the user's main identity key for payment activity. Phoenix follows that shape. The wallet connection uses request events, response events and encrypted payloads; the user still needs a wallet service that supports the method. That distinction matters. Phoenix can make zaps and payments feel closer to the social screen, but it is not the custodian of your Lightning funds simply because a wallet tab exists.
Nests gives another clue about Phoenix's ambition. Social apps are not only feeds. People gather in rooms, listen, talk, publish media, tip each other and carry identities across contexts. Phoenix is not perfect at all of that, but the feature trail shows a client trying to make those Nostr edges reachable from one place.
The security release you should not skip
If you read only one release note, read v0.5.0. It is not glamorous, and that is exactly why it matters. The headline items are security hardening, performance work and stability fixes. The release says the project fixed real Schnorr signature verification, NIP-46 forged relay message protection, NIP-46 secret leakage issues, PIN encryption problems, dangerous JSON parsing, hanging promises and lifecycle or timer leaks. It also removed unverified NIP-26 delegation trust from root-pubkey handling.
That is the kind of release that changes how you evaluate a Nostr client. A pretty social interface is not enough when the app signs events, parses untrusted data from relays and may talk to remote signers and wallets. The fact that these issues were found and fixed does not make Phoenix magically risk-free. It does make the project trail more credible than a client that never seems to mention security except as a slogan.
The performance side also matters for daily use. v0.5.0 introduced batched Schnorr verification in WASM, lazy-loaded routes, pre-compiled translations and worker-relay batch optimizations. A Nostr web client can drown itself in events if it is sloppy. Verification, profile loading, query behavior and render loops are not background trivia. They are the difference between a client that feels alive and one that teaches people to give up on Nostr.
The latest visible release, v0.5.3, came on April 8, 2026 and fixed an infinite loop in the NIP-05 component. Its downloadable Android assets still use Snort file names, such as `snort-arm64-v8a-v0.5.3.apk` and `snort-universal-v0.5.3.apk`. That is another reminder that Phoenix is a product face on the Snort codebase, not a separate history.
Who is behind it and how alive it looks
The public builder trail points to GitHub user `v0l` and the `v0l/snort` repository. The MIT License file names Kieran (v0l) as copyright holder. The maintainers file lists two Nostr public keys, including one beginning `npub1v0l`, and relay hints for the project such as `wss://relay.snort.social/`, `wss://pyramid.fiatjaf.com/`, `wss://nos.lol/` and an onion relay. That is the public source trail this page can verify without inventing a company story.
As checked during this rewrite, the GitHub repository was created on December 18, 2022, was pushed on May 29, 2026, and showed activity updated on June 4, 2026. It had 339 stars, 132 forks and 6 open issues through the GitHub API, with TypeScript as the primary language, MIT License metadata, topics for `nostr` and `react`, and `main` as the default branch. Those numbers will change, but the pattern is what matters: Phoenix/Snort is not an abandoned directory listing. It has a multi-year code trail, recent releases and real maintenance work.
The project also has documentation at `docs.snort.social`, and the docs describe Snort as a suite of TypeScript libraries powering Snort and other Nostr applications. That is worth noticing because it makes Phoenix part of a broader tooling story. The app is not only a consumer of Nostr libraries; it is built by the same project that exposes the underlying pieces other builders can use.
There is still a practical caveat. A living repository is not the same as a guarantee. You should check the current release, current issues, current build artifacts and current security notes before trusting any client with a key. Phoenix gives you a better public trail than many apps, but your key does not care about good vibes. It cares where it is exposed.
How to read Phoenix like a user
The right way to try Phoenix is to separate pleasure from trust. Pleasure first: does the feed feel readable, does search work for you, do profiles open cleanly, do notifications make sense, do messages fit your habits, do media and follows behave naturally? If the app fails there, the protocol story will not rescue it. Social software has to feel like a place.
Then trust: how are you signing? If you are using a low-value test key, local private-key login may be fine for exploration. If this is your real public identity, prefer NIP-07, NIP-46 or a stronger signer path where possible. If you connect a wallet, understand that Nostr Wallet Connect is a permissioned bridge to a wallet service, not a magic payment shield. If you upload media, remember that media lives on storage infrastructure and is referenced by Nostr events.
Finally, portability: post something small, open it in another client, inspect the event if you know how, and see what traveled. Do the profile details, media references, follows, zaps or client tags make sense outside Phoenix? That is the quiet superpower Nostr is supposed to give you. Not that every app looks the same, but that your identity and events are not trapped inside one app's database.
Phoenix earns attention because it tries to be friendly without being shallow. It has the familiar social-room feel that helps people start, and it has enough visible protocol depth for people who want to grow past the first feed. That is a rare balance. You can enjoy it as a web client, but you should judge it as Nostr software: by keys, relays, signers, media paths, wallet boundaries, release hygiene and whether your actions survive beyond the app that made them pleasant.
Sources worth opening
This rewrite keeps the product claims close to the public project trail: the Phoenix deployment, the Snort repository, Snort docs, release notes, implementation files and the NIPs that explain the protocol pieces Phoenix touches.
- Phoenix live site
- v0l/snort GitHub repository
- Snort TypeScript library documentation
- Phoenix on NostrApps
- Phoenix configuration file
- Snort monorepo package file
- Snort app package file
- Phoenix/Snort app startup and routes
- Root tab routes
- Login and publisher functions
- Login session types
- Multi-account store
- nostr_os signer bridge
- Blossom upload helper
- Nostr Wallet Connect settings page
- NostrConnectWallet implementation
- Worker relay README
- Maintainers file
- MIT License
- Snort v0.5.3 release
- Snort v0.5.0 security release
- Snort v0.4.0 feature release
- NIP-07 browser signing
- NIP-46 remote signing
- NIP-47 Nostr Wallet Connect
- NIP-55 Android signer application
- NIP-65 relay list metadata
- NIP-78 custom app data
- NIP-89 app handlers and client tags





