CSV and TSV
Plain-text tabular data. Mapshaper treats CSV/TSV as pure attribute data by default, or as a point layer when longitude and latitude columns are present. Combined with -join, CSV is the lowest-friction way to attach external attributes (population, election results, anything keyed on a stable id) to a geometry layer.
File extensions: .csv, .tsv · Read: ✓ · Write: ✓ · Multi-layer: no
CLI examples
mapshaper data.csv -info
mapshaper data.csv -points x=lon y=lat -o points.geojson
mapshaper big.csv csv-fields=id,name,pop -info
mapshaper provinces.shp -drop-table -o stats.csv
mapshaper data.csv -o delimiter=";" out.csv
Format-specific input options
encoding=— text encoding. Default is UTF-8.string-fields=— comma-separated list of fields to import as strings even if their values look numeric. Usestring-fields=*to import every field as a string. Essential for ZIP codes, FIPS codes and anything else where leading zeros matter.field-types=— per-field type hints, e.g.FIPS:str,population:num. More flexible alternative tostring-fields=.csv-skip-lines=— skip N lines at the top of the file. Useful for spreadsheet exports with notes above the data.csv-lines=— import only the first N data rows.csv-field-names=— assign explicit field names. Combine withcsv-skip-lines=1to override existing headers.csv-fields=— import only the named columns. Filtering happens during the read, so this option dramatically reduces peak memory for wide CSVs.csv-filter=— a JavaScript expression evaluated per row. Rows that return false are dropped before they ever reach the layer.csv-dedup-fields— rename duplicate column headers (otherwise Mapshaper errors out).decimal-comma— parse numbers using1.000,01European convention instead of1,000.01.
Format-specific output options
encoding=— text encoding for the output. Default is UTF-8.delimiter=— override the field delimiter, e.g.delimiter="|".decimal-comma— emit numbers using the European decimal-comma convention.field-order=ascending— sort columns alphabetically.
Practical notes
- The delimiter is auto-detected from the extension (
.csv→ comma,.tsv→ tab). Use-i format=csvto force CSV parsing for a differently-named file (e.g..txt). - When exporting non-point geometry to CSV, Mapshaper writes only the attribute table. Use
-pointsfirst if you want to export point coordinates aslon/latcolumns. - BOM-prefixed files (typically from Excel) are handled transparently on read.
- Output has no quoting unless a value contains the delimiter, a quote or a newline.
Importing identifier-like fields (ZIP, FIPS, phone numbers…)
This is the single biggest CSV footgun. Mapshaper guesses each column's type from its values, so a column of US ZIP codes like 02134, 90210, 10001 looks numeric and gets imported as numbers — silently stripping leading zeros and breaking any subsequent join. The same applies to FIPS codes, phone numbers, account numbers and any other identifier that happens to contain only digits.
Always declare these columns as strings on import:
mapshaper -i counties.csv string-fields=GEOID,STATEFP,COUNTYFP -info
mapshaper -i zips.csv string-fields=zipcode -join points key=zipcode,zipcode
If you don't trust the schema at all, string-fields=* imports every column as a string. You can also be precise with field-types=:
mapshaper -i data.csv field-types=GEOID:str,population:num,year:str -info
A symptom of getting this wrong is a join silently dropping all rows because 02134 (string) doesn't match 2134 (number).
Prefiltering large CSVs
For multi-gigabyte CSVs — election precinct records, OSM extract attribute tables, parcel data — it usually isn't viable to load the whole file into memory and then filter. Mapshaper has two options that filter during the read, before the data lands in a layer:
csv-fields=— keep only the named columns. Wide CSVs (hundreds of columns, only a few of interest) shrink dramatically.csv-filter=— a JavaScript expression evaluated per row. Rows that return false are skipped.
Example (note that numerical fields have not been converted from strings at this point):
mapshaper -i big.csv \
csv-fields=GEOID,name,population,state \
csv-filter='state == "TX" && population > "10000"' \
-o cities-tx.csv
In the web app
The same import options work in the web app. Tick with advanced options in the import dialog and pass any of string-fields=, field-types=, encoding=, csv-fields=, csv-filter= etc. as you would on the CLI:
string-fields=GEOID,STATEFP encoding=utf8
For very large CSVs, csv-fields= and csv-filter= are the most useful options for keeping memory under control. If a file is too big for the browser to load, the mapshaper-xl CLI is the fallback.
External resources
- RFC 4180: Common Format and MIME Type for CSV — the closest thing to a CSV specification, though many real-world files diverge from it.
- Frictionless CSV Dialect spec — a practical schema for declaring how a particular CSV file is formatted (delimiter, quoting, line terminator).