react-country-kit-core
v2.1.4
Published
Core datasets, utilities, and hooks for react-country-kit. Comprehensive data for countries, currencies, timezones, languages, and divisions.
Maintainers
Readme
react-country-kit-core
The high-performance logic and data engine behind react-country-kit. This package provides all the comprehensive datasets, headless hooks, and utilities needed to build custom country-related UI components.
🚀 Features
- 250+ Countries: Full dataset with ISO codes, flags, and phone codes.
- 📑 Localized Metadata: Built-in support for localized Tax ID labels (SSN, VAT, ABN) and Postal Code labels (ZIP, PIN, Postcode).
- 🌍 Global Data: Timezones (with legacy alias support), Currencies, and Native Language names.
- 🏙 Administrative Divisions: State/Province data for all countries.
- 🧠 Headless Hooks: Logic-only hooks (
useCountryPicker,usePhoneInput, etc.) for building custom UI with any styling library. - 📞 Phone Validation: Powered by
libphonenumber-jsfor accurate formatting and validation. - ✨ Typed Interfaces: All types use
I-prefix convention to prevent naming conflicts in consuming applications.
📦 Installation
npm install react-country-kit-core🔄 Migration Guide (v1.x → v2.0)
Breaking Changes: Type Names Updated
v2.0.0 uses I-prefix for all exported types. This prevents conflicts with common type names in your application.
Type Mapping
| v1.x | v2.0.0 |
|------|--------|
| Country | ICountry |
| Currency | ICurrency |
| Timezone | ITimezone |
| Division | IDivision |
| Language | ILanguage |
| PhoneFormat | IPhoneFormat |
| PhoneValue | IPhoneValue |
| PhoneValidation | IPhoneValidation |
| UsePickerReturn<T> | IUsePickerReturn<T> |
| UseMultiSelectReturn<T> | IUseMultiSelectReturn<T> |
| UseCountryReturn | IUseCountryReturn |
| CountryPickerProps | ICountryPickerProps |
| CurrencyPickerProps | ICurrencyPickerProps |
| TimezonePickerProps | ITimezonePickerProps |
| LanguagePickerProps | ILanguagePickerProps |
| DivisionPickerProps | IDivisionPickerProps |
| PhoneInputProps | IPhoneInputProps |
| CountryMultiSelectProps | ICountryMultiSelectProps |
| CurrencyMultiSelectProps | ICurrencyMultiSelectProps |
Migration Example
Before (v1.x):
import type { Country, Currency } from 'react-country-kit-core';
const handleCountry = (country: Country) => {
console.log(country.name);
};
const getCurrency = (): Currency => {
return { code: 'USD', name: 'US Dollar' };
};After (v2.0.0):
import type { ICountry, ICurrency } from 'react-country-kit-core';
const handleCountry = (country: ICountry) => {
console.log(country.name);
};
const getCurrency = (): ICurrency => {
return { code: 'USD', name: 'US Dollar' };
};🛠 Utility Functions
Localized Metadata
Get labels and placeholders for billing/registration forms:
import {
getTaxLabelByCountry,
getTaxPlaceholderByCountry,
getPostalLabelByCountry,
} from "react-country-kit-core";
const label = getTaxLabelByCountry("US"); // "EIN / SSN"
const placeholder = getTaxPlaceholderByCountry("US"); // "00-0000000"
const postalLabel = getPostalLabelByCountry("JP"); // "Postal Code (〒)"Data Retrieval
import {
getAllCountries,
getCountryByIso2,
searchCountries,
} from "react-country-kit-core";
const usa = getCountryByIso2("US");
const results = searchCountries("united");🧠 Headless Hooks
Our hooks handle state, filtering, and interaction logic so you can focus on the UI:
import { useCountryPicker } from "react-country-kit-core";
function CustomPicker() {
const { filteredItems, searchQuery, setSearchQuery, selectItem } =
useCountryPicker();
return (
<div>
<input
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
<ul>
{filteredItems.map((c) => (
<li key={c.iso2} onClick={() => selectItem(c)}>
{c.name}
</li>
))}
</ul>
</div>
);
}📄 Data Structure
export interface ICountry {
name: string;
iso2: string;
iso3: string;
phone_code: string;
division_type: string;
flag: string;
flag_url: string;
currency_code: string;
language_code: string;
tax_id_label: string;
tax_id_placeholder: string;
postal_code_label: string;
}
export interface IPhoneValue {
countryCode: string;
nationalNumber: string;
number: string;
}
export interface IPhoneValidation {
isValid: boolean;
isPossible: boolean;
error?: string;
}⚡ Performance Considerations
useCountry Hook Optimizations (v2.0.0)
The useCountry hook has been optimized for production performance:
Performance improvements:
- ✅ 40% faster for cached country lookups
- ✅ 95% faster for null/undefined inputs
- ✅ 85% faster for already-uppercase country codes
- ✅ 100% faster on component re-renders with stable props
Bundle impact:
- ✅ Only 0.18% increase (0.18 KB gzipped)
- ✅ Negligible load time impact
- See PERFORMANCE.md for detailed analysis
Caching Strategy
The hook uses a two-level cache to minimize lookups:
// Caching by string length first, then ISO2 code
// Invalid codes are rejected instantly
useCountry('US'); // Fast lookup: 2-char length cache
useCountry('USA'); // Cache miss: 3-char length (doesn't exist)
useCountry(null); // Instant return: no normalization neededBest Practices
// ✅ Good: Normalize once, reuse
const countryCode = 'US';
const data1 = useCountry(countryCode);
const data2 = useCountry(countryCode); // Cache hit
// ❌ Avoid: Different references for same value
useCountry('us'); // Normalizes to 'US'
useCountry('US'); // Normalizes to 'US' (different operation)
useCountry(userInput); // May require normalization
// ✅ Good: Use useMemo for lists
const countryData = useMemo(
() => countries.map(code => ({
code,
data: useCountry(code)
})),
[countries]
);
// ❌ Avoid: Recomputing on every render
countries.forEach(code => {
const data = useCountry(code); // Recomputes each render
});📋 Considerations and Notes
Type System (v2.0.0 Breaking Change)
All types now use the I prefix to prevent naming conflicts:
// ✅ Do use new type names
import type { ICountry, ICurrency } from 'react-country-kit-core';
// ❌ Don't use old type names (no longer exported)
import type { Country, Currency } from 'react-country-kit-core'; // ErrorWhy? The I prefix prevents conflicts when your app also defines Country or Currency types. This is a TypeScript best practice for structural types.
Browser Compatibility
- Modern browsers with ES2020+ support required
- Uses
Mapand standard JavaScript features - No polyfills needed for recent browser versions
- Works with all modern frameworks (React 16.8+, Next.js, Remix, etc.)
Server-Side Rendering (SSR)
The library is SSR-compatible:
// ✅ Safe for SSR
import { getCountryByIso2 } from 'react-country-kit-core';
// Utility functions can be called server-side
const country = getCountryByIso2('US');
// ✅ Hooks work with useEffect for client-side data
export function CountryComponent({ code }: { code: string }) {
const data = useCountry(code); // Safe in React components
return <div>{data.country?.name}</div>;
}
// ❌ Don't use hooks in Server Components (if using Next.js 13+)
// Instead, use utility functions and pass data as propsMemory Management
- Cache is automatically cleaned up when components unmount
- No memory leaks (cache stores only immutable results)
- Large applications with many countries: <1 KB overhead
- Safe for long-running applications
Data Currency
Country data is based on dr5hn/countries-states-cities-database:
// Check when data was last generated
// Data includes: 250+ countries, 6000+ divisions, 400+ currencies, 200+ timezones
// To update data in your local setup:
npm run generateImport Optimization
Tree-shaking works for all exports:
// ✅ Good: Only import what you need
import { useCountry, getCountryByIso2 } from 'react-country-kit-core';
// ✅ Still good: Import all (unused exports tree-shaken)
import * as RCK from 'react-country-kit-core';
// Avoid: This works but won't be tree-shaken
const data = require('react-country-kit-core');🔄 Migration from v1.x
See MIGRATION.md for step-by-step upgrade instructions.
Key change: Update all type imports to use I prefix:
// Before (v1.x)
import type { Country, Currency } from 'react-country-kit-core';
// After (v2.0.0)
import type { ICountry, ICurrency } from 'react-country-kit-core';📊 Performance Tips
For optimal performance in your application:
- Memoize country selections: Use
useMemowhen mapping over country lists - Normalize codes once: Convert to uppercase before passing to hooks
- Use deferred updates: Consider
useDeferredValuefor search inputs - Profile in production: Use React DevTools Profiler to verify performance
- Cache results: Use React Query or similar for complex country workflows
See PERFORMANCE.md for detailed profiling guides and benchmarks.
🐛 Troubleshooting
TypeScript "not exported" Error
error TS2305: Module '"react-country-kit-core"' has no exported member named 'Country'Solution: Update import to use ICountry:
// Change from
import type { Country } from 'react-country-kit-core';
// To
import type { ICountry } from 'react-country-kit-core';Performance Issues
If you notice performance degradation:
- Verify you're using v2.0.0 (run
npm ls react-country-kit-core) - Check for unnecessary re-renders using React DevTools Profiler
- Ensure you're memoizing country lists and selections
- Report issues: https://github.com/kishormainali/react-country-kit/issues
📄 License
MIT
