Modern NetCDF file reader and utilities
npm install modern-netcdfA modern JavaScript implementation for reading and working with NetCDF files. This library provides an efficient, async/await-based API for handling NetCDF v3.x files with support for partial reads, slicing, and memory-efficient operations.
- ๐ Full NetCDF-3 classic & 64-bit offset support
- ๐ Promise-based, await-friendly API
- ๐ช Hyperslab slicing with range + stride
- ๐ก Lazy HTTP-Range streaming for remote files
- โ๏ธ Zero-copy views & memory-efficient decoding
- ๐งต WebWorker shim auto-selects Node vs Browser
- ๐ Smart formatting for large arrays and strings
- ๐ ๏ธ Command-line netcdf-dump utility
- ๐ช TypeScript declarations included
``bash`
npm install modern-netcdf
`javascript
const { NetCDFReader } = require('modern-netcdf');
// From a file
const reader = await NetCDFReader.open('path/to/file.nc');
// From an ArrayBuffer
const buffer = fs.readFileSync('path/to/file.nc');
const reader = await NetCDFReader.open(buffer);
// From a URL (download header only; streams data on-demand)
const reader = await NetCDFReader.open('https://example.com/data.nc', { lazy: true });
// The first call to getData() will issue HTTP Range requests automatically.
// Access metadata
console.log(reader.dimensions); // { time: 72, y: 1040, x: 1077 }
console.log(reader.globalAttributes); // Array of global attributes
console.log(reader.variables); // Object of variable metadata
// Read entire variable
const data = await reader.getData('temperature');
// Clean up when done
reader.close();
`
The library supports sophisticated data slicing with start, end, and stride parameters:
`javascript
// Read a specific time index
const timeSlice = await reader.getData('temperature', {
time: 0 // Select first time step
});
// Read a range of latitudes and longitudes
const spatialSlice = await reader.getData('temperature', {
lat: [100, 200], // Select indices 100-199
lon: [400, 600] // Select indices 400-599
});
// Use stride to read every other point
const strided = await reader.getData('temperature', {
lat: [0, 100, 2], // Start: 0, End: 100, Stride: 2
lon: [0, 200, 2] // Start: 0, End: 200, Stride: 2
});
`
`javascript
// Get a specific variable
const tempVar = reader.getVariable('temperature');
// Access variable metadata
console.log(tempVar.name); // Variable name
console.log(tempVar.type); // Data type (float, double, etc.)
console.log(tempVar.dimensions); // Array of dimension names
console.log(tempVar.attributes); // Array of variable attributes
`
The package includes a netcdf-dump utility for inspecting NetCDF files:
`bashInstall globally
npm install -g modern-netcdf
The output format is similar to the standard
ncdump utility:`
netcdf input {
dimensions:
time = 72 ;
y = 1040 ;
x = 1077 ;
variables:
float temperature(time, y, x) ;
units = "K" ;
long_name = "Temperature" ;
...
}
`Error Handling
The library provides detailed error messages for common issues:
`javascript
try {
const reader = await NetCDFReader.open('file.nc');
const data = await reader.getData('nonexistent');
} catch (error) {
if (error.message.includes('Variable not found')) {
console.error('The requested variable does not exist');
}
}
`Memory Considerations
For large datasets, the library implements smart memory management:
- Only loads requested data portions into memory
- Automatically summarizes large arrays in output
- Provides clean-up method via
reader.close()Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
ISC
$3
`javascript
// worker.js
importScripts('modern-netcdf/dist/worker.js');// main thread (app.js)
const worker = new Worker('worker.js');
worker.postMessage({ id: 1, cmd: 'open', payload: { source: 'https://example.com/data.nc', options: { lazy: true } } });
worker.onmessage = (e) => {
const { id, result, error } = e.data;
if (error) console.error(error);
else console.log('Worker response', result);
};
`The same worker entry automatically routes to
worker_threads` when bundled for Node.js, so you can reuse the identical message protocol in server-side environments.