Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 0 additions & 30 deletions .eslintrc.js

This file was deleted.

52 changes: 22 additions & 30 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
@@ -1,51 +1,43 @@
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages

name: Node.js Package
name: Publish to npm

on:
release:
types: [created]

jobs:
build:
name: Build & Test (matrix)
runs-on: ubuntu-latest
strategy:
matrix:
node: [18, 20, 22]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 12
- run: npm i
node-version: ${{ matrix.node }}
cache: npm
- run: npm ci
- run: npm run typecheck
- run: npm run build
- run: npm test

publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- run: npm install && npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}

publish-gpr:
name: Publish (npm)
needs: build
runs-on: ubuntu-latest
permissions:
id-token: write # for provenance
contents: read
packages: write
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 12
registry-url: https://npm.pkg.github.com/
- run: npm install && npm ci
- run: npm publish
node-version: 20
registry-url: https://registry.npmjs.org/
cache: npm
- run: npm ci
# prepublishOnly will run (build + test + typecheck) per your package.json
- run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
42 changes: 15 additions & 27 deletions .github/workflows/test-node.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,16 @@
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Node.js CI

on:
push:
branches: [master]
pull_request:
branches: [master]

name: ci
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [12.x, 14.x, 16.x]

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm i
- run: npm run build --if-present
- run: npm test
test:
runs-on: ubuntu-latest
strategy:
matrix: { node: [18, 20, 22] }
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm run typecheck
- run: npm test
- run: npm run build
143 changes: 93 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,99 +1,142 @@
<h1 align=center>npy.js</h1>
<h6 align=center>Read .npy files directly in JS</h6>

<p align=center>
<a href="https://www.npmjs.com/package/npyjs"><img src="https://img.shields.io/npm/v/npyjs.svg?style=for-the-badge" /></a>
<a href="https://github.com/aplbrain/npyjs"><img src="https://img.shields.io/github/issues/aplbrain/npyjs.svg?style=for-the-badge" /></a>
<a href="https://github.com/aplbrain/npyjs"><img src="https://img.shields.io/github/license/aplbrain/npyjs.svg?style=for-the-badge" /></a>
<img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/aplbrain/npyjs/test-node.yml?label=Tests&style=for-the-badge">
<h1 align="center">npyjs</h1>
<h6 align="center">Read NumPy <code>.npy</code> files in JavaScript (Node, Browser, Deno)</h6>

<p align="center">
<a href="https://www.npmjs.com/package/npyjs"><img src="https://img.shields.io/npm/v/npyjs.svg?style=for-the-badge" /></a>
<a href="https://github.com/aplbrain/npyjs/issues"><img src="https://img.shields.io/github/issues/aplbrain/npyjs.svg?style=for-the-badge" /></a>
<a href="https://github.com/aplbrain/npyjs/blob/main/LICENSE"><img src="https://img.shields.io/github/license/aplbrain/npyjs.svg?style=for-the-badge" /></a>
<img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/aplbrain/npyjs/ci.yml?label=Tests&style=for-the-badge">
</p>

Read .npy files from [numpy](https://numpy.org/doc/1.18/reference/generated/numpy.save.html) in Node/JS.
Read `.npy` arrays saved with [NumPy](https://numpy.org/doc/stable/reference/generated/numpy.save.html) directly in modern JavaScript runtimes.

## Installation
---

Include npy.js in your project directly, or:
## Installation

```shell
```bash
npm install npyjs
# or
yarn add npyjs
# npm i npyjs
```

Supports **Node ≥18**, modern browsers, and Deno/Bun.

---

## Import

```javascript
```ts
// Modern named export (recommended)
import { load } from "npyjs";

// Back-compatibility class (matches legacy docs/tests)
import npyjs from "npyjs";
```

---

## Usage

- Create a new npyjs object:
### 1. Functional API (preferred)

```javascript
let n = new npyjs();
// Or with options:
let n = new npyjs({ convertFloat16: false }); // Disable float16 to float32 conversion
```ts
import { load } from "npyjs";

const arr = await load("my-array.npy");
// arr has { data, shape, dtype, fortranOrder }
console.log(arr.shape); // e.g., [100, 784]
```

- This object can now be used load .npy files. Arrays can be returned via a JavaScript callback, so usage looks like this:
### 2. Legacy Class API (still supported)

```javascript
n.load("my-array.npy", (array, shape) => {
// `array` is a one-dimensional array of the raw data
// `shape` is a one-dimensional array that holds a numpy-style shape.
console.log(`You loaded an array with ${array.length} elements and ${shape.length} dimensions.`);
});
```
```ts
import npyjs from "npyjs";

- You can also use this library promise-style using either .then or async await:
// Default options
const n = new npyjs();

// Disable float16→float32 conversion
const n2 = new npyjs({ convertFloat16: false });

```javascript
n.load("test.npy").then((res) => {
// res has { data, shape, dtype } members.
});
const arr = await n.load("my-array.npy");
```

```javascript
const npyArray = await n.load("test.npy");
---

## Accessing multidimensional elements

`npyjs` returns flat typed arrays with a `shape`. `npyjs` also ships a small helper to turn the flat `data` + `shape` into nested JS arrays.

```ts
import { load } from "npyjs";
import { reshape } from "npyjs/reshape";

const { data, shape, fortranOrder } = await load("my-array.npy");
const nested = reshape(data, shape, fortranOrder); // -> arrays nested by dims
```

## Accessing multidimensional array elements
For C-order arrays (the NumPy default), pass fortranOrder = false (default).

For Fortran-order arrays, pass true and the helper will return the natural row-major nested structure.

- You can conveniently access multidimensional array elements using the 'ndarray' library:
Or pair it with [ndarray](https://github.com/scijs/ndarray) or TensorFlow\.js:

```javascript
```ts
import ndarray from "ndarray";
const npyArray = ndarray(data, shape);
npyArray.get(10, 15);
import { load } from "npyjs";

const { data, shape } = await load("my-array.npy");
const tensor = ndarray(data, shape);

console.log(tensor.get(10, 15));
```

## Supported Data Types
---

The library supports the following NumPy data types:
## Supported Data Types

- `int8`, `uint8`
- `int16`, `uint16`
- `int32`, `uint32`
- `int64`, `uint64` (as BigInt)
- `int64`, `uint64` (as `BigInt`)
- `float32`
- `float64`
- `float16` (converted to float32 by default)

### Float16 Support
### Float16 Control

By default, float16 arrays are automatically converted to float32 for compatibility, since JavaScript doesn't natively support float16. You can control this behavior with the constructor options:

```javascript
// Default behavior - float16 is converted to float32
```ts
// Default: converts float16 → float32
const n1 = new npyjs();
// Keep float16 as raw uint16 values without conversion

// Keep raw Uint16Array
const n2 = new npyjs({ convertFloat16: false });
```

Unless otherwise specified, all code inside of this repository is covered under the license in [LICENSE](LICENSE).
---

## Development

- Built with [tsup](https://github.com/egoist/tsup) (dual ESM + CJS + d.ts)
- Tested with [Vitest](https://vitest.dev)
- CI on GitHub Actions (Node 18/20/22)

### Commands

```bash
npm run build # Build to dist/
npm test # Run Vitest
npm run typecheck # TypeScript type checking
```

---

## License

Please report bugs or contribute pull-requests on [GitHub](https://github.com/aplbrain/npyjs).
Apache-2.0 © [JHU APL](http://www.jhuapl.edu/)

---

<p align="center"><small>Made with ♥ at <a href="http://www.jhuapl.edu/"><img alt="JHU APL" align="center" src="./docs/apl-logo.png" height="23px"></a></small></p>
````
Loading