Primal
Primal is the polished Nostr client that makes the network feel fast and familiar, but the important story is the infrastructure behind that smoothness: cache servers, custom feeds, Reads, Remote Login, wallet flows and media services all shape what the reader sees.
A polished client with its own infrastructure
Primal is one of the clearest examples of a Nostr client that tries to feel like a finished social product. A new reader does not meet it as a protocol demo. The web app opens into feeds, profiles, search, notifications, direct messages, long-form reads, media playback and wallet surfaces. The Android and iOS apps package the same promise into an app-store-native experience. That polish is the first thing most people notice.
The second thing to notice is more important: Primal gets that polish by running more than a plain relay connection. The public Primal Server repository describes caching, membership, discovery and media-caching services. The web app exposes a cache-service setting. The Android app has dedicated networking, caching, wallet, account, media upload and signer modules. Primal is a Nostr client, but it is also a service stack that makes Nostr data easier to search, rank, render and monetize.
That does not make Primal less legitimate. It makes the trust model more interesting. Nostr lets a user keep identity and signed events outside one app, while Primal makes those events feel usable at consumer speed. Readers should understand both sides at once. Primal can be the easiest way into Nostr, but the parts that feel easiest often depend on Primal-run infrastructure.
What the public products say
The official Primal site is JavaScript-rendered, but its product surface is visible through the live app, download page and store listings. Google Play lists Primal from PRIMAL SYSTEMS INC. in the Social category, with in-app purchases, 50K+ downloads, parental guidance, data encrypted in transit and an update date of June 4, 2026. The Play listing describes easy onboarding, fast rich feeds, a built-in bitcoin wallet and content discovery.
The App Store listing adds more shape. It describes next generation social media powered by Nostr and Bitcoin. It lists rich feeds with media playback, a built-in wallet, long-form articles, discovery, advanced search and Remote Login for authorizing activity in compatible Nostr apps. As of the June 12, 2026 lookup, the United States listing showed version 3.0.61, a May 9, 2026 update with wallet fixes, 911 ratings and a 4.90 average, plus earlier releases that added Blossom media, Nostr Wallet Connect, richer wallet transactions, Remote Login and feed video improvements.
Those store descriptions are useful because they show what Primal wants normal users to see: a fast social client with Bitcoin built in. The code shows how much has to happen underneath to make that possible. The web app, Android app and server are open enough for a careful reader to inspect the gap between product promise and system behavior.
The web app is a full social client
The web app repository describes Primal's web app for Nostr as experienced on primal.net. It is built with SolidJS, TypeScript and Sass, and the package file includes Nostr, Cashu, Stripe, Blossom, Markdown editor, video and media dependencies. The README says the app features easy onboarding, a fast interface, exploration of Nostr and custom-feed management. The public version checked in package.json was 3.0.101; GitHub metadata checked on June 12, 2026 showed 272 stars, 95 forks, 143 open issues and a latest default-branch commit labeled 3.0.101.
The router and page structure show a broad product. There are pages and contexts for home feeds, reads, long-form articles, a reads editor, direct messages, bookmarks, advanced search, notifications, media, settings, network, Blossom, Nostr Wallet Connect, membership, premium and account flows. That is why Primal cannot be treated as a simple timeline reader. It has enough surface to be a primary Nostr environment for many users.
The web app can also hold or connect signing capability. Its local signer code can generate a private key, read an nsec from storage, encrypt stored key material with a PIN and sign events through nostr-tools. Its NIP-46 code can generate an app keypair, create a nostrconnect URI, use `wss://nrs.primal.net`, store a bunker URL and proxy signing, encryption and decryption requests to a remote signer. Readers should treat those as account-security features, not as invisible login plumbing.
Android is more than a wrapper
The Android app is a native project, not a web view wrapper. The repository is Kotlin, Android Studio, Jetpack Compose and Kotlin Multiplatform oriented, with modules for account, wallet, Nostr domain models, networking, caching, media upload, notifications, signer behavior and Lightning-related functionality. The README sets Android 8.0+ as the target floor and notes that release builds require signing configuration, while debug builds skip some encryption behavior and run slower.
The checked Android build file listed applicationId `net.primal.android`, versionName `3.5.10` and versionCode 2707. GitHub metadata checked on June 12, 2026 showed 222 stars, 39 forks, 90 open issues and a latest commit titled `Primal 3.5.10 release` from June 3, 2026. The dependency set includes Compose, Room, SQLCipher, Hilt, DataStore, OkHttp, Retrofit, Coil, Media3, CameraX, QR code tooling, bitcoinj, biometric APIs, Firebase/Play Billing in the Google flavor, Lightning KMP and many internal modules. That is the footprint of a serious native app, not just a feed screen.
The Android manifest is especially revealing. It registers links for `https://primal.net`, profile and event paths, reads, home, explore, direct messages, bookmarks, premium and legends. It handles `nostrconnect`, `primalconnect`, `primal://signer`, `nostr+walletconnect`, `nostrwalletconnect`, `nostrnwc`, `nostrnwc+primal` and `nostrsigner`. It also exposes services for media session behavior, remote signing and NWC. On Android, Primal wants to be a client, a signer participant, a wallet-connect participant and a destination for shared media.
Feeds are shaped by cache and directives
Primal's feed experience feels fast because the client does not only ask relays for raw chronological events. Both web and server code revolve around cache-backed queries. The server README explains that Primal Server connects to specified relays, collects events in real time, stores them locally and exposes websocket-based APIs to clients. Example cache requests include network statistics, feeds, thread views, user information, events and profile data.
The web app search and feed code sends cache requests such as `user_search`, `search`, `advanced_search`, `advanced_feed`, `get_recommended_reads` and `scored`. The Android FeedRepository has a `feedBySpec` method and fetches feed page snapshots using a feed specification, event kinds, ordering, limits and paging. This architecture lets Primal build custom feeds, trending surfaces, recommendations and rich thread views with far less waiting than a client that only asks public relays directly.
The tradeoff is reader-facing. A cache can make Nostr usable and searchable, but it can also filter, score, omit or delay data according to its own logic. Primal exposes settings for relays and cache service, which is important. If you care about comparing raw relay behavior with Primal's view, inspect your network settings, try another cache service when available and compare a few events in other clients.
Relay settings are visible, but Primal remains opinionated
Primal gives users relay controls. The web network settings page lets a user see the connected cache service, set an alternate cache service, restore the default cache, view relays, remove relays, add custom relays, reset to recommended relays and choose whether to post a copy of content to Primal's priority relay. It also includes a proxy-through-Primal option with explanatory UI text.
This is a better design than hiding relay behavior entirely. A reader can see that Nostr is not one server and can make deliberate choices about where events go. At the same time, Primal's default experience is still opinionated. Suggested users, default feeds, spam and NSFW moderation scopes, cache-backed search, a primary relay option and Primal-hosted media or wallet services all push toward a coherent Primal view of the network.
That is the central balance of the product. Primal is valuable because it makes Nostr coherent. It should not be read as a neutral microscope over every relay. If you want raw protocol inspection, use additional tools. If you want an app that normal people can open and understand, Primal is one of the strongest attempts.
Discovery and search are core features
Primal's discovery work is not a side tab. The web app has dedicated search and advanced-search contexts that query users, content, notes, long-form reads, polls and filtered-user information. It can decode npubs, search profiles, score user results and page through content using advanced feed specifications. The Android app mirrors the same idea at the domain layer with feed repositories, profile repositories, reads repositories and cached page snapshots.
This matters because discovery is one of Nostr's hardest product problems. Public-key identity and relay choice make the network portable, but they do not automatically answer a new user's question: what should I read now? Primal answers with scored users, suggested profiles, custom feed definitions, trending scopes, topic surfaces, article recommendations and search indexes that are easier for a normal person to navigate.
The reader should treat these as helpful views rather than as complete truth. A search result can depend on indexed relays, cache freshness, spam filtering, scoring and event kinds. If something is missing, it may still exist elsewhere on Nostr. If something is prominent, that prominence may reflect Primal's ranking and cache behavior. That is not unusual for a social app, but Nostr readers should name it clearly.
Reads makes long-form Nostr visible
Primal's Reads surface is one of the product's most important contributions. Long-form Nostr events can exist without Primal, but Primal makes them feel like a readable publication layer. The web app has Reads pages, topic routes, article previews, a Reads sidebar, a Reads editor, draft handling and article publishing dialogs. The Android domain layer has an ArticleRepository for feeds, article comments, highlights, observing articles and deleting article records.
The web Reads editor builds kind 30023 long-form events with title, summary, image, `d` identifiers, topic tags, relay tags, client tags and references. It supports drafts, preview modes, article metadata, optional hero images, markdown content and post-publish promotion. This is not a toy editor bolted onto a timeline. It tries to make Nostr articles authorable and readable from inside the same app.
Readers should still understand the portability boundary. A Nostr article is a signed event with tags and content. Primal can render it beautifully, attach comments and highlights and make it discoverable. Other clients may render the same event differently or not at all. If you publish serious long-form work through Primal, test how it appears in at least one other Nostr reader and keep your own copy of the text.
Media is becoming a first-class layer
Primal's store history and source code show a strong investment in media. App Store release notes mention Blossom media, image gallery changes, animated GIF uploads, video-player upgrades, feed video handling and multi-file uploads. The web app has media and uploader components, the Android app includes Media3, image and video handling, a foreground media session service and upload modules.
The Blossom settings page in the web app shows the model clearly. Primal has a default media server at `https://blossom.primal.net`, lets a user switch to another HTTPS Blossom server, supports mirrors, checks server availability, restores the default server and displays recommended mirrors. The Android upload service computes file metadata, SHA-256 hash, MIME type and file size, signs a Nostr authorization event for upload, PUTs the file, then optionally mirrors it to configured servers.
This is important because Nostr relays do not solve file storage. Media is held by storage servers and referenced by signed events. Primal's Blossom work gives users a concrete path for images and video, but it also asks users to think about media retention, deletion, mirroring and server policy. A Primal post can remain discoverable even if the media URL later breaks, and a mirrored file can outlive the user's expectation of deletion.
Remote Login turns Primal into a signer surface
Primal's Remote Login is a NIP-46 signing flow. The App Store description says Primal can authorize activity in compatible Nostr apps using Remote Login. The web code creates nostrconnect URIs, uses a client pubkey and secret, subscribes over NIP-46 relay traffic, stores bunker URLs and forwards signing, public-key, NIP-04 and NIP-44 operations through a BunkerSigner. The Android code has a RemoteSignerClient and parser for connect, ping, sign_event, get_public_key, NIP-04 and NIP-44 operations.
That is a large security surface. A signer can be more protective than pasting an nsec into every website, but it still signs real events. The quality of the approval screen, permission model, session revocation and relay path matters. The Android manifest also declares `nostrsigner` handling and a remote signer foreground service, which means the app is meant to participate in native Android signing flows, not just web QR login.
For readers, the rule is simple: Remote Login is powerful because it makes other apps usable without handing them your key. It is risky when you stop reading what is being authorized. Use it with apps you recognize, inspect requested permissions when they are shown, revoke stale sessions and avoid using a high-value identity in experimental signing flows unless you are comfortable with the failure modes.
Wallet behavior is woven into the social app
Primal has a separate wallet identity in the ecosystem, but the social app itself contains wallet surfaces. Store listings foreground the built-in bitcoin wallet. The web Nostr Wallet Connect settings let a user connect external NWC wallets, save wallet labels, encrypt wallet URIs, activate a wallet and send NWC info events. The Android app handles NWC deep links, wallet-connect schemes, Primal wallet connections and wallet background services.
The Android wallet code is substantial. It includes NWC repositories, NWC connection creation, local storage of service keys and relays, auto-start preferences, daily budgets, pending NIP-47 events, wallet request logs, invoice records and payment holds. It can build `nostr+walletconnect://` strings using `wss://relay.primal.net`, include a Lightning address, notify missed NWC events and talk to Primal wallet APIs for connection creation and revocation.
This makes zaps and social payments feel natural. It also means the reader should not treat the wallet button as decoration. A connected wallet can authorize payments, create invoices, hold logs and shape what the app can do with money. Start with small balances, small zap defaults and clear budgets. If you want deeper custody analysis, read the separate Primal Wallet page and compare the wallet's backup and recovery story to your risk tolerance.
Premium and membership are part of the stack
Primal is not only an open client project. It also sells services. The web code includes membership and premium flows, Stripe dependencies, premium leaderboards, legends pages, membership purchase history, premium media stats, media management, membership recovery, content backup and content rebroadcasting verbs. The Android app includes Play Billing in the Google flavor and Primal wallet verbs for membership products, purchase monitoring and legend customization.
This is not strange. A polished social client needs ongoing infrastructure, and Primal's cache, media, search, wallet and membership services cost money to operate. The important reader question is what is free Nostr behavior, what is Primal service behavior and what is paid account behavior. A Nostr identity can outlive Primal, but premium features may depend on Primal-run servers and commercial terms.
Readers should distinguish portability from service entitlement. Your signed posts, profile data and follows are Nostr data. Your membership state, premium media quota, custom name, content backup tooling, rebroadcast status and wallet-service account features may be Primal service state. That distinction keeps expectations realistic if you later move clients or reduce dependence on Primal.
Moderation and safety are practical, not abstract
Primal includes content moderation settings and default moderation scopes. The web constants include spam and NSFW moderation names and scope choices for content and trending areas. The network and search code also exposes filtered-user lookup behavior and filtering reasons. This is a reminder that an open social protocol still needs client-side and service-side choices about what to show.
The store listings frame the same issue for mainstream users. Google Play flags user interaction and data safety details. The App Store age rating notes unrestricted web access, messaging and chat, user-generated content and mature-content categories. A Nostr client cannot promise a sanitized platform without becoming a gatekeeper. It can provide filters, reports, mute lists, relay choices and ranking choices.
The reader should make safety choices deliberately. Check muted words, muted threads, relay settings, content filters, DM expectations, image autoplay, wallet confirmations and login sessions. Primal's polish can make the app feel like a normal social network, but the underlying network is still a public-key event network where screenshots, relays, caches and third-party clients exist outside one company's moderation boundary.
What to test before making Primal your main client
First, test identity and signing. Create or import a low-risk account, post a note, delete or request deletion for a harmless note, sign in from the web app, sign in from Android if you use it and test Remote Login with a compatible app. Confirm you understand where your key lives, whether a PIN protects local storage and how to revoke remote sessions.
Second, test the network view. Add and remove a custom relay, compare a known note in Primal and another client, inspect whether content is being posted to Primal's priority relay, try an alternate cache service if you have one and search for the same user or event elsewhere. You are learning how much of your experience comes from relays and how much from Primal's cache.
Third, test money and media slowly. Connect an NWC wallet with a tiny budget, send a small zap, make and pay a small invoice if relevant, then check logs and wallet history. Upload a harmless image, inspect its Blossom URL, mirror settings and event rendering in another client. These tests take minutes and prevent the two most common surprises: money permissions that are too broad and media that travels farther than expected.
Who Primal is best for
Primal is best for readers who want Nostr to feel usable now. If you are coming from mainstream social apps, it gives you familiar navigation, rich feeds, search, profiles, media, notifications, articles and a wallet without asking you to understand every relay and NIP on day one. That matters. A protocol only grows when some clients make it feel humane.
It is also useful for builders because the public repositories show a real production approach to Nostr UX: SolidJS on the web, Kotlin and Compose on Android, a cache server, custom feeds, advanced search, Reads, Blossom, NIP-46, NWC, wallet services, membership services and app-store distribution. Studying Primal teaches more about productizing Nostr than reading a list of event kinds alone.
Primal is less ideal if you want a minimalist, raw-relay, no-service-dependency client. Its best qualities come from opinionated infrastructure. That is not a flaw when the reader understands it. Primal is the client for people who want speed, discovery and polish, with enough visible settings to stay aware of the relays, cache, signer, wallet and media services underneath.
Sources worth opening
The best reading path starts with Primal's live product pages and store listings, then checks the web app, Android app and Primal Server repositories, followed by the specific source files for cache settings, Remote Login, NWC, Blossom uploads, Reads, feeds, search, wallet behavior and the relevant Nostr specifications.
- Primal official site
- Primal downloads page
- Primal Android on Google Play
- Primal on the App Store
- Primal web app repository
- Primal web app README
- Primal web app package file
- Primal web app 3.0.101 commit
- Primal web app router
- Primal web app constants
- Primal local signer code
- Primal NIP-46 web signer code
- Primal web NIP-46 implementation
- Primal web NWC settings
- Primal web network settings
- Primal web Blossom settings
- Primal web search library
- Primal web advanced search context
- Primal web Reads page
- Primal web Reads editor
- Primal web upload socket
- Primal Android repository
- Primal Android README
- Primal Android build file
- Primal Android 3.5.10 release commit
- Primal Android manifest
- Primal Android Blossom upload service
- Primal Android remote signer client
- Primal Android remote signer parser
- Primal Android NIP-47 event handler interface
- Primal Android NIP-47 event handler implementation
- Primal Android NWC repository implementation
- Primal Android Primal Wallet NWC repository
- Primal Android wallet operation verbs
- Primal Android Primal wallet verbs
- Primal Android feed repository
- Primal Android article repository
- Primal Server repository
- Primal Server README
- Nostr NIPs repository
- NIP-46 Nostr remote signing
- NIP-47 Nostr Wallet Connect
- NIP-57 Lightning zaps
- NIP-65 relay list metadata
- NIP-92 media attachments
- NIP-94 file metadata
- Blossom specification repository
- NostrApps listing for Primal





