How UntappdBolaget Works
UntappdBolaget matches your personal Untappd beer ratings against Systembolaget's product catalog, helping you find beers you'll love that are available at your local store.
1. Your Taste Profile
When you enter your Untappd username, the app scrapes your public beer checkins and builds a taste profile — your top beer styles ranked by how many you've tried and how highly you've rated them. This profile is the foundation of every recommendation.
If you've checked in a specific beer that's also on Systembolaget, the app directly matches it by brewery and beer name, so you can see your own rating and your friends' average for that exact beer.
2. Systembolaget Indexing
The app fetches beer products from Systembolaget's API for your selected stores. Products are fetched page-by-page with resumable cursors — if you close the app mid-indexing, it picks up where it left off.
An automatic daily refresh runs at 05:00 CET so the catalog is already current before the morning rush — Systembolaget publishes new listings overnight, and finishing the pipeline before peak usage means no mid-refresh stale-data flicker on the first visit of the day. A manual Refresh button in the status bar kicks off a fresh sync on demand.
Visible beers are also re-checked daily against their Systembolaget product pages (online availability check). Products that have been delisted or marked out of stock online are hidden automatically, and a summary toast tells you how many disappeared in a given check so nothing vanishes without explanation.
3. Taste Score
Every Systembolaget beer gets a Taste Score from 0 to 100. This score blends two things:
The stronger of the two signals (category fit vs. Untappd rating) is weighted at 60%, the weaker at 40%. A beer with a great style match but a poor community rating won't climb to Perfect, and vice versa.
When no Untappd rating is available yet, the category fit score is used alone with a × 0.75 penalty, so community-validated beers rank higher.
Price Factor
A small price adjustment (−2.5 to +5 points) nudges the final score based on how a beer's price compares to the median price for its style category (falling back to the global median when the category has too few products). Cheaper-than-median beers get a bonus, expensive ones get a penalty — so two beers with equal taste fit will have the better-value option ranked higher. The adjustment is small enough that taste fit and rating always dominate. Can be disabled in Settings.
ABV Factor
A similar ABV adjustment (−2.5 to +5 points) nudges the score based on how a beer's alcohol percentage compares to the median ABV for its style category. Higher-than-median ABV beers get a bonus, lower ones get a penalty. Like the price factor, this is a small nudge that won't override taste fit or rating. Can be disabled in Settings.
Score Tiers
Taste Scores are grouped into tiers to help you decide at a glance:
Style Normalization
Some beer styles — stouts, pastry stouts, barleywines — run systematically higher on Untappd than lighter styles like pilsners or session IPAs. Without adjustment, those styles would always dominate the top of your results regardless of personal fit.
To compensate, the app computes a per-style median rating from the enrichment cache and nudges each beer's contribution up or down based on how it compares to its style's median (clamped to a maximum ±0.8 on the 5-point scale). A 4.2 stout ends up slightly lower than a 4.2 pilsner because "4.2" is an average stout but a remarkable pilsner. The adjustment falls back to a broader style-family median (e.g. all IPAs) for niche substyles with too few samples. Can be disabled or softened in Settings.
Combined Excellence Bonus
When a beer scores ≥ 90 on both category fit and scaled Untappd rating, it earns a small +2 synergy bonus. A rank-4 style × 4.22 community rating would otherwise cap at 95, one point shy of Perfect — the bonus lets top-1% combinations actually cross the tier boundary.
Preference Penalty Cap
Price, ABV, and style-normalization adjustments are applied in score-space (style-norm uses a ×10 rating→score conversion so its impact stays linear across the curve). The total downside from all preferences combined is clamped at −5 points, so no beer can fall more than 5 points below its clean category × rating blend no matter how expensive, high-ABV, or unusually-styled it is. Positive bonuses pass through unchanged.
Score Breakdown
Every beer card has a score tooltip that shows the full breakdown: base category score, rank multiplier, scaled Untappd rating, combined-excellence bonus, price and ABV factors, and the style-normalization adjustment. If a recommendation ever looks wrong, the tooltip tells you exactly which component pushed the score up or down.
Untappd Rating Scaling
Untappd ratings aren't scaled linearly — a 4.0 is far rarer than a 3.5, and a 4.25+ is truly exceptional. The app uses a non-linear curve that accelerates through the 4.0–4.25 shoulder so top-1% ratings actually surface as top taste scores:
This means a 4.2+ rated beer in one of your top styles can reach Perfect tier (95+), reflecting how exceptional that combination is.
How Category Fit Works
Your Untappd styles are matched to Systembolaget categories through exact style-to-category mapping (base score 100). Styles without a direct mapping produce no match on their own — enrichment and lookup fill the gap by attaching an Untappd style that does have a mapping.
The base score is then multiplied by a rank multiplier based on how high the style sits in your taste profile. Your top 2 styles stay at the full 1.00 multiplier. Ranks 3–5 step down gently (0.98 / 0.96 / 0.94), ranks 6–10 decay moderately (0.85–0.65), and ranks 11+ keep decaying by 0.05 per rank from 0.55, flooring at 0.30 by rank 17.
Formula: categoryScore = baseScore × rankMultiplier. The best-fitting style for each beer wins. The final Taste Score is then: max(categoryScore, scaledUntappdRating) × 0.6 + min(categoryScore, scaledUntappdRating) × 0.4 + combinedExcellenceBonus + clampedPreferences (clamped to 0–100), where clampedPreferences = priceBonus + abvBonus + styleNormAdjustment×10, with the negative side capped at −5.
4. Enrichment
For beers you haven't tried, the app searches Untappd to find the beer's global rating. Beers on the page you're currently viewing are prioritized so the top of the visible list fills in first as you scroll and paginate.
Results are cached locally with tiered TTLs: 7 days for found matches, 6 hours for not-found results, and 1 hour for errors. Enrichment results are also shared via a cloud cache so other users benefit from previous lookups.
For beers you've already checked in on Untappd, a separate lookup worker goes straight to the beer's Untappd page to confirm the match and pull your personal rating. This is more precise than search-based enrichment and marks the beer as tasted in the UI.
5. Shopping List Sharing
The shopping list lets you save beers and share them across devices or with friends using a sync code — an 8-character code generated automatically for each user.
How it works
Split mode preferences also sync across devices. No accounts needed — the code is all you need.
Beyond sharing
The shopping list also tracks what you've bought, what you've tasted (from Untappd check-ins), and which items are currently in Restock (temporarily out of stock). Group the list by any of those dimensions, bulk-remove items that are already bought, and get a celebration popup when a beer you saved becomes available at a selected store or returns from Restock.
6. Customization
Your Taste Score isn't fixed — you can shape it.
Styles
Add, remove, reorder, and reset the styles in your taste profile. Your explicit order overrides the natural (rating × volume) ranking, so if you want New England IPAs at the top regardless of how often you've checked them in, drag them there.
Filters
Every filter in the sidebar is a tri-state: Include (default, show everything), Only (show just these), or Exclude (hide these). This applies to personal labels like Tasted, List, and Bought, as well as product categories like Restock, New, and Multi-pack.
Scoring preferences
Price factor, ABV factor, and style normalization can each be dialled up, down, or off in Settings. The app re-scores all beers live when you change a preference so you can see the effect immediately.
Seasonal & Weather Experimental
An optional, opt-in scoring adjustment that nudges the Taste Score toward beers that fit the current season and today's weather at your location:
- Winter + cold / rainy: stouts, porters, barleywines, winter warmers, dubbels.
- Spring + sunny: pilsners, helles, wheat beers, pale ales, saisons, bocks — the first-outdoor-beer picks.
- Summer + warm / hot: wheat beers, lagers, pilsners, kölsch, gose, berliner weisse, sour / fruit beers.
- Autumn + mild: märzen / oktoberfest, amber, brown ale, IPA, saison.
Enable it on the Taste Profile page (Scoring Adjustments → Seasonal & Weather). It asks for browser location access, fetches current weather from Open-Meteo, caches the reading locally (1 h), and auto-refreshes while the tab is visible. Favoured beers pick up a ± bonus on their Taste Score and a ☀ badge on the home page; the Taste Score popup shows the per-beer reason. Flip it back to None any time to turn it off — no data leaves the browser except the weather coordinates.
Themes
The background gradient and ambient bubbles automatically adopt a colour palette matched to your top beer style — hoppy greens for IPA profiles, amber tones for pale ales, deep roasty browns for stouts, and so on across 12 beer-style theme families. You can also lock a specific theme (or pick Auto) from the Theme section in Settings.
7. Exploring the App
Beyond the main results list, the app surfaces its data in a few focused places:
- Taste Profile — your top styles, breweries and countries, coverage statistics, and a personal rationale explaining why the app ranks things the way it does.
- Statistics — catalog-wide numbers about the matched universe: tier distribution, cache coverage, average score, restocking and coming-soon counts. These numbers ignore the sidebar filters on purpose — they're facts about your matched catalog, not the filtered view.
- Release notes — changelog of every new feature, improvement, and bug fix, grouped by version with links back to the GitHub issues.
- Hint strip — contextual chips on the home page that suggest useful actions based on what you're looking at: offering to hide reported beers, surface a top style you haven't explored, re-include restocking items, or reset filters that have narrowed the list too far.
- Breadcrumb trail — a small trail above the results showing the search terms and filters you've applied, each with a one-click undo.
8. Keyboard Shortcuts
Quick navigation for power users:
9. License
UntappdBolaget is licensed under the Business Source License 1.1 (BSL 1.1). You may use the source code for personal, non-commercial purposes. Commercial use as a beer recommendation service requires a separate license.
The license automatically converts to the Apache License 2.0 on 2030-03-12, making the code fully open source from that date.
Full license text: LICENSE on GitHub
10. Privacy
Your data is stored locally in your browser (IndexedDB and localStorage). Requests to Untappd and Systembolaget are proxied through a Cloudflare Worker to handle CORS and API headers — the proxy does not log or store request data beyond short-lived caches.
If you use shopping list sync, your list is stored in Cloudflare KV under your sync code (auto-expires after 30 days of inactivity). Profile and enrichment data may be cached in Cloudflare KV to speed up lookups for all users. There are no accounts, no tracking, no analytics.
11. Feedback & Ideas
Have ideas for improvements, spotted a bug, or just want to say hello? We'd love to hear from you!
UntappdBolaget is an independent fan project and is not affiliated with, endorsed by, or sponsored by Untappd or Systembolaget. All Untappd ratings, beer data, brewery names, trademarks, and other third-party content remain the property of their respective owners.
If you are a rights holder or data owner and want content removed, please contact us and we will respond promptly.
