@recoengine/strategies
v0.1.2
Published
The nine standard scoring strategies for recoengine: history, affinity, popularity, recency, novelty, discovery, similarity, co-occurrence, context. Domain-neutral by construction.
Maintainers
Readme
@recoengine/strategies
The nine standard, domain-neutral scoring strategies for
@recoengine/core.
npm i @recoengine/strategies @recoengine/coreAlready using
recoengine? These are re-exported from it — no separate install needed.
What it is
A scoring strategy answers "how well does this candidate fit this user" by reading one or
more feature columns and folding them into a single score column plus its reasons. Each
strategy here is a factory function returning a ScoringStrategy you register with
.use(...). None of them looks inside your item payload — they read named feature columns a
domain extractor produced — so the same strategy serves music, commerce, or news unchanged.
The strategies
| Factory | Scores by |
| --- | --- |
| historyStrategy | repeat interaction — count × recency of past events |
| affinityStrategy | match to a user-affinity feature (artist, brand, genre…) |
| popularityStrategy | blended global/cohort popularity percentiles; a cold-start fallback |
| recencyStrategy | how new the item is (exponential decay of age) |
| similarityStrategy | similarity to recent items and to the user profile |
| coOccurrenceStrategy | "people who interacted with X also…" co-occurrence |
| noveltyStrategy | unfamiliar items, scaled by how saturated the profile is |
| discoveryStrategy | rewards distance from the usual — exploration |
| contextStrategy | match to request-time context signals |
Usage
import { createEngine } from '@recoengine/core'
import { popularityStrategy, historyStrategy, affinityStrategy } from '@recoengine/strategies'
const engine = createEngine<Track>()
.use(myProvider)
.use(myFeatureExtractors) // produce the features these read
.use(historyStrategy())
.use(popularityStrategy({ cohortFeature: null }))
.use(affinityStrategy({ id: 'artist', feature: 'affinity_artist' }))
.use(affinityStrategy({ id: 'genre', feature: 'affinity_genre' }))
.configure({ limits: { maxCandidates: 5_000, maxLimit: 100, timeoutMs: 200 } })
.build()Each factory takes an options object (e.g. HistoryStrategyOptions,
PopularityStrategyOptions) to tune thresholds, feature names, and weights. Register two
instances of the same strategy under different ids (as with the two affinityStrategy
calls above) so they don't compete for the same weight.
Every strategy declares the feature keys it requires; get one wrong and build() throws
before the first request. The history-based features these expect can be produced for free
by @recoengine/features.
Links
- Repository & full docs: https://github.com/waleron07/recommendationEngine
MIT
