italian-cap-comuni-province
v1.1.0
Published
๐ฎ๐น Complete TypeScript library for Italian locations: municipalities, provinces, postal codes with advanced search and autocomplete
Downloads
266
Maintainers
Readme
Italian CAP Comuni Province
๐ฎ๐น Complete TypeScript library for Italian locations: municipalities, provinces, postal codes with advanced search and autocomplete
A lightweight, performant TypeScript library providing access to all Italian municipalities, provinces, and regions with intelligent search capabilities, CAP validation, and autocomplete support.
โจ Features
- ๐ High Performance: Optimized searches with in-memory indices (O(1) lookups)
- ๐ฆ Tree-shakable: Import only what you need
- ๐ Smart Search: Advanced algorithms with relevance scoring (Jaro-Winkler similarity)
- ๐ฏ TypeScript Native: Full type safety and IntelliSense support
- ๐ฑ Zero Dependencies: No external libraries required
- ๐ Dual ESM/CJS: Supports both module formats
- ๐ Always Updated: Data synced with official ISTAT sources
- ๐ฏ Form Helpers: Deduplicated data perfect for dropdowns and forms
- ๐ฎ Postal Code APIs: Get all CAP codes for any commune
- ๐ท๏ธ Unique Communes: No duplicates, perfect for UI components
๐ฆ Installation
npm install italian-cap-comuni-province
# or
yarn add italian-cap-comuni-province
# or
pnpm add italian-cap-comuni-province๐ Quick Start
import {
searchComuni,
getComuniByCAP,
isValidCAP,
} from 'italian-cap-comuni-province';
// Search municipalities by name
const results = searchComuni('Milano', { limit: 5 });
console.log(results.item.nome); // "Milano"
// Find municipalities by postal code
const comuni = getComuniByCAP('20100');
console.log(comuni.nome); // "Milano"
// Validate Italian postal codes
console.log(isValidCAP('20100')); // true
console.log(isValidCAP('99999')); // false๐ Advanced Search
import {
searchComuni,
searchComuniWithFilters,
} from 'italian-cap-comuni-province';
// Search with options
const results = searchComuni('Rom', {
exactMatch: false, // partial search (default)
limit: 10, // max 10 results
soloCapoluoghi: true, // only provincial capitals
});
// Search with geographical filters
const filteredResults = searchComuniWithFilters(
'San',
{
regione: 'Lombardia',
provincia: 'Milano',
},
{ limit: 5 },
);๐๏ธ Working with Provinces and Regions
import {
getAllProvince,
getComuniByProvincia,
getComuniByRegione,
getCapoluoghi,
getProvinceByRegione,
getComuniUniqueByProvincia,
getCapsByComune,
getCapsByComuneNome,
} from 'italian-cap-comuni-province';
// Get all provinces (alphabetically sorted)
const province = getAllProvince();
// Municipalities by province
const comuniMilano = getComuniByProvincia('Milano'); // or 'MI'
// Municipalities by region
const comuniLombardia = getComuniByRegione('Lombardia');
// Get provinces in a region (alphabetically sorted)
const provinceLombardia = getProvinceByRegione('Lombardia');
// Only provincial capitals
const capoluoghi = getCapoluoghi();
// Get unique communes for forms (no CAP duplicates)
const uniqueComuni = getComuniUniqueByProvincia('Milano'); // or 'MI'
// Get all postal codes for a commune
const caps = getCapsByComune('015146'); // ISTAT code
// Handle communes with same name in different provinces
const results = getCapsByComuneNome('San Giovanni');๐๏ธ Form Integration & UI Helpers
Deduplicated Data for Forms
When building forms, you often need unique communes without CAP duplicates. These helper functions provide clean data for dropdowns and selects:
import {
getComuniUniqueByProvincia,
getCapsByComune,
getCapsByComuneNome,
getComuneWithAllCaps,
} from 'italian-cap-comuni-province';
// Get unique communes for a province (no CAP duplicates)
const uniqueComuni = getComuniUniqueByProvincia('MI');
console.log(uniqueComuni.length); // No duplicates, perfect for dropdowns
// Get all postal codes for a specific commune
const caps = getCapsByComune('015146'); // Milano ISTAT code
console.log(caps); // ['20100', '20121', '20122', ...] - all Milan postal codes
// Get postal codes by commune name (handles homonyms)
const results = getCapsByComuneNome('San Giovanni');
results.forEach((result) => {
console.log(
`${result.comune.nome} (${
result.comune.siglaProvincia
}): ${result.caps.join(', ')}`,
);
});
// Get complete commune data with all its postal codes
const communeData = getComuneWithAllCaps('015146');
if (communeData) {
console.log(
`${communeData.comune.nome} has ${communeData.caps.length} postal codes`,
);
}Complete React Form Example
import React, { useState, useEffect } from 'react';
import {
getAllProvince,
getComuniUniqueByProvincia,
getCapsByComune,
type Comune,
} from 'italian-cap-comuni-province';
function AddressForm() {
const [selectedProvincia, setSelectedProvincia] = useState('');
const [selectedComune, setSelectedComune] = useState<Comune | null>(null);
const [availableCAPs, setAvailableCAPs] = useState<string[]>([]);
// Load provinces
const province = getAllProvince();
// Load unique communes when province changes
const comuni = selectedProvincia
? getComuniUniqueByProvincia(selectedProvincia)
: [];
// Load postal codes when commune changes
useEffect(() => {
if (selectedComune) {
const caps = getCapsByComune(selectedComune.codiceIstat);
setAvailableCAPs(caps);
} else {
setAvailableCAPs([]);
}
}, [selectedComune]);
return (
<form>
{/* Province Dropdown */}
<select
value={selectedProvincia}
onChange={(e) => setSelectedProvincia(e.target.value)}
>
<option value="">Select Province</option>
{province.map((provincia) => (
<option key={provincia.sigla} value={provincia.sigla}>
{provincia.nome}
</option>
))}
</select>
{/* Communes Dropdown (no duplicates!) */}
<select
value={selectedComune?.codiceIstat || ''}
onChange={(e) => {
const comune = comuni.find((c) => c.codiceIstat === e.target.value);
setSelectedComune(comune || null);
}}
disabled={!selectedProvincia}
>
<option value="">Select Commune</option>
{comuni.map((comune) => (
<option key={comune.codiceIstat} value={comune.codiceIstat}>
{comune.nome}
</option>
))}
</select>
{/* Postal Codes Dropdown */}
<select disabled={!selectedComune}>
<option value="">Select Postal Code</option>
{availableCAPs.map((cap) => (
<option key={cap} value={cap}>
{cap}
</option>
))}
</select>
</form>
);
}๐ฎ Autocomplete
import { getSuggestions } from 'italian-cap-comuni-province';
// For implementing autocomplete
const suggestions = getSuggestions('Mil', 5);
// ['Milano', 'Milazzo', 'Militello in Val di Catania', ...]๐ Data Access
import comuniItaliani from 'italian-cap-comuni-province';
// Complete data access
const stats = comuniItaliani.getStats();
console.log(`Total municipalities: ${stats.totaleComuni}`);
// Single municipality by ISTAT code
const roma = comuniItaliani.getComuneByIstat('058091');
// All regions (alphabetically sorted)
const regioni = comuniItaliani.getAllRegioni();๐๏ธ Form Integration Example
import {
searchComuni,
isValidCAP,
getSuggestions,
} from 'italian-cap-comuni-province';
// React component example
function CityAutocomplete({ value, onChange }) {
const [suggestions, setSuggestions] = useState([]);
const handleInputChange = (query) => {
const results = getSuggestions(query, 10);
setSuggestions(results);
};
const handleCitySelect = (cityName) => {
const results = searchComuni(cityName, { exactMatch: true });
if (results.length > 0) {
const comune = results[0].item;
onChange({
comune: comune.nome,
provincia: comune.nomeProvincia,
cap: comune.cap,
regione: comune.nomeRegione,
});
}
};
// ... rest of component
}๐ TypeScript Types
interface Regione {
codiceRegione: string;
nome: string;
tipologia: string;
ripartizioneGeografica: string;
numeroProvince: number;
numeroComuni: number;
superficie: number; // in kmยฒ
}
interface Provincia {
codiceRegione: string;
sigla: string;
nome: string;
tipologia: string;
numeroComuni: number;
superficie: number; // in kmยฒ
codiceSovracomunale: string;
}
interface Comune {
codiceIstat: string;
nome: string;
nomeAlternativo?: string;
cap: string;
codiceBelfiore: string;
siglaProvincia: string;
nomeProvincia: string;
codiceRegione: string;
nomeRegione: string;
tipologiaRegione: string;
ripartizioneGeografica: string;
isCapoluogo: boolean;
coordinate: {
lat: number;
lng: number;
};
superficie: number;
}
interface SearchOptions {
caseSensitive?: boolean;
exactMatch?: boolean;
limit?: number;
soloCapoluoghi?: boolean;
}
interface SearchResult<T> {
item: T;
score: number;
}
interface ComuneWithCaps {
comune: Comune;
caps: string[];
}How to use all interfaces:
// Working with the complete hierarchy
const regione: Regione = getAllRegioni()[0];
const province: Provincia[] = getProvinceByRegione(regione.nome);
const comuni: Comune[] = getComuniByProvincia(province[0].sigla);
console.log(
`${regione.nome} has ${regione.numeroProvince} provinces and ${regione.numeroComuni} municipalities`,
);
const regionePuglia: Regione = getRegioneByCode('16');
const provincePuglia: Provincia[] = getProvinceByCodeRegione(
regionePuglia.codiceRegione,
);
console.log(`${regionePuglia.nome} has ${regionePuglia.numeroProvince}`);๐ API Reference
Core Search Functions
searchComuni(query, options); // Search municipalities with scoring
searchProvince(query, options); // Search provinces
searchRegioni(query, options); // Search regions
searchComuniWithFilters(query, filters, options); // Advanced filtered searchData Access Functions
getAllRegioni(); // Get all regions (sorted)
getAllProvince(); // Get all provinces (sorted)
getComuniByProvincia(provincia); // Get all municipalities (with duplicates)
getComuniByRegione(regione); // Get municipalities by region
getCapoluoghi(); // Get only provincial capitalsForm Helper Functions โญ New
getComuniUniqueByProvincia(provincia); // Unique municipalities for dropdowns
getCapsByComune(codiceIstat); // All postal codes for a municipality
getCapsByComuneNome(nome); // Postal codes by municipality name
getComuneWithAllCaps(codiceIstat); // Complete municipality data with all CAPsUtility Functions
isValidCAP(cap); // Validate Italian postal codes
getSuggestions(query, limit); // Get autocomplete suggestionsโก Performance
- Bundle size: ~4MB compressed (complete dataset)
- Search speed: O(1) for CAP and ISTAT codes, O(n) optimized for names
- Memory footprint: ~20MB runtime (indices included)
- Tree-shaking: Full support, import only used functions
๐ Data Source
This library uses the comprehensive Italian municipalities database provided by Garda Informatica.
The database includes:
- 8,000+ Italian municipalities
- 110+ provinces and metropolitan cities
- 20 regions
- Postal codes (CAP)
- ISTAT codes
- Geographic coordinates
- Administrative boundaries
Data Features:
- โ Always Updated: Automatically synchronized with official ISTAT sources
- โ Complete: All Italian administrative divisions
- โ Free: Released under MIT license
- โ Reliable: Used by professionals and developers
๐ Credits
Special thanks to Garda Informatica for providing and maintaining this comprehensive, free, and always up-to-date database of Italian municipalities. Their automated procedures ensure the data stays current with official ISTAT sources.
Visit their website: https://www.gardainformatica.it/database-comuni-italiani
๐ Data Updates
The underlying data is regularly updated from official ISTAT sources. New versions of this library are released when significant administrative changes occur (new municipalities, province modifications, etc.).
##ย ๐ Changelog
v1.1.0 - Province autonome and data updated
- Data update to 2026-31-01
- Added getRegioniAndProvinceAutonome and getProvinceAutonome functions
v1.0.0 - Initial Release
- ๐ First stable release with complete Italian locations data
๐ License
MIT License - see LICENSE file
Original database by Garda Informatica is also released under MIT License.
๐ค Contributing
Contributions are welcome! Please open issues and pull requests.
๐ Links
Made with โค๏ธ for the Italian developer community
