Build MacroFactor
KINDAreplaces $11.99/mosaves $143.88/yrback to the verdict
A nutrition tracker whose distinguishing feature is that it never uses a formula for your energy expenditure. It derives expenditure from the relationship between what you logged and how your weight trend actually moved, which means the interesting work is separating signal from noise in daily weight and being honest about the error you cannot remove.
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 local application.
Get it nodejs.org, or nvm install 22. open ↗
Verify
node --version prints v22 or higher - decidefree
Why These are enforced in code before anything is displayed, and deciding them after the algorithm exists means deciding them to fit the algorithm.
Get it Write down an absolute minimum daily intake, a maximum weekly rate of change, and a plain statement that this tool is not appropriate for anyone with a history of disordered eating.
Verify
All three are written down and the first two appear as constants in the safety module - have readyfree for public datasets; commercial databases are licensed
Why Search over a local database is what makes logging fast enough to keep happening, and licence terms differ sharply between sources.
Get it A publicly available national nutrient database, checking the licence covers your use. Import it locally rather than querying a service.
Verify
Searching returns results offline in under a hundred milliseconds - have readyfree if you own a scale, and it takes eight weeks
Why Expenditure estimation cannot be evaluated on synthetic data alone, and the minimum useful window is measured in weeks rather than days.
Get it Weigh daily at a consistent time and log intake honestly, including the days you would rather not.
Verify
Eight weeks of weights and mostly complete intake logs exist
Data model
Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.
- weights(date, kg, entered_at) · one per day, and days are allowed to be missing - trend(date, kg) · derived, never entered, an exponential moving average over the raw series - foods(id, name, kcal_per_100g, protein_g, carb_g, fat_g, source) · source is imported or user - entries(id, date, food_id, grams, meal, logged_at) · the log, kept even when a day is incomplete - expenditure(date, kcal, window_days, confidence) · derived, with the window it was computed over - goals(id, started_at, direction, rate_kg_per_week, floor_kcal, ended_at) · the rate cap and floor live here - Expenditure is a derived table with the window recorded, because a number computed over eight days and one computed over eight weeks are not the same claim.
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 |
|---|---|---|---|
DB_PATH | required | ~/.local/share/macrofactor/data.db | Weights and food logs. Health data, so treat backups accordingly. |
FLOOR_KCAL | required | 1500 | The absolute minimum target. Enforced in the safety module, not the interface. |
MAX_RATE_KG_PER_WEEK | required | 0.75 | The fastest change the tool will plan for. Goals beyond it are refused. |
MIN_WINDOW_DAYS | required | 21 | Below this no expenditure figure is shown at all, because it would be noise. |
TREND_HALF_LIFE_DAYS | required | 10 | How fast the trend responds. Shorter chases water, longer lags real change. |
The build, in order
A weight trend that is not the scale reading
You can see the signal in a noisy daily weight series.
A pure function over the series, unit tested with a synthetic step change.
Files
src/trend.tssrc/trend.test.tsPeople skip days. The smoothing must not assume a dense series.
Files
src/trend.tsSo the user sees how little a single day means. This is educational, not decorative.
Files
src/chart.ts
done when · tick each as it passeswatch out- Treating each day's weight as a measurement of body mass is wrong by several kilograms: a gram of stored glycogen holds around three grams of water with it, and sodium, food in transit and hormonal cycles move the number far more than fat does over a week. Smooth it, and never show a raw day-to-day change as though it means something.
Logging food without it being a chore
A normal day's food is logged in a couple of minutes.
Search must be fast offline. This is the unglamorous part that decides adoption.
Files
src/foods.tsMost people eat the same things. Exploit that or the logging stops.
Files
src/quick.tsNever treat a half-logged day as a low intake day. It poisons every later number.
Files
src/entries.ts
done when · tick each as it passeswatch out- A tracker where logging a normal day takes ten minutes is abandoned within a fortnight, and then every downstream number is computed from a partial log, which is worse than having no numbers. Saved meals and repeating a previous day are not conveniences here, they are what makes the data exist at all.
Expenditure from your own data
The tool tells you what you actually burn, with an honest confidence.
Average intake minus energy implied by trend change. Excluding incomplete days.
Files
src/expenditure.tsNo number is better than a number that is wrong by a thousand.
Files
src/expenditure.tsKnown expenditure in, recovered expenditure out, within a stated tolerance.
Files
src/expenditure.test.ts
done when · tick each as it passeswatch out- Showing an expenditure figure after five days is worse than showing nothing, because the trend change over that period is almost entirely water and the resulting number can be wrong by a thousand calories. Require a minimum window and widen it when logging has been patchy, rather than always producing an answer.
Targets with a floor the maths cannot cross
A recommended intake exists and it is never unsafe.
Not from a formula. That is the entire premise of the tool.
Files
src/target.tsIn the computation, not the interface. Property test that nothing crosses them.
Files
src/safety.tssrc/safety.test.tsA silent clamp looks like agreement and the user tries again.
Files
src/goals.ts
done when · tick each as it passeswatch out- Clamping silently to the floor makes the tool appear to have agreed to an unsafe goal, and the user sets it again in a month. Refuse the goal, say which limit it crossed, and offer the nearest acceptable one, so the constraint is visible rather than hidden inside the arithmetic.
Adapting without chasing noise
The target updates weekly as your expenditure changes, and does not thrash.
Weekly, bounded. Continuous adaptation chases water weight.
Files
src/adapt.tsThe spiral this prevents is the most important behaviour in the tool.
Files
src/adapt.tsPrevious, new, and why. An unexplained change in a health target erodes trust.
Files
src/adapt.ts
done when · tick each as it passeswatch out- Adapting to a falling apparent expenditure caused by under-reporting produces a lower target, which increases the pressure that caused the under-reporting, and the target spirals downward on data that was never real. Detect a sudden drop in logging completeness or an implausible expenditure change and pause rather than adapt.
Review, export and deleting it allproduct builder
You can see the long view, take your data with you, and remove it completely.
No streaks, no percentages framed as compliance, no good and bad foods.
Files
src/review.tsRound trip tested. Health data should never be trapped in one application.
Files
src/export.tstests/roundtrip.test.tsDerived tables and backups included. Health data deletion should be total.
Files
src/deletion.ts
done when · tick each as it passeswatch out- A review that reports adherence as a percentage with a streak beside it turns a measurement tool into a compliance scorecard, which is precisely the failure mode this whole build is trying to avoid. Report what happened without grading it, and never display a broken streak.
That is the whole plan for MacroFactor. What it deliberately does not cover is below · check the gaps before you call it a replacement.
- Barcode scanning and photo food recognition.
- A comprehensive maintained food database.
- Any clinical or medical claim.
- Coaching, periodisation and training integration.
- food database, adaptive coaching models, mobile capture, and ongoing nutrition expertise
- wearable hardware data
- coach network
- clinical validation
- large content library and social network
- Protein and fibre targets alongside energy, which most people need more than precision on calories
- Recomposition handling, where weight barely moves and the expenditure model needs care
- A diet break mode that pauses goals without pausing measurement
Need the files? The project pack on the verdict page hands your agent the whole brief · more wellness.