npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

Iโ€™ve always been into building performant and accessible sites, but lately Iโ€™ve been taking it extremely seriously. So much so that Iโ€™ve been building a tool to help me optimize and monitor the sites that I build to make sure that Iโ€™m making an attempt to offer the best experience to those who visit them. If youโ€™re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, ๐Ÿ‘‹, Iโ€™m Ryan Hefnerย  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If youโ€™re interested in other things Iโ€™m working on, follow me on Twitter or check out the open source projects Iโ€™ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soonโ€“ish.

Open Software & Tools

This site wouldnโ€™t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you ๐Ÿ™

ยฉ 2026 โ€“ย Pkg Stats / Ryan Hefner

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

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 search

Data 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 capitals

Form 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 CAPs

Utility 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