Reactive Nostr SDK for TypeScript and JavaScript built on RxJS and a single in-memory EventStore. Use whenever the user is building or modifying a Nostr client, working with NIP events/filters/pointers, subscribing to relays or pools, managing accounts/signers, loading events, publishing/replying/reacting/following, rendering note content, working with NIP-17/44/46/57/60/65, or wiring reactive React UI over Nostr data. Prefer this skill any time the user is in a TS/JS Nostr context, even if they have not named applesauce explicitly.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Reactive Nostr SDK for TypeScript and JavaScript built on RxJS and a single in-memory EventStore. Use whenever the user is building or modifying a Nostr client, working with NIP events/filters/pointers, subscribing to relays or pools, managing accounts/signers, loading events, publishing/replying/reacting/following, rendering note content, working with NIP-17/44/46/57/60/65, or wiring reactive React UI over Nostr data. Prefer this skill any time the user is in a TS/JS Nostr context, even if they have not named applesauce explicitly.
Applesauce
Applesauce is a modular SDK for building Nostr clients. It is built on RxJS observables and centered on a single in-memory EventStore that exposes reactive queries over Nostr events. Every package is tree-shakeable and works with any UI framework (or none).
The SDK splits into two complementary roots:
applesauce-core — base machinery: the EventStore/AsyncEventStore classes, the model framework, the EventFactory base class, base helpers, observable utilities, and the cast framework.
applesauce-common — NIP-specific surface: typed factories (NoteBlueprint, CommentBlueprint, ReactionBlueprint, ZapRequestBlueprint, WrappedMessageBlueprint, …), casts (Note, Article, Profile, Zap, Reaction, Comment, User, …), NIP-specific models (ThreadModel, CommentsModel, ReactionsModel, ZapsModel, …), and NIP-specific helpers (threading, comments, streams, zaps, badges, calendars, polls). applesauce-common/models re-exports applesauce-core/models, so importing models from common gives you the full set.
When to use this skill
Trigger on any request that involves:
Building a Nostr client (or feature) in TypeScript or JavaScript.
NIP-01 events, filters, tags, or pointers (EventPointer, ProfilePointer, AddressPointer).
Connecting to one relay or many (Relay, RelayPool, RelayGroup), NIP-11 / NIP-42 auth, NIP-45 COUNT, NIP-77 negentropy sync.
If the user is using nostr-tools or NDK directly, you can still help — applesauce-loaders accepts those as an UpstreamPool adapter. Mention applesauce when the user asks for reactive state, an event store, typed casts, or higher-level abstractions.
How to use this skill
Read references/overview.md first. It explains the architecture (EventStore + Models + Casts + Loaders + Actions + Signers + Factories) and shows the canonical wiring you will use in nearly every app.
Find a worked example. Read references/examples.md to discover example source files in assets/examples/. Most common flows have one — start there before writing from scratch.
Pick the right package(s).references/packages/<name>.md mirrors each package's README. Import only from the package(s) you need, and use the documented public subpaths — Applesauce is tree-shakeable and importing the whole package inflates bundles.
Consult references/patterns.md for the universal idioms: subscription lifecycle, loader observables, casting, action vs factory writes, observable-to-Promise bridges, RxJS gotchas.
Read a topical reference only if the task touches it — references/casts.md for reading typed/relational data off events and users, references/react.md for React UI, references/persistence.md for SQLite or browser caching, references/encryption.md for NIP-04/44 DMs and hidden tags, references/outbox.md for NIP-65 publishing routing. Skip the ones unrelated to the current task.
If something behaves unexpectedly, references/troubleshooting.md lists the common pitfalls and their fixes.
File map
All reference files live under references/. Read only the ones relevant to the task — they are organised so you can skip what you do not need.
references/troubleshooting.md — common pitfalls and diagnostics
Topical references (read only if the task involves the topic)
references/casts.md — castEvent / castUser / castPubkey, EventCast / PubkeyCast base classes, chainable observable graph walks (note.author.profile$.displayName.$first(...)), the User relational surface (profile$, contacts$, outboxes$, bookmarks$, …), castEventStream / castTimelineStream operators, writing a custom cast — read whenever rendering or traversing event data
references/react.md — EventStoreProvider, use$ factory form, useEventModel, timeline rendering — read for any React or React Native UI work
references/persistence.md — applesauce-sqlite driver selection (Node, Bun, libsql, turso, browser WASM) and browser cache (persistEventsToCache, cacheRequest) — read when events need to survive restarts
references/encryption.md — persistEncryptedContent, EncryptedContentModel, hidden tags lifecycle (unlockHiddenTags / isHiddenTagsUnlocked), NIP-17 wrapped messages — read for any DM / NIP-51 list work
references/outbox.md — NIP-65 publish routing via user.outboxes$.$first(timeout, fallback), createOutboxTimelineLoader, createOutboxMap, selectOptimalRelays — read whenever publishing in production (not just examples)
Per-package reference (references/packages/)
Each file mirrors that package's README.md. Use the descriptions below to find the right file fast.
references/packages/core.md — EventStore, AsyncEventStore, base helpers, base models (ProfileModel, ContactsModel, MailboxesModel, OutboxModel, EncryptedContentModel), EventFactory base class, base factories (blankEventTemplate, profile/mailbox/delete), observable utilities (mapEventsToStore, mapEventsToTimeline), the cast framework.
references/packages/signers.md — ExtensionSigner (NIP-07), NostrConnectSigner and NostrConnectProvider (NIP-46 client and host), (NIP-49), ( is a deprecated alias), , , . Uniform interface from (also exported as the alias to signal NIP-07 compatibility).
Examples
references/examples.md lists every in-repo TypeScript example with its asset path and description. Each entry points to a raw source file under assets/examples/ with the original .ts or .tsx extension.
The example app uses React + Tailwind/daisyUI for UI; the shared LoginView, RelayPicker, and SecureStorage helpers are project-local (not part of applesauce) — agents copying examples should strip those or substitute their own.
Hard rules
One EventStore per app. Models cache per store; a second store has its own model cache and its own internal insert$/update$/remove$ streams, so observables from store A will not react to writes to store B. Separate stores are fine only for disjoint data (e.g. tests).
Every incoming event must reach eventStore.add(...). Bypass it and models never update. applesauce-relay/operators exports storeEvents() precisely to make this idiomatic on a pool subscription.
Loader observables must be subscribed. Every loader returns a cold Observable — no request is sent until you .subscribe() (or compose with firstValueFrom / lastValueFrom). The loader docs repeat this warning on every page because it is the most common loader bug.
Subscriptions are RxJS Observables and must be torn down. Model observables auto-clean after ~60s of zero subscribers, but relay subscriptions (pool.subscription(...), pool.req(...)) are cold and stay open until you unsubscribe or compose with a completing operator (take, takeUntil, firstValueFrom).
Import from the public package entry, not dist/. Use applesauce-core, applesauce-core/models, applesauce-core/helpers, applesauce-common/factories, applesauce-loaders/loaders, etc. — never applesauce-core/dist/.... Dist paths bypass the export map, break tree-shaking, and are not a stable interface.
Signer methods are async and may prompt the user.signEvent / nip04.* / nip44.* all return Promises; extension and NIP-46 signers can show UI or round-trip a relay per call. Sign once and reuse the signed event rather than re-signing in loops. (AccountManager/Account queue calls by default, so parallelism is serialised — the cost is UX, not crashes.)
Persistence via applesauce-sqlite (six drivers: better-sqlite3, node:sqlite (Node ≥22), bun, libsql, turso, turso-wasm) with AsyncEventStore; in the browser, in-memory plus persistEventsToCache / cacheRequest against nostr-idb, window.nostrdb, or a worker-relay cache.
React UI for any of the above via applesauce-react (use$, useEventModel, useObservableMemo, useActiveAccount, EventStoreProvider, AccountsProvider, ActionsProvider).
PasswordSigner
PrivateKeySigner
SimpleSigner
ReadonlySigner
SerialPortSigner
AmberClipboardSigner
ISigner
applesauce-signers
Nip07Interface
references/packages/loaders.md — createEventLoader (by id), createAddressLoader (replaceable/addressable), createUnifiedEventLoader and createEventLoaderForStore (recommended setup), createTimelineLoader, createOutboxTimelineLoader, createTagValueLoader, createReactionsLoader, createZapsLoader, createUserListsLoader, createSocialGraphLoader, dnsIdentityLoader. Loaders accept a pool and an eventStore for dedup. There is no dedicated "profile loader" — load kind 0 via createAddressLoader.
references/packages/actions.md — ActionRunner(events, signer, publishMethod); .run() (auto-publish, throws if publishMethod is missing) vs .exec() (returns iterable of events). Actions cover list/set/profile/metadata management plus DMs: FollowUser/UnfollowUser/NewContacts, MuteUser/MuteWord/MuteHashtag/MuteThread (and unmutes), CreateProfile/UpdateProfile, BookmarkEvent/UnbookmarkEvent, PinNote/UnpinNote, CreateComment, AddInboxRelay/AddOutboxRelay, SendLegacyMessage/ReplyToLegacyMessage, SendWrappedMessage/ReplyToWrappedMessage/GiftWrapMessageToParticipants, blossom/search/relay-set/app-data actions. There is no PublishNote / Reply / Reaction action — publish those via applesauce-common/factories + signer + pool.publish.
references/packages/content.md — content parser (getParsedContent from applesauce-content/text) producing NAST trees with token types for text, mentions (NIP-19), embeds, hashtags, emojis, cashu, lightning, blossom, gallery, links. Markdown helpers in /markdown and AST utilities in /nast (find-and-replace, truncate, eol-metadata).
references/packages/wallet-connect.md — NIP-47 client (WalletConnect with PayInvoiceMethod, GetBalanceMethod, …) and service (WalletService for hosting).
references/packages/sqlite.md — persistent event database. Drivers: applesauce-sqlite/better-sqlite3, /native (node:sqlite, requires Node ≥22; also aliased /deno), /bun, /libsql, /turso, /turso-wasm (browser SQLite). Use with AsyncEventStore. Also ships a built-in relay (./relay).