Quickstart
Before you start
Section titled “Before you start”You need:
- Node.js 22 or later for the Node path.
- Any modern browser for the
BlobReaderandHttpRangeReaderpaths.
Install
Section titled “Install”npm install @fits-js/corepnpm add @fits-js/coreyarn add @fits-js/corebun add @fits-js/coreEverything comes from the same entry. Pick the reader that fits the byte source.
Open a local file
Section titled “Open a local file”import { NodeFileReader, openFits, readImage } from "@fits-js/core";
const reader = await NodeFileReader.open("data/image.fits");try { const { hdus } = await openFits(reader); const primary = hdus[0];
const region = { start: [0, 0], shape: [16, 16] }; const { data } = await readImage(primary, reader, { region }); console.log(data.slice(0, 8));} finally { await reader.close();}openFits enumerates HDUs and reads only header blocks. readImage with a
region only reads the bytes that region covers, so a small cutout from a
multi-gigabyte cube stays cheap.
Open a file over HTTP
Section titled “Open a file over HTTP”import { HttpRangeReader, openFits, readImage } from "@fits-js/core";
const reader = new HttpRangeReader("https://example.test/cube.fits");const { hdus } = await openFits(reader);const primary = hdus[0];
const region = { start: [0, 0], shape: [8, 8] };const { data } = await readImage(primary, reader, { region });HttpRangeReader issues HTTP Range requests for the bytes openFits and
readImage ask for, and fetches are page-granular. Measured on a 1.2 MB
archive file with five image extensions, enumeration costs about 320 KB at
the default 64 KiB pageSize, and an 8x8 cutout from the first extension
then costs nothing more, because its bytes land in pages the enumeration
already cached. A smaller pageSize trades more requests for fewer bytes.
The HTTP guide covers the tuning.
If the server answers the initial bytes=0-0 probe with 200 (ignoring the
range), the reader falls back to fetching the whole body once and serving
later reads from memory.
Open a file in the browser
Section titled “Open a file in the browser”import { BlobReader, openFits, readImage } from "@fits-js/core";
const input = document.querySelector<HTMLInputElement>("input[type=file]")!;input.addEventListener("change", async () => { const file = input.files?.[0]; if (!file) return;
const reader = new BlobReader(file); const { hdus } = await openFits(reader); const primary = hdus[0];
const { data } = await readImage(primary, reader); // ...render or analyze});The same code path works for File (from a picker) and Blob (from fetch,
IndexedDB, or any other Web source).
A note on the lazy cutout
Section titled “A note on the lazy cutout”None of the snippets above ever read more than they need.
openFits(reader)reads only the 2880-byte header blocks for each HDU.readImage(primary, reader, { region })reads only the bytes the region spans.- Reading without a
regionreturns the full image.
A 4 GB cube with a tiny region cutout still costs kilobytes, not
gigabytes, which is the point. See
examples/http-range
for a complete program that prints the byte counts.