Getting started

For developers

Read, validate and write .well files from code, what the schema guarantees, and which parts of the spec matter most when you build on the format.

A .well file is a JSON object with a fixed set of top-level blocks. You can read it with any JSON parser and validate it with the published JSON Schema in any language. In TypeScript or JavaScript, @welldot/core gives you types, validation that matches the spec, and the v1 upgrade.

Read and validate in TypeScript

pnpm add @welldot/core
read.ts
import { readFile } from 'node:fs/promises';
import { parseWell, type Well } from '@welldot/core';

const text = await readFile('PT-01.well', 'utf8');

// Throws a ZodError (with a path for each problem) when the file is invalid.
// A version 1 file is upgraded to v2 on the way in.
const well: Well = parseWell(text);

console.log(well.name, well.bore_hole.length, well.lithology.length);

Parsing and validating covers the error shape, safeParse and legacy files. Serializing and sharing covers writing a file back.

Validate in other languages

The JSON Schema (draft 2020-12) is published at a stable URL:

https://welldot.org/schema/v2/well.schema.json

Any JSON Schema validator can use it, for example ajv in JavaScript, jsonschema in Python or santhosh-tekuri/jsonschema in Go. The schema is generated from the Zod validators of @welldot/core, so the two accept the same documents. A few rules can only be checked in code; see Validating.

What the shape guarantees

  • Required fields. version, well_type (core identity) and the construction and geology arrays (bore_hole, well_case, reduction, well_screen, surface_case, hole_fill, lithology, fractures, caves, possibly empty) are required. Everything else is optional. See the Well object. Note that parseWell and the generated JSON Schema currently accept a file without well_type; write it anyway.
  • Fixed units. Every number has one canonical unit set by the spec, never by the file (Units). Convert on display, not in storage.
  • Absent means unknown. Optional fields without a value are omitted, never null (Absent values).
  • Unknown members survive. Readers must preserve fields and blocks they do not recognize, prefixed with x- or not (Extensibility). Do not strip them on save.
  • Open vocabularies. Most string fields recommend values but accept any string. Show unknown values as they are (Recommended vocabularies).
  • String ids, local references. Records point to each other by string id within the same file (Cross-reference rules). A dangling reference is a warning, not an error.
parseWell in @welldot/core currently accepts a file without version. The spec says such a file SHOULD be rejected (parser version handling), so always write it.

Parts of the spec to read first

If you are buildingRead
A reader or viewerTop-level structure, Versioning, Units
An editorthe above, plus Block kinds, Datetime conventions, Duplicate ids
A database or registryCross-reference rules, well_id, Interoperability
A converter from another formatUnits, Precision, Changes from v1

Building on .well collects the decisions that matter for editors, databases and pipelines.

Draw and analyze

  • @welldot/render draws a profile into an SVG element with D3.
  • @welldot/utils computes volumes, drawdown, permit status, production totals and water quality indicators.
import { parseWell } from '@welldot/core';
import { calculateHoleFillVolume, getLatestStaticLevel } from '@welldot/utils';

const well = parseWell(text);
calculateHoleFillVolume('gravel_pack', well); // m³ of gravel pack
getLatestStaticLevel(well); // m below ground, negative if flowing

Test data

The 19 example wells are complete, valid files covering crystalline, karst, sedimentary, flowing, hand-dug and monitoring wells, plus incomplete and inconsistent records. They ship with @welldot/core as @welldot/core/examples/<file> and are served at https://welldot.org/examples/<file>.

Working with an AI assistant

Point your assistant at this site's MCP server to let it search these docs and validate the .well files it writes, or give it /llms.txt.