I did not want to buy an xG or prediction feed and put a nicer interface on top of it. Score Buddy builds its own expected-goals estimates from raw match statistics, then uses those estimates together with form, team strength, standings, recent performance, and other pre-match data to produce probability-based forecasts. The current modelling stack uses XGBoost and LightGBM alongside statistical calibration rather than treating one model as the answer to every market.
That distinction matters in the app because a match is not reduced to a single home/draw/away guess. Score Buddy can show the main result probabilities alongside expected goals, goal totals, both-teams-to-score, corners, cards, team form, head-to-head history, season comparisons, and standings. The aim is to let someone glance at the prediction first and only dig into the supporting numbers when they want to.
Buddy Picks came from a fairly practical problem: generating probabilities is easy compared with deciding which ones are actually worth putting in front of a person. The curation layer removes redundant and conflicting candidates, ranks what remains, and produces a much smaller shortlist for each match. Those picks are resolved after the match as well, so I can measure the selection logic on finished fixtures instead of judging it by a few good-looking examples.
The model code runs separately from the public API. Python workers handle data synchronization, feature generation, training, backfills, scheduled inference, and other long-running jobs. The Node.js API serves the mobile client and also acts as the control surface for the system. I built an internal dashboard around it for leagues, fixtures, model runs, worker health, jobs, pipelines, prediction performance, featured picks, and notifications. That became important once Score Buddy moved from something I could run manually into something expected to refresh itself throughout the day.
The mobile client is built with Flutter. There is no required account: users can open the app, browse upcoming fixtures, open a match, and move between the prediction and the underlying stats without creating a profile first. Firebase handles multilingual push notifications, while the API keeps the mobile payloads intentionally smaller than the much denser data available internally.
I built scorebuddy.pro as a separate Next.js application rather than making the marketing site another route inside the backend. It has its own prediction-card components, product walkthrough, screenshots, legal pages, store routing, SEO metadata, sitemap and structured data. The site currently ships in 15 languages, with locale-specific URLs and metadata and a proper RTL layout for Arabic rather than a translated LTR page.
Score Buddy is now released on iOS and Android. A user sees a match card, a prediction, and the numbers behind it; the data work, model runs, evaluation, and operations needed to keep those numbers fresh stay out of the way.

