An International Tip Calculator β Because Tipping Customs Are Wildly Different
In the US, 18% is the minimum you can leave without feeling guilty. In Japan, handing a waiter cash is confusing at best and insulting at worst. In Germany, you round up to the nearest euro. In China, it's technically illegal in some hotels. A tip calculator needs to know which country you're in to give useful advice β not just a number.
Tipping is one of those travel quirks that sneaks up on you. This calculator has presets for 14 countries with culturally-appropriate tip ranges and explanations in both Japanese and English.
π Live demo: https://sen.ltd/portfolio/tip-calc/
π¦ GitHub: https://github.com/sen-ltd/tip-calc
Features:
- 14 country presets (US, JP, DE, FR, GB, IT, ES, AU, CA, CN, IN, AE, KR, BR)
- Currency-aware formatting via Intl.NumberFormat
- Country-specific tip ranges and cultural notes
- Round up to nearest currency unit
- Even split among N people
- Japanese / English UI
- Dark / light theme
- Zero dependencies, 33 tests
Country presets
export const COUNTRIES = [
{
code: 'US',
name: { en: 'United States', ja: 'γ’γ‘γͺγ«' },
currency: 'USD',
locale: 'en-US',
typicalTip: [15, 20],
defaultTip: 18,
note: {
en: '15-20% is standard. Even bad service gets 10%+. Bars: $1-2 per drink.',
ja: '15-20% γζ¨ζΊγζͺγγ΅γΌγγΉγ§γ 10% δ»₯δΈγζ
£δΎγγγΌγ― $1-2/γγͺγ³γ―',
},
},
{
code: 'JP',
name: { en: 'Japan', ja: 'ζ₯ζ¬' },
currency: 'JPY',
locale: 'ja-JP',
typicalTip: [0, 0],
defaultTip: 0,
note: {
en: 'No tipping. Attempting to tip is often refused and may be seen as rude.',
ja: 'γγγζεγͺγγζΈ‘γγγ¨γγγ¨ε°ζγγγ',
},
},
// ... 12 more
];
Each country has its own locale for number formatting, its own default tip (zero for Japan), and a note explaining the local custom. The note is the most important field β a traveler who sees "US: 18%" and "Japan: 0%" learns something that actually affects their next meal.
Intl.NumberFormat for currency
Different currencies have different conventions. JPY has no decimal places. USD uses comma thousands separators. EUR uses period as thousands separator in most locales. Intl.NumberFormat handles all of this:
export function formatCurrency(amount, currency, locale) {
const isZeroDecimal = currency === 'JPY' || currency === 'KRW';
return new Intl.NumberFormat(locale, {
style: 'currency',
currency,
minimumFractionDigits: isZeroDecimal ? 0 : 2,
maximumFractionDigits: isZeroDecimal ? 0 : 2,
}).format(amount);
}
The zero-decimal check is necessary because Intl defaults to 2 decimal places even for JPY, producing wrong-looking output like Β₯1,500.00. Japanese currency has no sub-yen units in practice.
Round up to nearest
Rounding a tip up to a convenient amount is a common request β pay Β₯4500 for a Β₯4321 bill:
export function roundUp(amount, to) {
if (to === 0) return amount;
return Math.ceil(amount / to) * to;
}
Divide, ceil, multiply. roundUp(4321, 100) β 4400. roundUp(4321, 500) β 4500. Users choose the rounding base (1, 5, 10, 100, 500, 1000) from a dropdown.
Even split with precision
export function splitEven(total, people) {
if (people <= 0) return 0;
// Floor to 2 decimal places so each person pays a "clean" amount
return Math.floor((total / people) * 100) / 100;
}
Note: Math.floor, not round. If 3 people split $100, each pays $33.33 (total: $99.99). The 1Β’ remainder is absorbed by whoever initiates the transfer. Better than $33.34 Γ 3 = $100.02 where the group collectively overpays.
Tipping notes in context
The educational aspect: what makes this tool different from the hundreds of generic tip calculators is that it TEACHES. Japanese people visiting the US benefit from seeing "You should leave 15-20%". Americans visiting Japan benefit from seeing "Do not tip".
Each country's note renders prominently below the calculator. Travelers can pick their destination and skim the customs before their first meal there.
Series
This is entry #97 in my 100+ public portfolio series.
- π¦ Repo: https://github.com/sen-ltd/tip-calc
- π Live: https://sen.ltd/portfolio/tip-calc/
- π’ Company: https://sen.ltd/





![Defluffer - reduce token usage π by 45% using this one simple trick! [Earthday challenge]](https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiekbgepcutl4jse0sfs0.png)







