Migrating from applesauce v4 to v5
This guide explains how to migrate an existing applesauce v4 project to v5, with a focus on import changes and the applesauce-common package. It is written for both humans and AI agents (LLMs, code‑mod tools) and favors mechanical “if you see X, replace with Y” style rules.
1. Goals and scope
- What this covers:
- Moving helpers, models, blueprints, and operations that were previously imported from
applesauce-core(andapplesauce-factory) to their new homes. - Installing and wiring the
applesauce-commonpackage. - A step‑by‑step algorithm that an AI agent can safely follow to refactor imports.
- Moving helpers, models, blueprints, and operations that were previously imported from
- What this does not cover:
- Non-import behavior changes (runtime semantics, new features).
- Breaking changes in external deps (
nostr-tools, React, etc.).
If you only remember one thing: most NIP‑specific helpers and models moved out of applesauce-core into applesauce-common.
2. Conceptual changes: applesauce-core vs applesauce-common
In v4, applesauce-core exposed both protocol‑level primitives and a large set of NIP‑specific helpers and models. In v5, these responsibilities are split:
applesauce-core(protocol‑level primitives):EventStore,AsyncEventStore- Observables (
Observable,Subject,BehaviorSubject,ReplaySubject), promise helpers (firstValueFrom,lastValueFrom,simpleTimeout,TimeoutError) - Low‑level event helpers (
NostrEvent,UnsignedEvent,VerifiedEvent,kinds, encoding/decoding, pointer utilities, filters, cache) - Base models for generic patterns (
EventModel,TimelineModel,ProfileModel, etc. in the “core” sense) EventFactoryshell inapplesauce-core/event-factory
applesauce-common(NIP‑specific and app‑level functionality):- NIP‑specific helpers for:
- Threads/comments (NIP‑10, NIP‑22)
- Groups
- Streams (NIP‑53)
- Articles (NIP‑23)
- Calendar events (NIP‑52)
- Polls (NIP‑88)
- Zaps, bookmarks, mutes, highlights, handlers, blossom servers, etc.
- NIP‑specific models:
CommentsModel,ThreadModel,WrappedMessagesModel,LegacyMessages*,CalendarEventsModel,EventZapsModel,ReceivedZapsModel,SentZapsModel, various “group” and “stream” models, etc.
EventFactoryblueprints and domain‑level operations.
- NIP‑specific helpers for:
You can see this reflected in the package docs:
applesauce-core:packages/core/README.mdapplesauce-common:packages/common/README.md- Packages overview:
apps/docs/introduction/packages.md
Rationale: applesauce-core stays small and focused on the Nostr protocol itself, while applesauce-common hosts higher‑level, NIP‑specific building blocks you may or may not want to depend on.
3. Package changes and installation
At a high level, v5 projects will usually use:
| Area | Package(s) |
|---|---|
| Core protocol | applesauce-core |
| NIP helpers | applesauce-common |
| Content parsing | applesauce-content |
| Reactive UI | applesauce-react |
| Actions | applesauce-actions |
| Wallet (NIP‑60) | applesauce-wallet |
| Relays | applesauce-relay, applesauce-loaders, etc. |
3.1. Add applesauce-common
If your v4 project did not already use applesauce-common, install it alongside your existing packages:
npm install applesauce-common applesauce-core
# or
yarn add applesauce-common applesauce-core
# or
pnpm add applesauce-common applesauce-core3.2. Keep applesauce packages on the same major version
To avoid subtle breakage:
- Ensure all
applesauce-*packages you use are on a consistent major version (e.g. all^5.xonce v5 is published). - Do not mix
applesauce-core@4withapplesauce-common@5, etc.
4. Import migration rules (applesauce-core → applesauce-common)
This section is designed for AI agents as well as humans. It focuses on patterns, not a complete symbol list.
4.1. Helpers: move NIP‑specific helpers to applesauce-common/helpers
Rule:
- Before (v4): Many NIP‑specific helpers were imported from:
applesauce-core/helpersapplesauce-core/helpers/<module>
- After (v5): Those helpers now live under:
applesauce-common/helpersapplesauce-common/helpers/<module>
Representative mappings (derived from current exports and examples):
- Identity / profile helpers:
getDisplayName,getProfilePicture,getProfileContent,getProfilePointersFromList- v4: from
applesauce-core/helpers - v5: from
applesauce-common/helpers
- Social graph / relay helpers:
groupPubkeysByRelay,mergeRelaySets,getSeenRelays,selectOptimalRelays- v4:
applesauce-core/helpers - v5:
applesauce-common/helpers
- Threading and comments:
getNip10References,interpretThreadTags,getCommentEventPointer,getCommentReplyPointer,getCommentRootPointer- v4:
applesauce-core/helpers(threading‑related modules) - v5:
applesauce-common/helpers
- Groups:
encodeGroupPointer,decodeGroupPointer,groupMessageEvents, group list helpers- NIP-29 Group Management helpers (new in v5):
CREATE_GROUP_KIND,CREATE_INVITE_KIND,DELETE_GROUP_KIND,EDIT_METADATA_KIND,JOIN_REQUEST_KIND,LEAVE_REQUEST_KIND,PUT_USER_KIND,REMOVE_USER_KIND, and related group management functions - v4:
applesauce-core/helpers - v5:
applesauce-common/helpers(orapplesauce-common/helpers/groupsfor group-specific helpers)
- Articles / highlights / media:
getArticleImage,getArticlePublished,getArticleSummary,getArticleTitle- Highlight helpers (
getHighlightText,getHighlightContext,getHighlightSourceEventPointer,getHighlightSourceAddressPointer, etc.) - v4:
applesauce-core/helpers - v5:
applesauce-common/helpers
- Calendar:
- Calendar kinds and symbols (
CALENDAR_EVENT_RSVP_KIND,DATE_BASED_CALENDAR_EVENT_KIND,TIME_BASED_CALENDAR_EVENT_KIND, etc.) - Helpers like
getCalendarEventStart/End,getCalendarEventTitle,getCalendarAddressPointers - v4:
applesauce-core/helpers - v5:
applesauce-common/helpers
- Calendar kinds and symbols (
- Polls:
POLL_KIND,POLL_RESPONSE_KIND, poll options / votes / type helpers- v4:
applesauce-core/helpers - v5:
applesauce-common/helpers
- Zaps:
getZapAmount,getZapEventPointer,getZapSender,getZapRecipient,getZapRequest,isValidZap, etc.- v4:
applesauce-core/helpers - v5:
applesauce-common/helpers
- Gift wrap, bookmarks, mutes, streams, handlers, blossom servers, etc.:
- Numerous helpers with names like
getGiftWrapRumor,getBookmarks,getMutedThings,getStream*,getHandler*,mergeBookmarks,matchMutes,mergeBlossomServers. - v4:
applesauce-core/helpers - v5:
applesauce-common/helpers
- Numerous helpers with names like
- Lists and relay lists:
FAVORITE_RELAYS_KIND,getListTags,getRelaysFromList,getAddressPointersFromList,isEventPointerInList,ReadListTags, and other list-related helpers- v4:
applesauce-core/helpers/lists - v5:
applesauce-common/helpers/lists
- External identifiers (NIP-73):
parseExternalPointer,isValidExternalPointer,getExternalPointerFromTag,ExternalIdentifiers,ExternalPointer- v4:
applesauce-core/helpers/external-id - v5:
applesauce-common/helpers/external-id
Keep these in applesauce-core/helpers (protocol primitives):
- Encoding/decoding and core types:
NostrEvent,UnsignedEvent,VerifiedEvent,kinds,noteEncode,neventEncode,naddrEncode,npubEncode,nsecEncode
- Pointers and tags:
AddressPointer,EventPointer,ProfilePointer,isEventPointer, low‑leveldecodeAddressPointer,decodeEventPointer,decodeProfilePointer- Note: In v5, pointer decoding helpers (
decodeAddressPointer,decodeEventPointer,decodeProfilePointer,parseReplaceableAddress) no longer throw errors on invalid input; they returnnullinstead. Update any code that relied on try/catch around these functions to check fornullreturn values.
- Generic tag / filter / cache helpers:
Filter,matchFilter,matchFilters,mergeFilters,processTagsgetOrComputeCachedValue,getCachedValue,setCachedValue,LRU
- URL / bytes helpers:
bytesToHex,hexToBytes,ensureHttpURL,ensureWebSocketURL,normalizeURL, etc.
If a helper name is obviously NIP‑specific or app‑level, move it to applesauce-common/helpers. If it is a core protocol helper (encoding, pointers, filters, cache, low‑level URL handling), keep it in applesauce-core/helpers.
4.2. Models: move NIP‑specific models to applesauce-common/models
Rule:
- Before (v4): Most high‑level models (threads, comments, zaps, streams, calendar, bookmarks, mutes, etc.) were exported from:
applesauce-core/models
- After (v5): These models live in:
applesauce-common/models
Representative mappings:
- Threading / comments:
ThreadModel,CommentsModel,RepliesModel,WrappedMessagesModel,LegacyMessagesThreads,LegacyMessageReplies, etc.- v4:
applesauce-core/models - v5:
applesauce-common/models
- Zaps:
EventZapsModel,ReceivedZapsModel,SentZapsModel- v4:
applesauce-core/models - v5:
applesauce-common/models
- Calendar:
CalendarEventsModel,CalendarEventRSVPsModel- v4:
applesauce-core/models - v5:
applesauce-common/models
- Groups and channels:
CommentsModel, channel‑related models (e.g.ChannelMessagesModel,ChannelMetadataModel,ChannelHiddenModel,ChannelMutedModel), streams/chat models- v4:
applesauce-core/models - v5:
applesauce-common/models
- Bookmarks, pins, hidden/public variants:
UserBookmarkModel,UserHiddenBookmarkModel,UserPublicBookmarkModel,UserPinnedModel,UserBlossomServersModel- v4:
applesauce-core/models - v5:
applesauce-common/models
Models that remain “core”:
- Base models such as
EventModel,TimelineModel,ProfileModel,FiltersModel,MailboxesModel,OutboxModel,ReplaceableModel,ContactsModel,HiddenContactsModel,PublicContactsModelare still conceptually part ofapplesauce-core. - However, in v5 these may be re‑exported and/or extended in
applesauce-common/modelsfor NIP‑specific use cases.
Relay models moved to applesauce-common:
- Relay-related models (
FavoriteRelaysModel,FavoriteRelaySetsModel,SearchRelaysModel,BlockedRelaysModel) moved fromapplesauce-core/modelstoapplesauce-common/models:- v4:
applesauce-core/models(orapplesauce-core/models/relays) - v5:
applesauce-common/models(orapplesauce-common/models/relays)
- v4:
As a migration heuristic:
- If a
*Modelname refers to generic protocol concepts (events, timelines, contacts): keep it inapplesauce-core/models. - If a
*Modelname refers to relay lists or other NIP-specific concepts: move it toapplesauce-common/models. - If it refers to a NIP or app concept (comments, polls, streams, bookmarks, mutes, zaps, calendar, wrapped messages): move it to
applesauce-common/models.
4.3. Operations and blueprints: move to applesauce-common
In v4, many EventFactory operations and blueprints lived either in applesauce-factory or under applesauce-core exports. In v5:
EventFactoryitself lives inapplesauce-core/event-factory.- Domain‑specific operations and blueprints live in
applesauce-common:applesauce-common/operationsapplesauce-common/blueprints
The common operations/blueprints include (non‑exhaustive):
- Operations:
AppData,Calendar,CalendarEvent,CalendarRsvp,Channel,Comment,FileMetadata,Geohash,GiftWrap,Groups,Hashtags,Highlight,LegacyMessage,List,LiveStream,MediaAttachment,Note,PicturePost,Poll,PollResponse,Reaction,Stream,StreamChat,TagOperations,Torrent,WrappedMessage,Zap
- Blueprints:
AppDataBlueprint,CalendarBlueprint,ChannelMessageBlueprint,ChannelMessageReplyBlueprint,CommentBlueprint,DeleteBlueprint,FileMetadataBlueprint,FollowSetBlueprint,GiftWrapBlueprint,GroupMessageBlueprint,HighlightBlueprint,LegacyMessageBlueprint,LegacyMessageReplyBlueprint,LiveChatMessageBlueprint,NoteBlueprint,NoteReplyBlueprint,PicturePostBlueprint,PollBlueprint,PollResponseBlueprint,ProfileBlueprint,ReactionBlueprint,ShareBlueprint,SingleChoicePollResponseBlueprint,StreamChatMessage,TorrentBlueprint,WrappedMessageBlueprint,WrappedMessageReplyBlueprint- NIP-29 Group Management blueprints (new in v5):
GroupJoinRequestBlueprint,GroupLeaveRequestBlueprint,GroupCreateBlueprint,GroupDeleteBlueprint,GroupEditMetadataBlueprint,GroupPutUserBlueprint,GroupRemoveUserBlueprint
Migration rules:
- If an operation or blueprint name clearly corresponds to a NIP or domain:
- v4 imports from
applesauce-coreorapplesauce-factory - v5 imports from:
applesauce-common/operations(for operations)applesauce-common/blueprints(for blueprints)
- v4 imports from
EventFactoryusage:- v4:
- Often
import { EventFactory } from "applesauce-factory";
- Often
- v5:
import { EventFactory } from "applesauce-core/event-factory";- And blueprints/operations from
applesauce-common.
- v4:
5. AI‑friendly refactor algorithm
This section is a mechanical algorithm that an AI agent can follow to refactor imports.
5.1. Search scope
Scan all TypeScript/JavaScript files:
- Look for imports whose module specifier starts with:
"applesauce-core""applesauce-factory"(v4 only)
5.2. Classify imported symbols
Define two curated lists (these can be hard‑coded by the agent or configured by the user):
- Always‑core (keep in
applesauce-core):EventStore,AsyncEventStoreObservable,Subject,BehaviorSubject,ReplaySubject,TimeoutError,firstValueFrom,lastValueFrom,simpleTimeoutEventFactory(but move toapplesauce-core/event-factoryif previously fromapplesauce-factory)- Protocol types and utilities:
NostrEvent,UnsignedEvent,VerifiedEvent,kinds, encoding/decoding helpers, pointer types and basic pointer helpers,Filter, cache helpers, pure URL/byte helpers.
- Always‑common (move to
applesauce-common):- Any symbol that is:
- A NIP or app concept:
CommentsModel,ThreadModel,WrappedMessagesModel,LegacyMessagesThreads,LegacyMessageReplies,EventZapsModel,CalendarEventsModel,FavoriteRelaysModel,FavoriteRelaySetsModel,SearchRelaysModel,BlockedRelaysModel,HighlightBlueprint,CommentBlueprint,GroupMessageBlueprint,PollBlueprint,Zap,AppData,Calendar,GiftWrap,Stream, etc. - A NIP‑oriented helper, e.g.
getNip10References,groupPubkeysByRelay(social graph),getArticle*,getHighlight*,getCalendarEvent*,getZap*, list helpers likegetListTags,getRelaysFromList,FAVORITE_RELAYS_KIND.
- A NIP or app concept:
- Any symbol that is:
5.3. Rewrite rules (pseudo‑code)
For each import statement:
import { A, B, C } from "applesauce-core/helpers";
// or:
import { X, Y } from "applesauce-core/models";
// or:
import { EventFactory, CommentBlueprint } from "applesauce-factory";Apply this algorithm:
- For each imported symbol
S:- If
Sis in the always‑core list:- Keep module as
applesauce-core(or update path toapplesauce-core/event-factoryforEventFactory).
- Keep module as
- Else if
Sis in the always‑common list or matches any of these patterns:- Name ends with
Modeland is clearly domain‑specific (CommentsModel,ThreadModel,WrappedMessagesModel, etc.). - Name ends with
Blueprint. - Name is in the known operations list (
AppData,Calendar,Comment,Poll,Zap,Stream, etc.). - Name is a helper that appears in both v4
applesauce-core/helpersand v5applesauce-common/helpers. - Then:
- If it is a helper → new module:
applesauce-common/helpers(orapplesauce-common/helpers/<module>). - If it is a model → new module:
applesauce-common/models. - If it is an operation → new module:
applesauce-common/operations. - If it is a blueprint → new module:
applesauce-common/blueprints.
- If it is a helper → new module:
- Name ends with
- Else if ambiguous:
- Prefer
applesauce-coreif it deals only with low‑level protocol concerns. - Prefer
applesauce-commonif it refers to a NIP, UI feature, or application domain.
- Prefer
- If
- Once each symbol is classified, group them by their new target module and emit one import per module.
5.4. Handling applesauce-factory
If you see imports from "applesauce-factory":
EventFactory→import { EventFactory } from "applesauce-core/event-factory";- Any blueprints or operations → map to
applesauce-common/blueprintsorapplesauce-common/operationsas described above.
5.5. Other packages
As you refactor, do not change imports from these packages unless you have a specific reason:
applesauce-actionsapplesauce-walletapplesauce-reactapplesauce-contentapplesauce-relayapplesauce-loaders
They are already v5‑compatible at their public surface; the main change is that they internally depend on applesauce-common. Your application code usually does not need to adjust imports from these packages.
6. Before/after examples
These examples demonstrate common migration patterns.
6.1. Simple helper move (profiles)
Before (v4):
import { getDisplayName, getProfilePicture } from "applesauce-core/helpers";After (v5):
import { getDisplayName, getProfilePicture } from "applesauce-common/helpers";6.2. Models move (threads and comments)
Before (v4):
import { EventStore } from "applesauce-core";
import { ThreadModel, CommentsModel } from "applesauce-core/models";After (v5):
import { EventStore } from "applesauce-core";
import { ThreadModel, CommentsModel } from "applesauce-common/models";6.3. Factory + blueprints
Before (v4):
import { EventFactory } from "applesauce-factory";
import { CommentBlueprint } from "applesauce-core/operations"; // or applesauce-factory in older code
const factory = new EventFactory({ signer });
const blueprint = CommentBlueprint({ content: "Hello" });After (v5):
import { EventFactory } from "applesauce-core/event-factory";
import { CommentBlueprint } from "applesauce-common/blueprints";
const factory = new EventFactory({ signer });
const blueprint = CommentBlueprint({ content: "Hello" });6.4. End‑to‑end example: zap timeline
Before (v4) – everything from core:
import { EventStore, mapEventsToStore, mapEventsToTimeline } from "applesauce-core";
import { getZapAmount, getZapEventPointer, getZapSender, isValidZap } from "applesauce-core/helpers";
import { useObservableMemo } from "applesauce-react/hooks";
import { onlyEvents, RelayPool } from "applesauce-relay";After (v5) – split between core and common:
import { EventStore, mapEventsToStore, mapEventsToTimeline } from "applesauce-core";
import { getZapAmount, getZapEventPointer, getZapSender, isValidZap } from "applesauce-common/helpers";
import { useObservableMemo } from "applesauce-react/hooks";
import { onlyEvents, RelayPool } from "applesauce-relay";6.5. End‑to‑end example: group threads
Before (v4):
import { EventStore, mapEventsToStore, mapEventsToTimeline } from "applesauce-core";
import { getDisplayName, getProfilePicture, getTagValue } from "applesauce-core/helpers";
import { EventFactory } from "applesauce-factory";
import { CommentsModel } from "applesauce-core/models";After (v5):
import { EventStore, mapEventsToStore, mapEventsToTimeline } from "applesauce-core";
import { getDisplayName, getProfilePicture, getTagValue } from "applesauce-common/helpers";
import { EventFactory } from "applesauce-core/event-factory";
import { CommentsModel } from "applesauce-common/models";6.6. Lists helpers migration
Before (v4):
import { FAVORITE_RELAYS_KIND, getListTags, getRelaysFromList } from "applesauce-core/helpers/lists";
import { FavoriteRelaysModel } from "applesauce-core/models";After (v5):
import { FAVORITE_RELAYS_KIND, getListTags, getRelaysFromList } from "applesauce-common/helpers/lists";
import { FavoriteRelaysModel } from "applesauce-common/models";6.7. Pointer helpers behavior change
Before (v4) - relying on thrown errors:
import { decodeEventPointer } from "applesauce-core/helpers/pointers";
try {
const pointer = decodeEventPointer(encoded);
// use pointer
} catch (e) {
// handle error
}After (v5) - checking for null:
import { decodeEventPointer } from "applesauce-core/helpers/pointers";
const pointer = decodeEventPointer(encoded);
if (pointer) {
// use pointer
} else {
// handle invalid input
}7. Notes on other packages
7.1. applesauce-actions
- Public exports are stable in v5:
- Root
indexexports:ActionRunner,Actions. applesauce-actions/actionsexposes individual actions such asBookmarkEvent,FollowUser,MuteUser,SendWrappedMessage, etc.
- Root
- You do not generally need to change your imports:
import { ActionRunner } from "applesauce-actions";import { FollowUser } from "applesauce-actions/actions";
Breaking changes in v5:
- Actions are now async-only: All actions must return
Promise<void>. Actions can no longer be synchronous functions or async generators. - Removed async generator support: The
ActionRunnerno longer supports actions that are async generators (async function*). - ActionContext methods are async: Both
publishandrunmethods inActionContextnow returnPromise<void>.
Migration example:
// v4 - could be sync or async generator
export function MyAction(): Action {
return async function* (context) {
// generator code
yield event1;
yield event2;
};
}
// v5 - must be async function returning Promise<void>
export function MyAction(): Action {
return async (context) => {
// async code
await context.publish(event1);
await context.publish(event2);
};
}If you have custom actions that used async generators, convert them to async functions that call context.publish() for each event.
7.2. applesauce-wallet
- Public exports are also stable:
- Root
indexexports:Actions,Blueprints,Helpers,Models,Operations. applesauce-wallet/actionsexports wallet‑specific actions likeCreateWallet,UnlockWallet,NutzapProfile, etc.
- Root
- Migration work here is mostly indirect:
- Ensure
applesauce-commonis installed so any shared helpers/models used by wallet internals resolve correctly.
- Ensure
7.3. applesauce-react
- Root exports are unchanged:
AccountsContext,AccountsProviderActionsContext,ActionsProviderEventStoreContext,EventStoreProviderFactoryContext,FactoryProviderHelpers,Hooks
- Hooks and providers still import from:
"applesauce-react/hooks""applesauce-react/providers"
- New in v5: The
use$hook is available from"applesauce-react/hooks":- A utility hook that combines
useObservableStateanduseMemofor easier observable usage - Supports
BehaviorSubject,Observable, and factory functions with dependency arrays - Example:
const value = use$(observable);orconst value = use$(() => createObservable(), [deps]);
- A utility hook that combines
- Your migration work is mostly in how you feed models and helpers into your React components (via the import rules above).
7.4. applesauce-content
- The content package’s top‑level exports (
Helpers,Text,Markdown,Nast) are unchanged between v4 and v5. - Some examples in the docs now combine
applesauce-content(for parsing text/markdown) with models and helpers fromapplesauce-common.
7.5. Loaders, relay, signers, accounts, etc.
applesauce-loaders,applesauce-relay,applesauce-signers,applesauce-accountsare largely unaffected at the import level.- Just ensure you keep them on a consistent major version with
applesauce-core/applesauce-common.
Loader attachment to EventStore
- In v4, there were multiple experimental loader properties on
EventStore(eventLoader,replaceableLoader,addressableLoader). - In v5, these are replaced by a single unified
eventLoader. Apps should:- Prefer the Unified Event Loader (
createUnifiedEventLoader) when setting up loaders. - Or, more commonly, use
createEventLoaderForStore(eventStore, pool, options)fromapplesauce-loaders/loadersto attach the unified loader to anEventStorein one step.
- Prefer the Unified Event Loader (
RelayPool behavior changes
- RelayPool ignores offline relays by default: The
request(),subscription(),publish(), andsync()methods inRelayPoolnow ignore unreachable (ready=false) relays by default. This is controlled by theignoreOfflineproperty (default:true). Manual methods likereq()andevent()still include offline relays. - New retry configuration options:
RelayandRelayPoolconstructors now acceptsubscriptionRetry,requestRetry, andpublishRetryoptions for configuring default retry limits. These replace the previous approach.
Migration note: If your v4 code relied on offline relays being included in automatic methods (request(), subscription(), publish(), sync()), you may need to:
- Set
ignoreOffline: falseon yourRelayPoolinstance, or - Use the manual
req()andevent()methods which always include offline relays.
8. Verification and troubleshooting checklist
After applying the import migration, use this checklist:
- 1. Install dependencies
- Ensure
applesauce-commonis installed. - Align all
applesauce-*packages to the same major version.
- Ensure
- 2. Compile and typecheck
- Run your project’s build/test commands (for this monorepo,
pnpm build/pnpm test). - Fix any remaining import‑not‑found errors by moving the symbol to
applesauce-commonas per the rules above.
- Run your project’s build/test commands (for this monorepo,
- 3. Runtime smoke tests
- Open key screens: threads/comments, group chat, highlight/article pages, zap timelines, calendar views.
- Verify that models populate and helpers behave as before.
- 4. Diff‑based validation (for AI agents)
- Confirm that any removed imports from
"applesauce-core/helpers"or"applesauce-core/models":- Either moved to
"applesauce-common/helpers"/"applesauce-common/models"/"applesauce-common/operations"/"applesauce-common/blueprints", or - Were intentionally deleted because they are unused.
- Either moved to
- Confirm that any removed imports from
- 5. Ambiguous symbols
- When in doubt, prefer:
applesauce-corefor protocol‑level primitives and generic utilities.applesauce-commonfor NIP‑specific or app‑level behavior.
- When in doubt, prefer:
Once this checklist passes, your project should be functionally equivalent to the v4 version while taking full advantage of the v5 applesauce-common split.
9. New features in v5
This section documents new features and APIs introduced in v5 that are not migration concerns but may be useful to know about.
9.1. Event Casting System
v5 introduces a type-safe event casting system in applesauce-common/casts for working with Nostr events in a more structured way.
Location: applesauce-common/casts or applesauce-common/Casts
Key exports:
cast()function andCastbase class- Specific cast classes:
NoteCast,ProfileCast,ZapCast,CommentCast,MailboxesCast,StreamCast
Usage example:
import { cast, NoteCast } from "applesauce-common/casts";
// Cast an event to a NoteCast for type-safe access to note-specific properties
const note = cast(event, NoteCast);
// Now you can use note-specific methods and propertiesThis is a new API for v5 and does not require migration from v4 code.
9.2. Observable Utilities
v5 adds new observable utilities in applesauce-common/observable:
Location: applesauce-common/observable or applesauce-common/Observable
Key exports:
chainable- Chainable observable utilities for building reactive pipelinescast-event- Event casting observablesfilter-timeline-by-mutes- Timeline filtering utilities for muting
These are new utilities for v5 and do not require migration from v4 code.
9.3. NIP-29 Group Management
v5 adds comprehensive support for NIP-29 group management:
Helpers: applesauce-common/helpers/groups
- Group management constants:
CREATE_GROUP_KIND,CREATE_INVITE_KIND,DELETE_GROUP_KIND,EDIT_METADATA_KIND,JOIN_REQUEST_KIND,LEAVE_REQUEST_KIND,PUT_USER_KIND,REMOVE_USER_KIND - Group management helper functions
Blueprints: applesauce-common/blueprints
GroupJoinRequestBlueprint- Create a join request for a groupGroupLeaveRequestBlueprint- Create a leave request for a groupGroupCreateBlueprint- Create a new groupGroupDeleteBlueprint- Delete a groupGroupEditMetadataBlueprint- Edit group metadataGroupPutUserBlueprint- Add or update a user in a groupGroupRemoveUserBlueprint- Remove a user from a group
This is a new feature for v5 and does not require migration from v4 code.
