Short answer

A "shapefile" is not a file — it is a small collection of files sharing one base name, where each member holds one part of the dataset. The geometry, the geometry index, the attribute table, and the coordinate reference system each live in their own file (.shp, .shx, .dbf, .prj). This sidecar design dates from the early 1990s, predates modern self-describing containers, and is the reason an incomplete transfer silently breaks a layer.

The mandatory three, plus the ones that matter

Per the Esri Shapefile Technical Description, three files are mandatory and several others are common:

  • .shp — geometry. The main file. It stores each feature's shape as a record: a point, polyline, polygon, or multipart variant, with a header declaring the shape type (e.g. type 1 = Point, type 3 = PolyLine, type 5 = Polygon) and the layer bounding box. All features in one shapefile must be the same shape type.
  • .shx — shape index. A fixed-length index giving the byte offset and length of each record in the .shp. It lets software jump directly to feature N instead of scanning. If it is missing or stale, many tools refuse to open the layer; some can rebuild it.
  • .dbf — attribute table. A dBASE IV table, one row per feature, in the same order as the geometry records. This is where your fields live. The dBASE format is what imposes shapefile's harshest limits (see below).
  • .prj — projection. A single line of WKT describing the coordinate reference system. It is technically optional, but without it the data has no declared CRS and any other GIS must guess. Treat it as mandatory.
  • .cpg — code page. A tiny text file naming the character encoding of the .dbf (e.g. UTF-8 or ISO-8859-1). Without it, accented and non-Latin text is frequently mangled.
  • .sbn / .sbx — Esri's spatial index (optional, for faster spatial queries).
  • .qix — a quadtree spatial index used by GDAL/MapServer.
  • .fix — feature-ID index used by some tools.
  • .shp.xml — metadata in XML.

The link between them is purely the shared base name and same directory. Rename roads.shp to streets.shp without renaming roads.dbf and the layer breaks, because the format has no internal manifest tying the parts together.

Why this design, and why its limits bite

The shapefile predates SQLite, GeoPackage, and even widespread XML. Splitting concerns into fixed-format files made each one simple to read with 1990s code. But the .dbf attribute table carries dBASE-era constraints that still surprise people:

  • Field names are limited to 10 characters and get silently truncated on export. population_density becomes populatio, and two long names can collide.
  • Field types are limited (numeric, character, date, logical). There is no native boolean nuance, no proper time, and no support for NULL in a clean way — empty numerics often read as 0.
  • Numeric precision is capped by the field width you declared, so long IDs can overflow.
  • The 2 GB ceiling applies to both .shp and .dbf because offsets are 32-bit.
  • Encoding is fragile unless a .cpg accompanies the .dbf.

None of this matters until a handoff exposes it — which is exactly why format choice is part of data quality, not a detail.

Field example: the email that breaks

A colleague emails only parcels.shp. You double-click it and one of three things happens: it will not open at all (no .shx), it opens as bare geometry with no attribute table (no .dbf), or it opens but every tool warns "unknown CRS" and overlays it in the wrong place (no .prj). The dangerous case is the partial open, because the map looks fine while the attributes or projection are quietly absent.

Inspecting and packaging correctly

Use ogrinfo to confirm a layer is complete and to read its CRS and field schema before you trust or send it:

ogrinfo -so parcels.shp parcels
# Shows geometry type, feature count, extent, SRS (from .prj), and fields

To package for delivery, zip the whole sidecar set so it cannot be separated in transit:

zip parcels.zip parcels.shp parcels.shx parcels.dbf parcels.prj parcels.cpg

Most GIS, and GDAL via the /vsizip/ virtual filesystem, can read the zip directly — and a zip is impossible to send "half complete."

The better alternative for handoff

When you control the format, prefer a GeoPackage. It is an OGC standard that puts geometry, attributes, CRS, multiple layers, and spatial indexes inside a single SQLite .gpkg file — no sidecars, no 10-character field names, full UTF-8, proper field types, and no 2 GB practical limit. Convert with one command:

ogr2ogr -f GPKG parcels.gpkg parcels.shp

For web delivery, GeoJSON (RFC 7946) is also single-file and self-describing, though it is verbose and best for smaller vector layers rather than heavy analytical datasets, which belong in a database such as PostGIS.

Validation before delivery

  • Run ogrinfo -so and confirm geometry type, feature count, CRS (a real WKT, not "unknown"), and field schema all read as expected.
  • Open the layer in a fresh project on another machine to catch missing sidecars.
  • Check that accented or non-Latin attribute text displays correctly; if not, your .cpg/encoding is wrong.
  • If field names were truncated on export, decide whether the recipient needs the full names — and if so, switch to GeoPackage.

Common pitfalls and why they happen

  • Sending only .shp. It is the largest, most "file-like" member, so people assume it is the whole dataset. It is not.
  • Renaming one member. The parts are bound only by name; rename them as a set or not at all.
  • Losing the .prj. The data still opens, so the loss is invisible until features overlay wrong or measurements fail.
  • Ignoring .cpg. Accents survive on the author's machine (whose default code page matches) and break on the recipient's — a classic "works for me" trap.

Bathyl perspective

We treat a shapefile handoff as complete only when the full sidecar set is verified and zipped, and we default to GeoPackage whenever we control both ends. A dataset that opens on one machine but is missing its .prj or .cpg is not delivered — it is a future support ticket. The packaging discipline is as much part of the deliverable as the geometry itself.

Related reading

Sources