A tide prediction engine written in TypeScript.
Warning
Not for navigational use
Do not use calculations from this project for navigation, or depend on them in any situation where inaccuracies could result in harm to a person or property. Tide predictions are only as good as the harmonics data available, and these can be inconsistent and vary widely based on the accuracy of the source data and local conditions. The tide predictions do not factor events such as storm surge, wind waves, uplift, tsunamis, or sadly, climate change. 😢
This monorepo contains:
- neaps - Main tide prediction library with station finding
- @neaps/api - HTTP JSON API for tide predictions with OpenAPI specification
- @neaps/tide-predictor - Core harmonic tide prediction engine
npm install neapsimport { getExtremesPrediction } from "neaps";
const prediction = getExtremesPrediction({
latitude: 26.7, // or `lat`
longitude: -80.05, // or `lng` or `lon`
start: new Date("2025-12-17"),
end: new Date("2025-12-18"),
datum: "MLLW", // optional, defaults to MLLW if available
units: "meters", // optional, defaults to 'meters', can also be 'feet'
});
console.log(prediction);
// {
// datum: 'MLLW',
// units: 'meters',
// station: {
// id: '8723214',
// name: 'Fort Lauderdale, FL',
// // ...
// },
// distance: 12.3,
// extremes: [
// { time: 2019-01-01T03:12:00.000Z, level: 3.2, high: true, low: false, label: 'High' },
// { time: 2019-01-01T09:45:00.000Z, level: 0.5, high: false, low: true, label: 'Low' },
// ]
// }import { getTimelinePrediction } from "neaps";
const timeline = getTimelinePrediction({
lat: 26.77,
lon: -80.05,
start: new Date("2025-12-19T00:00:00-05:00"),
end: new Date("2025-12-19T01:00:00-05:00"),
timeFidelity: 5 * 60, // seconds, defaults to `10 * 60`
units: "meters", // optional, defaults to 'meters', can also be 'feet'
});
console.log(timeline);
// {
// datum: 'MLLW',
// units: 'meters',
// station: {
// id: 'noaa/8722588',
// name: 'Port of Palm Beach',
// // ...
// },
// timeline: [
// { time: 2025-12-19T05:00:00.000Z, hour: 0, level: 0.7232836255650095 },
// { time: 2025-12-19T05:06:00.000Z, hour: 0.1, level: 0.7231644154595303 },
// { time: 2025-12-19T05:12:00.000Z, hour: 0.2, level: 0.7221097788490487 },
// { time: 2025-12-19T05:18:00.000Z, hour: 0.3, level: 0.7201242512580206 },
// // ...
// ]
// }import { getWaterLevelAtTime } from "neaps";
const prediction = getWaterLevelAtTime({
lat: 26.77,
lon: -80.05,
time: new Date("2025-12-19T00:30:00-05:00"),
datum: "MSL",
units: "meters", // optional, defaults to 'meters', can also be 'feet'
});
console.log(prediction);
// {
// datum: 'MSL',
// units: 'meters',
// station: {
// id: 'noaa/8722588',
// name: 'Port of Palm Beach',
// // ...
// },
// time: 2025-12-19T05:30:00.000Z,
// hour: 0,
// level: -0.43840585181640557
// }Neaps uses @neaps/tide-database to find station data. You can find stations by location or ID.
import { nearestStation } from "neaps";
const station = nearestStation({ lat: 26.7, lon: -80.05 });
console.log(`${station.name} (${station.source.id})`); // Fort Lauderdale, FL (8722588)Once you've found a station, you can get predictions, timeline, or water level at a specific time for that station:
// Get extremes prediction for the nearest station
station.getExtremesPrediction({
start: new Date("2025-12-17"),
end: new Date("2025-12-18"),
});
// Get timeline prediction for the nearest station
station.getTimelinePrediction({
start: new Date("2025-12-19"),
end: new Date("2025-12-20"),
});
// Get timeline prediction for the nearest station
station.getWaterLevelAt({ time: new Date("2025-12-19T00:30:00-00:00") });import { stationsNear } from "neaps";
stationsNear({ latitude: 45.6, longitude: -122.7 }, 5).forEach((s) => {
console.log(`${s.name} (${s.source.id}) - ${(s.distance / 1000).toFixed(2)} km away`);
});
// Vancouver (9440083) - 3.49 km away
// Portland Morrison Street Bridge (9439221) - 10.24 km away
// KNAPP(THORNES)LNDG, WILLOW BAR (9440171) - 16.34 km away
// Rocky Point (9439189) - 16.93 km away
// WASHOUGAL, COLUMBIA RIVER (9440047) - 24.89 km awayimport { findStation } from "neaps";
// Find station by Neaps ID
findStation("noaa/8443970"); // Boston
// Find station by source ID (e.g. NOAA)
findStation("9440083"); // VancouverNeaps is continuously validated against NOAA tidal predictions, comparing the time and height of predicted high and low tides for all NOAA tide stations.
- Recent High/low predictions extracted from both NOAA and Neaps for 3300+ NOAA reference and subordinate stations
- One-to-one event matching using a ±180-minute window
- Metrics computed per station and aggregated across all stations
- Evaluated automatically in CI on every change
As of Dec 2025:
- Stations evaluated: 3,363
- High/low events compared: 36,990
- Median |Δt|: 3.5 minutes
- 95% of stations have median |Δt| < 13.5 minutes
- Median MAE: 1.1 cm
- 95% of stations have MAE < 4.5 cm
Neaps reproduces high and low tide timing with minute-level accuracy and tide heights with centimeter-level accuracy compared to NOAA's tide predictions. Validation is automated and enforced in CI to prevent regressions as the model evolves.