EU VAT Rates Data
Rates for 44 European countries — plus VAT number format descriptions and built-in format validation for every country. Sourced daily from the European Commission TEDB. MIT licensed.
EU VAT Rates 2026
Standard, reduced, and super-reduced rates for all 27 EU member states. Data sourced daily from the European Commission TEDB. Last updated: 30.03.2026.
| Country | Standard | Reduced | Super Reduced |
|---|---|---|---|
| ATAustria | 20% | 10%, 13%, 19% | — |
| BEBelgium | 21% | 6%, 12% | — |
| BGBulgaria | 20% | 9% | — |
| HRCroatia | 25% | 5%, 13% | — |
| CYCyprus | 19% | 5%, 9% | 3% |
| CZCzech Republic | 21% | 12% | — |
| DKDenmark | 25% | — | — |
| EEEstonia | 24% | 9%, 13% | — |
| FIFinland | 25.5% | 10%, 13.5% | — |
| FRFrance | 20% | 0.9%, 1.05%, 5.5%, 8.5%, 10%, 13% | 2.1% |
| DEGermany | 19% | 7% | — |
| GRGreece | 24% | 6%, 13%, 17% | 4% |
| HUHungary | 27% | 5%, 18% | — |
| IEIreland | 23% | 9%, 13.5% | — |
| ITItaly | 22% | 5%, 10% | 4% |
| LVLatvia | 21% | 5%, 12% | — |
| LTLithuania | 21% | 5%, 12% | — |
| LULuxembourg | 17% | 8%, 14% | 3% |
| MTMalta | 18% | 5%, 7% | — |
| NLNetherlands | 21% | 9% | — |
| PLPoland | 23% | 5%, 8% | 8% |
| PTPortugal | 23% | 6%, 13%, 16%, 22% | 6% |
| RORomania | 21% | 11% | — |
| SKSlovakia | 23% | 5%, 19% | — |
| SISlovenia | 22% | 5%, 9.5% | — |
| ESSpain | 21% | 10% | 4% |
| SESweden | 25% | 6%, 12% | — |
Rates are indicative. Some countries apply additional territorial variants (e.g. French overseas departments, Portuguese Azores). Always verify with the relevant tax authority for invoicing purposes.
VAT Number Formats & Validation
Every country includes a human-readable format description and a regex pattern for local format validation. Use the built-in validateFormat() function — no API key, no network call.
import { validateFormat } from 'eu-vat-rates-data'
validateFormat('ATU12345678') // true
validateFormat('DE123456789') // true
validateFormat('INVALID') // false| Country | Format | Pattern |
|---|---|---|
| ALAlbania | AL + 1 letter + 8 digits + 1 letter | ^AL[A-Z]\d{8}[A-Z]$ |
| ADAndorra | AD + alphanumeric | no standard format |
| ATAustria | ATU + 8 digits | ^ATU\d{8}$ |
| BEBelgium | BE + 0/1 + 9 digits | ^BE[01]\d{9}$ |
| BABosnia and Herzegovina | BA + alphanumeric | no standard format |
| BGBulgaria | BG + 9–10 digits | ^BG\d{9,10}$ |
| HRCroatia | HR + 11 digits | ^HR\d{11}$ |
| CYCyprus | CY + 8 digits + 1 letter | ^CY\d{8}[A-Z]$ |
| CZCzech Republic | CZ + 8–10 digits | ^CZ\d{8,10}$ |
| DKDenmark | DK + 8 digits | ^DK\d{8}$ |
| EEEstonia | EE + 9 digits | ^EE\d{9}$ |
| FIFinland | FI + 8 digits | ^FI\d{8}$ |
| FRFrance | FR + 2 alphanumeric + 9 digits | ^FR[A-HJ-NP-Z0-9]{2}\d{9}$ |
| GEGeorgia | GE + alphanumeric | no standard format |
| DEGermany | DE + 9 digits | ^DE\d{9}$ |
| GRGreece | EL + 9 digits | ^EL\d{9}$ |
| HUHungary | HU + 8 digits | ^HU\d{8}$ |
| ISIceland | IS + 5–6 digits | ^IS\d{5,6}$ |
| IEIreland | IE + 7 digits + 1–2 letters | ^IE\d{7}[A-W][A-IW]?$|^IE\d[A-Z+*]\d{5}[A-W]$ |
| ITItaly | IT + 11 digits | ^IT\d{11}$ |
| XKKosovo | XK + alphanumeric | no standard format |
| LVLatvia | LV + 11 digits | ^LV\d{11}$ |
| LILiechtenstein | LI + alphanumeric | no standard format |
| LTLithuania | LT + 9 or 12 digits | ^LT(\d{9}|\d{12})$ |
| LULuxembourg | LU + 8 digits | ^LU\d{8}$ |
| MTMalta | MT + 8 digits | ^MT\d{8}$ |
| MDMoldova | MD + alphanumeric | no standard format |
| MCMonaco | MC + alphanumeric | no standard format |
| MEMontenegro | ME + 8 digits | ^ME\d{8}$ |
| NLNetherlands | NL + 9 digits + B + 2 digits | ^NL\d{9}B\d{2}$ |
| MKNorth Macedonia | MK + 13 digits | ^MK\d{13}$ |
| NONorway | NO + 9 digits + MVA | ^NO\d{9}MVA$ |
| PLPoland | PL + 10 digits | ^PL\d{10}$ |
| PTPortugal | PT + 9 digits | ^PT\d{9}$ |
| RORomania | RO + 2–10 digits | ^RO\d{2,10}$ |
| RSSerbia | RS + 9 digits | ^RS\d{9}$ |
| SKSlovakia | SK + 10 digits | ^SK\d{10}$ |
| SISlovenia | SI + 8 digits | ^SI\d{8}$ |
| ESSpain | ES + letter/digit + 7 digits + letter/digit | ^ES[A-Z0-9]\d{7}[A-Z0-9]$ |
| SESweden | SE + 12 digits | ^SE\d{12}$ |
| CHSwitzerland | CHE + 9 digits (+ MWST/TVA/IVA) | ^CHE\d{9}(MWST|TVA|IVA)?$ |
| TRTurkey | TR + 10 digits | ^TR\d{10}$ |
| UAUkraine | UA + 12 digits | ^UA\d{12}$ |
| GBUnited Kingdom | GB + 9 or 12 digits (or GD/HA + 3 digits) | ^GB(\d{9}|\d{12}|GD\d{3}|HA\d{3})$ |
Note: Greece uses the "EL" prefix in VAT numbers, not "GR". Format validation checks the local format only — use the vatnode API to verify against the official VIES database.
Quick Start
Pick your language and copy-paste to get started.
npm install eu-vat-rates-dataimport { getRate, getStandardRate, getAllRates, isEUMember, validateFormat, dataVersion } from 'eu-vat-rates-data'
// Get full record for a country
const fi = getRate('FI')
console.log(fi.standard) // 25.5
console.log(fi.reduced) // [10,13.5]
console.log(fi.eu_member) // true
console.log(fi.vat_abbr) // 'ALV'
console.log(fi.format) // 'FI + 8 digits'
console.log(fi.pattern) // '^FI\d{8}$'
// Shorthand for the standard rate
const de = getStandardRate('DE') // 19
// Iterate all 44 countries
const all = getAllRates()
for (const [code, rate] of Object.entries(all)) {
console.log(`${code}: ${rate.standard}%`)
}
// VAT number format validation — free, no API key
validateFormat('FI12345678') // true
validateFormat('INVALID') // false
// Type guards
isEUMember('NO') // false — Norway is in dataset but not EU
isEUMember('DE') // true
// Dataset freshness
console.log(`Rates as of ${dataVersion}`) // 2026-03-30Everything you need, nothing you don't
A self-contained dataset — no network calls, no rate limits, no account.
44 Countries
EU-27 plus Norway, Switzerland, UK, Turkey, Ukraine and 10 more non-EU European countries.
6 Languages
Native packages for JavaScript/TypeScript, Python, PHP, Go, Ruby, and a WordPress plugin.
Updated Daily
GitHub Actions fetches fresh rates from the EC TEDB every morning and publishes automatically.
TypeScript Types
Full type safety with CountryCode, VatRate, and helper type guards included.
VAT Format Validation
Every country includes a format description and regex pattern. Built-in validateFormat() — free, no API key.
What's in the dataset
Each country record contains the following fields.
standardStandard VAT rate in percent (e.g. 25.5)reducedReduced rates, sorted ascending. Empty array when none.super_reducedSuper-reduced rate applied to a narrow set of essentials.parkingTransitional parking rate. Null for most countries.eu_memberWhether this is an EU-27 member state.currencyISO 4217 currency code (EUR for eurozone).vat_nameLocal name of the tax (e.g. 'Arvonlisävero').vat_abbrShort abbreviation (e.g. 'ALV', 'MwSt', 'TVA').formatHuman-readable VAT number format (e.g. 'ATU + 8 digits'). Unique to this package.uniquepatternRegex string for VAT number format validation (e.g. '^ATU\\d{8}$'). Null for countries without a standard format. Unique to this package.unique{
"country": "Finland",
"currency": "EUR",
"eu_member": true,
"vat_name": "Arvonlisävero",
"vat_abbr": "ALV",
"standard": 25.5,
"reduced": [
10,
13.5
],
"super_reduced": null,
"parking": null,
"format": "FI + 8 digits",
"pattern": "^FI\\d{8}$"
}Available packages
All packages ship the same dataset — pick the one for your stack.
WordPress / WooCommerce
Canonical dataset repo
Raw JSON data, update scripts, and GitHub Actions workflow for all packages.
Need VAT number validation too?
The vatnode API validates EU VAT numbers against the official VIES database — real-time, with caching and webhook support.