modern-netcdf
v0.3.3
Published
Modern NetCDF file reader and utilities
Downloads
11
Maintainers
Readme
Modern NetCDF
A 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.
Features
- 📖 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-dumputility - 💪 TypeScript declarations included
Installation
npm install modern-netcdfUsage
Basic Usage
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();Advanced Data Slicing
The library supports sophisticated data slicing with start, end, and stride parameters:
// 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
});Working with Variables
// 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 attributesCommand-line Tool
The package includes a netcdf-dump utility for inspecting NetCDF files:
# Install globally
npm install -g modern-netcdf
# Use the command-line tool
netcdf-dump path/to/file.nc
# Or use with npx
npx netcdf-dump path/to/file.ncThe 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:
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
Using in a WebWorker (browser)
// 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.
