A headless composition engine for any collection — posts, products, videos, games, search results. BitFeed provides the primitives for sourcing, filtering, scoring, mixing, constraining and explaining. What any of it means stays yours.
It is not a recommendation algorithm, and it does not contain one.
BitFeed has no opinion about what a feed is, what content is good, what engagement matters, what should trend, or what should appear first. It is the machinery for expressing those decisions — the same way BitGate gives an application a framework for moderation policy rather than a moderation policy. If you are looking for the part that decides your feed is interesting: you write it, as a provider, and BitFeed runs it.
A recipe that omits a stage simply skips it.
Which is what makes it serializable, hashable, signable, publishable, forkable and subscribable — and what lets a runtime answer “can I run this?” before running it.
{
"spec": "bitfeed/1",
"name": "Home",
"sources": [
{ "provider": "nostr.following", "lane": "following" },
{ "provider": "nostr.interests", "lane": "interests" }
],
"scorers": [
{ "provider": "app.interestMatch", "weight": 0.4 },
{ "provider": "bitfeed.recency", "weight": 0.35 },
{ "provider": "bitfeed.random", "weight": 0.25 }
],
"mix": [
{ "lane": "following", "ratio": 0.6 },
{ "lane": "interests", "ratio": 0.4 }
],
"constraints": [
{ "provider": "bitfeed.maxPerKey",
"params": { "field": "creator", "max": 2, "window": 10 } }
]
}
Each layer answers one question and requires none of the others.
Four properties that hold structurally, not by good intentions.
Same candidates, recipe, context, seed and engine version — same feed. Ties break on a hash of the seed and candidate id, so relay arrival order cannot leak into ranking. CI bans Math.random() and wall-clock reads outright.
Every ranked item carries per-provider contributions that sum exactly to the score shown. An explanation you cannot verify is decoration.
Inserted items are placed into slots, never scored into them, and run after ranking is finished. There is no code path from a bid to a scorer.
Core's executable code contains no Nostr, video or product vocabulary — asserted by a test, not a convention. The same recipe shape ranks posts, listings and games.
BitFeed consumes a decision and never asks why it was made. A denial removes a candidate before ranking, where no score can rescue it.
The shipped presets are ordinary recipes over portable providers, not engine modes. Every component is replaceable, including all of them.
The Feed Builder runs the real engine in your browser — no server, no network, no relays.