npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jsfitsio

v3.1.0

Published

JavaScript/TypeScript library for reading and writing FITS files in Node.js and the browser.

Readme

jsfitsio

FITS I/O library for JavaScript and TypeScript.

jsfitsio reads and writes FITS data in Node.js and browser-oriented scientific web applications. It provides a lightweight FITS data model supporting images, N-dimensional data cubes, multiple HDUs, binary tables and ASCII tables.

It is designed as a building block for astronomy, astrophysics and scientific data analysis and visualisation workflows.

The project is available on GitHub:

https://github.com/fab77/jsfitsio

Features

  • Read FITS files from remote HTTP/HTTPS URLs.
  • Read FITS files from the local filesystem in Node.js.
  • Parse multi-block FITS headers.
  • Support FITS files containing multiple HDUs.
  • Support Primary HDUs and Image extensions.
  • Support N-dimensional FITS images and data cubes.
  • Support Binary Table (BINTABLE) extensions.
  • Support ASCII Table (TABLE) extensions.
  • Access table data through getRow() and getCell().
  • Expose image data using native JavaScript TypedArrays.
  • Preserve 64-bit integer image data using BigInt64Array.
  • Read and write FITS files using the FITSFile / HDU data model.
  • Provide ESM, CommonJS and browser bundle outputs.
  • Keep the jsfitsio 2.x API available as a deprecated compatibility layer.

Supported FITS data

HDU types

jsfitsio 3.x supports:

  • Primary HDU
  • Image HDU (IMAGE)
  • Binary Table HDU (BINTABLE)
  • ASCII Table HDU (TABLE)

Image data types

Supported FITS BITPIX values:

| BITPIX | FITS data type | JavaScript representation | | -----: | ------------------------------------ | ------------------------- | | 8 | 8-bit unsigned integer | Uint8Array | | 16 | 16-bit two's-complement integer | Int16Array | | 32 | 32-bit two's-complement integer | Int32Array | | 64 | 64-bit two's-complement integer | BigInt64Array | | -32 | IEEE single-precision floating point | Float32Array | | -64 | IEEE double-precision floating point | Float64Array |

Installation

npm install jsfitsio

The package currently targets Node.js >=22.0.0.

Usage

For new applications, use FITSParser.loadFITSFile() and the FITSFile/HDU data model.

The older FITSParsed API is retained only for backward compatibility.

jsfitsio 3.x uses FITSFile and HDU objects as its main data model.

The canonical entry point for reading FITS files is:

FITSParser.loadFITSFile();

The returned FITSFile may contain:

  • PrimaryHDU
  • ImageHDU
  • BinaryTableHDU
  • AsciiTableHDU

Image HDUs support N-dimensional data, including FITS cubes.

Read a FITS file from a URL

import { FITSParser } from "jsfitsio";

const url =
  "http://skies.esac.esa.int/Herschel/normalized/PACS_hips160//Norder8/Dir40000/Npix47180.fits";
const fitsFile = await FITSParser.loadFITSFile(url);
if (!fitsFile?.primaryHDU) {
  throw new Error("Unable to load FITS file");
}
const image = fitsFile.primaryHDU;
console.log("BITPIX:", image.bitpix);
console.log("Shape:", image.shape);
console.log("Dimensions:", image.naxis);
console.log("Elements:", image.elementCount);
console.log("Data:", image.typedData);

Reading a FITS file

import { FITSParser } from "jsfitsio";

const fitsFile = await FITSParser.loadFITSFile("./example.fits");
if (!fitsFile) {
  throw new Error("Unable to load FITS file");
}
console.log("Number of HDUs:", fitsFile.length);
console.log("Primary HDU:", fitsFile.primaryHDU);

loadFITSFile() can load both local files in Node.js and HTTP/HTTPS FITS resources.

const fitsFile = await FITSParser.loadFITSFile(
  "https://example.org/data/image.fits",
);

Reading an image FITS

The Primary HDU is represented by PrimaryHDU, which extends ImageHDU.

import { FITSParser } from "jsfitsio";

const fitsFile = await FITSParser.loadFITSFile("./image.fits");
if (!fitsFile?.primaryHDU) {
  throw new Error("Primary HDU not found");
}
const image = fitsFile.primaryHDU;
console.log("BITPIX:", image.bitpix);
console.log("Shape:", image.shape);
console.log("Dimensions:", image.naxis);
console.log("Number of elements:", image.elementCount);

For example, a FITS header containing:

NAXIS  = 3
NAXIS1 = 1024
NAXIS2 = 1024
NAXIS3 = 20

is represented as:

image.shape;
// [1024, 1024, 20]

image.naxis;
// 3

The shape follows FITS axis order:

[NAXIS1, NAXIS2, NAXIS3, ...]

Accessing typed image data

Image payloads are exposed through JavaScript TypedArrays.

const data = image.typedData;

The TypedArray type depends on BITPIX.

| BITPIX | JavaScript type | | ------ | --------------- | | 8 | Uint8Array | | 16 | Int16Array | | 32 | Int32Array | | 64 | BigInt64Array | | -32 | Float32Array | | -64 | Float64Array |

Example:

if (image.typedData instanceof Float32Array) {
  console.log(image.typedData[0]);
}

BITPIX=64 values are preserved using BigInt64Array, avoiding precision loss for integers larger than JavaScript's safe integer range.


Reading FITS cubes

No special cube class is required.

A FITS cube is simply an N-dimensional ImageHDU.

const fitsFile = await FITSParser.loadFITSFile("./cube.fits");
const cube = fitsFile?.primaryHDU;
if (!cube) {
  throw new Error("Cube not found");
}
console.log(cube.shape);
console.log(cube.elementCount);

For:

NAXIS1 = 256
NAXIS2 = 256
NAXIS3 = 100

the result is:

cube.shape;
// [256, 256, 100]
cube.elementCount;
// 6553600

The payload remains a flat TypedArray:

const pixels = cube.typedData;

The application can interpret the array according to the FITS dimensions.


Reading multiple HDUs

A FITSFile may contain multiple HDUs.

const fitsFile = await FITSParser.loadFITSFile("./multi-hdu.fits");
if (!fitsFile) {
  throw new Error("Unable to load FITS");
}
for (let i = 0; i < fitsFile.length; i++) {
  const hdu = fitsFile.getHDU(i);
  console.log(i, hdu?.type);
}

Example output:

0 PRIMARY
1 IMAGE
2 BINTABLE
3 TABLE

Individual HDUs can be retrieved with:

const hdu = fitsFile.getHDU(1);

If the index does not exist, getHDU() returns null.


Reading an ImageHDU extension

import { FITSParser, ImageHDU } from "jsfitsio";

const fitsFile = await FITSParser.loadFITSFile("./multi-image.fits");
const hdu = fitsFile?.getHDU(1);
if (hdu instanceof ImageHDU) {
  console.log(hdu.shape);
  console.log(hdu.typedData);
}

Reading a binary table

Binary FITS tables are represented by BinaryTableHDU.

import { FITSParser, BinaryTableHDU } from "jsfitsio";

const fitsFile = await FITSParser.loadFITSFile("./catalog.fits");
const hdu = fitsFile?.getHDU(1);
if (!(hdu instanceof BinaryTableHDU)) {
  throw new Error("Expected BINTABLE HDU");
}
console.log("Rows:", hdu.rowCount);
console.log("Columns:", hdu.columnCount);
console.log(hdu.columns);

Column metadata includes information such as:

const column = hdu.columns[0];
console.log(column.name);
console.log(column.format);
console.log(column.type);
console.log(column.byteOffset);
console.log(column.byteWidth);

Reading BINTABLE cells

Cells can be accessed by column name:

const id = hdu.getCell(0, "ID");
const flux = hdu.getCell(0, "FLUX");

or by zero-based column index:

const id = hdu.getCell(0, 0);

A complete row can be read with:

const row = hdu.getRow(0);
console.log(row);

For a table containing:

ID    FLUX
1     1.5
2     3.25

the result may be:

hdu.getRow(0);
// [1, 1.5]
hdu.getRow(1);
// [2, 3.25]

Reading an ASCII FITS table

ASCII tables are represented by AsciiTableHDU.

import { FITSParser, AsciiTableHDU } from "jsfitsio";

const fitsFile = await FITSParser.loadFITSFile("./ascii-table.fits");
const hdu = fitsFile?.getHDU(1);
if (!(hdu instanceof AsciiTableHDU)) {
  throw new Error("Expected ASCII TABLE HDU");
}

console.log(hdu.rowCount);

console.log(hdu.columns);

Cells can be accessed by name:

const id = hdu.getCell(0, "ID");
const name = hdu.getCell(0, "NAME");
const flux = hdu.getCell(0, "FLUX");

or as complete rows:

hdu.getRow(0);
// [1, "STAR-A", 12.5]

The original ASCII row is also available:

const text = hdu.getRowText(0);

Writing FITS files

jsfitsio 3.x can serialize the FITSFile / HDU data model.

import { FITSParser, FITSWriter } from "jsfitsio";

const fitsFile = await FITSParser.loadFITSFile("./input.fits");
if (!fitsFile) {
  throw new Error("Unable to load FITS");
}
const serialized = FITSWriter.createFITSFile(fitsFile);

serialized is a complete FITS file represented as:

Uint8Array;

It can be stored, transmitted, or used to create a browser Blob.


FITS read/write round trip

A common workflow is:

import { FITSParser, FITSWriter } from "jsfitsio";

const original = await FITSParser.loadFITSFile("./input.fits");
if (!original) {
  throw new Error("Unable to read FITS");
}
const bytes = FITSWriter.createFITSFile(original);

The serialized FITS preserves the HDU structure:

PrimaryHDU
ImageHDU
BinaryTableHDU
AsciiTableHDU

including HDU headers and raw payloads.


Writing a FITS file in Node.js

In Node.js:

import { FITSParser, FITSWriter } from "jsfitsio";

const fitsFile = await FITSParser.loadFITSFile("./input.fits");
if (!fitsFile) {
  throw new Error("Unable to load FITS");
}
FITSWriter.writeFITSFileModel(fitsFile, "./output.fits");

Writing FITS in the browser

createFITSFile() returns a Uint8Array, so the result can be converted to a browser Blob.

import { FITSWriter } from "jsfitsio";

const bytes = FITSWriter.createFITSFile(fitsFile);
const blob = new Blob([bytes], {
  type: "application/fits",
});
const url = URL.createObjectURL(blob);

For example, to trigger a browser download:

const link = document.createElement("a");
link.href = url;
link.download = "output.fits";
link.click();
URL.revokeObjectURL(url);

Browser bundle

The package also provides browser bundle outputs through dist/.

When loaded as a script, the UMD bundle exposes the jsfitsio global.

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>jsfitsio browser example</title>
  </head>

  <body>
    <script src="./jsfitsio.js"></script>

    <script>
      const url =
        "http://skies.esac.esa.int/Herschel/normalized/PACS_hips160//Norder8/Dir40000/Npix47180.fits";

      jsfitsio.FITSParser.loadFITSFile(url).then((fitsFile) => {
        if (fitsFile?.primaryHDU) {
          const image = fitsFile.primaryHDU;

          console.log("BITPIX:", image.bitpix);
          console.log("Shape:", image.shape);
          console.log("Data:", image.typedData);
        }
      });
    </script>
  </body>
</html>

Migrating from jsfitsio 2.x

Deprecated API

Migration example

Build

Install dependencies:

npm install

Run tests:

npm test

Build production outputs:

npm run prod

The build generates:

  • lib-esm/ for ESM output and TypeScript declarations
  • dist/jsfitsio.cjs for CommonJS
  • dist/jsfitsio.js and dist/jsfitsio.min.js for browser usage

License

jsfitsio is licensed under the Apache License, Version 2.0.

See LICENSE.md.

Author

Fabrizio Giordano