Build Hypefury
KINDAreplaces $29/mosaves $348/yrback to the verdict
A scheduling queue whose design is dictated by current platform economics: posts cost money per item, links cost far more, several capabilities are simply unavailable below Enterprise, and a queue that does not know this will produce an unexpected bill or a silent failure.
Before step 1
Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.
- installfree
Why Runs the server and the publishing worker.
Get it nodejs.org, or nvm install 22. open ↗
Verify
node --version prints v22 or higher - installfree locally
Why Queue state, spend tracking and idempotency records.
Get it Docker or your package manager. open ↗
Verify
psql connects and a unique constraint enforces idempotency - accountpay per use; a link post costs many times a plain one
Why Pricing and capabilities changed substantially in 2026, and building against a tutorial's description of the old tiers produces a tool that fails at send time.
Get it Apply for access, read the current pricing and endpoint availability for your tier, and record both with the date you checked. open ↗
Verify
A test post publishes and the recorded capability map matches what your tier actually allows - decidefree to decide
Why Writes cost money per item and a queue that ignores that produces a bill rather than a surprise you can undo.
Get it Decide a monthly figure, and work out how many posts that is at the URL and non-URL prices.
Verify
A figure is written down and the post count it implies is calculated - have readyfree
Why Slot behaviour, empty queue handling and the cost difference between link and non-link posts only become visible with a real queue running for a while.
Get it Write or gather enough posts to fill your slots for two weeks, including several with links.
Verify
A queue exists with at least a third of posts containing links
Data model
Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.
- accounts(id, platform, handle, tier, connected_at, capabilities_json) - posts(id, account_id, body, media_ids_json, contains_url, thread_parent_id, state, scheduled_for, posted_at, external_id) - cost_estimates(post_id, currency, amount_minor, basis) · basis records which price rule applied - spend(account_id, period, estimated_minor, actual_minor) - capabilities(platform, tier, endpoint, available, checked_on, source_url) · dated, because this is what changed - slots(id, account_id, day_of_week, time_local, timezone) · the recurring queue - failures(post_id, at, kind, detail, retryable) · kind is rate_limit, capability, auth or content - A post records whether it contains a URL, because that single fact changes its cost by more than an order of magnitude.
Environment variables
These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.
| Variable | Needed | Example | Where the value comes from |
|---|---|---|---|
DATABASE_URLsecret | required | postgres://localhost:5432/queue | Queue state, spend and platform tokens by reference. |
PLATFORM_API_KEYsecret | required | a platform-issued key | Official API only. Browser automation is not part of this build. |
PRICING_PATH | required | ./config/pricing.json | Dated per-write pricing including the URL surcharge. |
CAPABILITIES_PATH | required | ./config/capabilities.json | Dated endpoint availability per tier. This is what changed in 2026. |
MONTHLY_BUDGET_MINOR | required | 3000 | Checked before scheduling. Writes cost money per item. |
RECYCLE_OLD_POSTS | required | never | Present as a constant. An empty slot is information; a recycled post is noise. |
The build, in order
Knowing what your tier can actually do
An unavailable capability fails when you schedule, not when it sends.
They changed in 2026 without grandfathering. Constants go quietly wrong.
Files
config/capabilities.jsonA failure at send is a failure you find out about afterwards.
Files
src/capability.tsBetween scheduling and sending, a tier can change.
Files
src/publish.ts
done when · tick each as it passeswatch out- Discovering that your tier no longer has an endpoint at the moment a scheduled post tries to send means a silent failure at the worst possible time, and the removals in 2026 came without grandfathering. Check capability at scheduling time, and treat the map as dated data that goes stale rather than as constants.
Costing a post before you queue it
You know what a week's queue will cost before it runs.
A link costs over ten times a plain post. That belongs in the interface.
Files
src/cost.tssrc/cost.test.tsBefore the week runs, not on the invoice.
Files
src/projection.tsDivergence means the pricing table is stale.
Files
src/spend.ts
done when · tick each as it passeswatch out- A post containing a link costs many times one without, which is invisible in an interface that treats all posts the same, and a queue full of link posts produces a bill nobody predicted. Detect the URL, price accordingly, and show the difference at the point where someone is deciding whether to include a link.
A queue that fills slots sensibly
Content flows into recurring slots without you scheduling each item.
Test both daylight transitions. A post an hour early is visible.
Files
src/slots.tssrc/slots.test.tsAn empty queue is information. A recycled post is noise.
Files
src/queue.tsMoving an item should not lose its scheduled position.
Files
src/queue.ts
done when · tick each as it passeswatch out- Automatically recycling old posts when the queue runs dry is the feature that turns a scheduling tool into a repetition machine, and followers notice long before the operator does. Leave the slot empty and say the queue is empty, since an empty slot is information and a recycled post is noise.
Publishing, and failing usefully
Posts go out through the official API and failures are explicable.
A timeout that actually succeeded is the common duplicate.
Files
src/publish.tsRate limit, capability, auth, content. Four different responses.
Files
src/failures.tsRather than failing every queued post in sequence.
Files
src/accounts.ts
done when · tick each as it passeswatch out- Retrying every failure identically will repost after a timeout that actually succeeded, producing a duplicate, and will retry a content rejection forever. Use an idempotency key, classify the failure, and retry only the classes where retrying can help.
Threads, media and knowing what happenedproduct builder
Multi-part posts publish correctly and you can see what the queue did.
Each to the previous, in order, with the platform's own mechanism.
Files
src/threads.tsDelete or continue. Orphaned parts are the worst outcome.
Files
src/threads.tsSize and format. A rejection after upload wastes the request and the money.
Files
src/media.ts
done when · tick each as it passeswatch out- A thread that fails on its third part leaves two orphaned posts in public that read as an incomplete thought, which is worse than nothing having posted at all. Decide the rule in advance: either delete the published parts or post a continuation, and make the choice explicit rather than leaving orphans.
That is the whole plan for Hypefury. What it deliberately does not cover is below · check the gaps before you call it a replacement.
- Engagement automation.
- Browser automation of the web interface.
- Analytics beyond what the API returns.
- Broad platform coverage.
- platform integrations, auto-reposting, cross-posting, analytics, and creator templates
- many maintained network APIs
- inbox and moderation
- deep analytics
- team approvals and asset libraries
- Per-slot content types, so the queue mixes rather than posting five similar things
- A cost comparison between posting with and without a link, which is now a real editorial decision
- Draft review before an item enters the queue, once the queue itself is trustworthy
Need the files? The project pack on the verdict page hands your agent the whole brief · more social media.