Contributing
How to contribute to the Country State City project.
Contributing Guide
We welcome contributions! Here's how to get started.
Fork and clone
git clone https://github.com/your-username/CountryStateCity.git
cd CountryStateCity/country-state-city
npm installCreate a branch
Use the naming convention:
feature/description— new featuresfix/description— bug fixesdocs/description— documentation changesrefactor/description— code refactoring
git checkout -b feature/add-new-dataMake your changes
- Run
npm run devfor development - Run
npm run lintto check code style - Run
npm testto run tests
Submit a pull request
Push your branch and open a PR against main.
Project Structure
| Directory | Purpose |
|---|---|
app/ | Next.js pages (documentation website) |
components/ | React components |
content/docs/ | MDX documentation files |
data/ | Raw JSON data files |
countrystatecity-npm/ | NPM package source |
countrystatecity-mcp/ | MCP server source |
lib/ | Shared utilities |
types/ | TypeScript interfaces |
Website-generated assets
The interactive map and country flags use generated, local browser assets. They are intentionally
not committed under public/vendor; npm run build:web recreates them before every production
build.
Use the focused commands while changing either integration:
npm run data:web-maplibre
npm run test:web-maplibre
npm run data:web-flags
npm run test:web-flagsThe MapLibre module worker is published as maplibre-gl-worker.js and imports
maplibre-gl-shared.js. Keep the .js paths: production servers commonly send unknown .mjs
files as application/octet-stream, and browsers reject module workers when
X-Content-Type-Options: nosniff is enabled. The flag generator creates one lowercase 4:3 SVG for
each of the 250 iso2 values.
After a self-hosted deployment, verify the public response types as well as the build output:
curl -I https://countrystatecity.tansuasici.com/vendor/maplibre/maplibre-gl-worker.js
# Content-Type: application/javascript
curl -I https://countrystatecity.tansuasici.com/vendor/flags/tr.svg
# Content-Type: image/svg+xmlThe CI matrix runs the focused asset checks on every pull request. A deployment is not complete
until the /map page creates a non-zero MapLibre canvas without console errors and a country result
resolves its /vendor/flags/{iso2}.svg background image.
Data Updates
Country, state, and city updates use a source-pinned staging pipeline. Do not edit production JSON files directly.
- Pin the upstream release, full commit SHA, asset sizes, and SHA-256 checksums in
data/sources/. - Add source-backed local corrections to
data/patches/overrides.json; never modify a cached raw source file. - Run
npm run test:data-syncto validate the source and patch manifests. - Run
npm run data:check-freshnessto confirm the manifest pins the current upstream release. - Run
npm run data:sync -- --check --verify-reproducibleto fetch, normalize, validate, diff, optimize, and shard the candidate dataset in.data-sync/. - Review the source, quality, schema, change, and output reports. Add
--record-reportto save a versioned copy underdata/sync-reports/. - Run
npm run test:data,npm test, and the relevant builds before publishing.
Use --offline to reproduce a run from checksum-verified cached assets. A failed checksum or
quality gate exits before any production data file can be written.
Production apply remains an explicit release-maintainer action. It runs only after the identity report passes and the pinned source manifest enables apply; normal contribution intake cannot write canonical production files.
Do not add data with an unknown source or license. Include a stable upstream revision or release, retrieval date, and compatible license in the provenance registry.
Suggest a data correction
Use Suggest a correction on a selected map record, or open the repository's Data correction Issue Form. A GitHub account is required; anonymous submissions are disabled so rate limits, duplicate detection, review decisions, and attribution remain auditable.
The form requires the stable public ID, old and proposed values, a stable HTTPS source, source
license, explanation, and contributor attestation. Automated intake rejects missing sources,
unchanged values, mismatched IDs, blocked redirect/local URLs, incompatible form values, and
duplicate or rate-limited submissions. A passing proposal receives the data-correction:review
label; it is not production data.
Maintainers verify the evidence and license, record a reviewer and decision, then convert an accepted proposal into a reviewed JSON record. Apply it with:
npm run contribution:apply -- path/to/reviewed-proposal.json
npm run contribution:metrics
npm run test:contributionsThe apply command checks that reviewed old values still match canonical data, then links the accepted correction to all three durable records:
data/patches/overrides.json— source-backed production overlay;data/contributions/ledger.json— contributor, source, reviewer, timestamps, issue, and decision;data/contributions/CHANGELOG.md— human-readable correction history.
First-response and final-decision SLA targets are 72 and 168 hours. Acceptance, rejection, and SLA
compliance are generated in data/contributions/metrics.json from the audit ledger.
License
Source code is licensed under MIT. The country/state/city derivative database is made available under ODbL 1.0. See Data License & Attribution.