Skip to content

dupontcyborg/numpy-ts

Repository files navigation

numpy-ts

License: MIT npm version bundle size numpy api coverage

███╗   ██╗██╗   ██╗███╗   ███╗██████╗ ██╗   ██╗  ████████╗███████╗
████╗  ██║██║   ██║████╗ ████║██╔══██╗╚██╗ ██╔╝  ╚══██╔══╝██╔════╝
██╔██╗ ██║██║   ██║██╔████╔██║██████╔╝ ╚████╔╝█████╗██║   ███████╗
██║╚██╗██║██║   ██║██║╚██╔╝██║██╔═══╝   ╚██╔╝ ╚════╝██║   ╚════██║
██║ ╚████║╚██████╔╝██║ ╚═╝ ██║██║        ██║        ██║   ███████║
╚═╝  ╚═══╝ ╚═════╝ ╚═╝     ╚═╝╚═╝        ╚═╝        ╚═╝   ╚══════╝

Complete NumPy implementation for TypeScript and JavaScript

⚠️ Under active development — API may change before v1.0

npm install numpy-ts

Why numpy-ts?

  • 📊 Extensive API336 of 507 NumPy functions (66.3% coverage)
  • ✅ NumPy-validated — 3000+ test cases cross-validated against Python NumPy
  • 🔒 Type-safe — Full TypeScript support with shape and dtype inference
  • 🌐 Universal — Works in Node.js and browsers with .npy/.npz file support
  • 🎯 Zero dependencies — Pure TypeScript, no heavy external libraries

Quick Start

import * as np from 'numpy-ts';

// Array creation with dtype support
const A = np.array([[1, 2], [3, 4]], 'float32');
const B = np.ones([2, 2], 'int32');

// Broadcasting and chained operations
const result = A.add(5).multiply(2);

// Linear algebra
const C = A.matmul(B);
const trace = A.trace();

// Reductions with axis support
const colMeans = A.mean(0);  // [2.0, 3.0]

// NumPy-style slicing with strings
const row = A.slice('0', ':');    // A[0, :]
const submatrix = A.slice('0:2', '1:');  // A[0:2, 1:]

Features

API Coverage

Progress toward complete NumPy API compatibility:

Category Complete Total Status
Arithmetic 29/29 100%
Broadcasting 3/3 100%
Comparison 10/10 100%
Exponential 9/9 100%
Gradient 4/4 100%
Hyperbolic 9/9 100%
I/O 8/8 100%
Indexing 21/21 100%
Logic 24/24 100%
Rounding 7/7 100%
Searching 7/7 100%
Sorting 6/6 100%
Trigonometric 16/16 100%
Reductions 34/36 94% 🟡
Array Creation 33/35 94% 🟡
Array Manipulation 37/46 80% 🟡
Statistics 9/12 75% 🟡
Bit Operations 9/13 69% 🟡
NDArray Methods 34/53 64% 🟡
Linear Algebra (linalg) 19/31 61% 🟡
Linear Algebra 9/15 60% 🟡
Set Operations 7/12 58% 🟡
Other Math 5/15 33% 🔴
Random 17/53 32% 🔴
Utilities 4/16 25% 🔴
FFT 0/18 0% 🔴
Polynomials 0/10 0% 🔴
String/Formatting 0/10 0% 🔴
Type Checking 0/7 0% 🔴
Unplanned 0/25 0% 🔴

Overall: 336/507 functions (66.3% complete)

See the complete API Reference for detailed function list.

Data Types (dtypes)

NumPy-compatible type system with automatic promotion:

DType NumPy numpy-ts Notes
Floating Point
float64 Default dtype
float32
float16 ⚠️ Planned (waiting for this)
Signed Integers
int64 Uses BigInt
int32
int16
int8
Unsigned Integers
uint64 Uses BigInt
uint32
uint16
uint8
Other Numeric
bool Stored as uint8
complex64
complex128
Non-Numeric
str_ Not planned
bytes_ Not planned
object_ Not planned
datetime64 Not planned
timedelta64 Not planned

Supported: 13/20 numeric dtypes

Intentional Divergences from NumPy

numpy-ts focuses on numeric array computing. The following NumPy features are not planned:

Feature Why Not Included
Datetime/Timedelta (datetime64, timedelta64) JS has native Date; libraries like date-fns handle time math better
F-order memory layout Exists in NumPy for Fortran/BLAS interop, which doesn't exist in JS
Object dtype (object_) Defeats the purpose of typed arrays; use regular JS arrays instead
String/Bytes dtypes (str_, bytes_, U, S) JS strings are first-class; no need for fixed-width string arrays

These omissions keep the library focused and the bundle small. For string manipulation, datetime math, or heterogeneous data, use native JS/TS constructs alongside numpy-ts.

NumPy Memory Model

  • View trackingbase attribute and OWNDATA flag
  • Strided arrays — C/F contiguous flags for memory layout
  • Zero-copy ops — Views for slicing, transpose, reshape (when possible)
const arr = np.ones([4, 4]);
const view = arr.slice('0:2', '0:2');

console.log(view.base === arr);      // true - view tracks base
console.log(view.flags.OWNDATA);     // false - doesn't own data
console.log(arr.flags.C_CONTIGUOUS); // true - row-major layout

Architecture

┌─────────────────────────────────┐
│  NumPy-Compatible API           │
│  Broadcasting, DType Promotion  │
└───────────────┬─────────────────┘
                │
┌───────────────┴─────────────────┐
│  NDArray (Views & Memory Mgmt)  │
│  Strided Arrays, Base Tracking  │
└───────────────┬─────────────────┘
                │- - - - - - - - - - - - - - - - - - ┐  
┌───────────────┴─────────────────┐  ┌ ─ ─ ─ ─ ─ ─ ─ ┴ ─ ─ ─ ─ ─ ─ ─ ─┐
│  TypeScript / JavaScript Core   │  │  WASM Compute Engine (Future)  │
│  Computational Engine           │  │  Optimized BLAS / arithmetic   │
└─────────────────────────────────┘  └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘

Pure TypeScript implementation built from scratch for correctness and NumPy compatibility.

Performance

Benchmark Results

See benchmarks/README.md for detailed performance analysis.

File I/O

Read and write .npy and .npz files with Node.js or browsers.

Node.js

import { load, save, savez, savez_compressed } from 'numpy-ts/node';

save('array.npy', arr);
const arr = load('array.npy');

savez('arrays.npz', { a: arr1, b: arr2 });
const { a, b } = load('arrays.npz');

Browser

import * as np from 'numpy-ts';

// Parse fetched .npy file
const response = await fetch('array.npy');
const arr = np.parseNpy(await response.arrayBuffer());

// Serialize for download
const bytes = np.serializeNpy(arr);

Why separate imports? The /node entry includes Node.js fs usage. Keeping it separate ensures browser bundles stay clean.

Examples

Broadcasting

const matrix = np.ones([3, 4]);     // (3, 4)
const row = np.arange(4);           // (4,)
const result = matrix.add(row);     // (3, 4) - row broadcast to each row

const col = np.array([[1], [2], [3]]);  // (3, 1)
const grid = col.multiply(row);         // (3, 4) - outer product via broadcasting

Slicing

TypeScript doesn't support Python's arr[0:5, :], so we use strings:

arr.slice('0:5', '1:3');     // arr[0:5, 1:3]
arr.slice(':', '-1');        // arr[:, -1]
arr.slice('::2');            // arr[::2]

// Convenience helpers
arr.row(0);                  // arr[0, :]
arr.col(2);                  // arr[:, 2]

Type Safety

const arr = np.zeros([3, 4]);  // Type: NDArray<Float64>
arr.shape;  // Type: readonly [3, 4]
arr.sum();  // Type: number

Comparison with Alternatives

Feature numpy-ts numjs ndarray TensorFlow.js
NumPy API Coverage 336/507 (66%) ~20% Different ML-focused
TypeScript Native ✅ Full Partial ❌ No ✅ Yes
NumPy Validated ✅ 1365+ tests Mostly ❌ No ❌ No
.npy/.npz Files ✅ v1/v2/v3 ❌ No ❌ No ❌ No
Broadcasting ✅ Full Limited Limited ✅ Full
Bundle Size <50kb ~60kb ~5kb >100kb

Contributing

Contributions welcome! See CONTRIBUTING.md for detailed instructions on:

  • Setting up the development environment
  • Adding new functions with tests
  • Running benchmarks
  • Submitting pull requests

Documentation

License

MIT License — Copyright (c) 2025 Nicolas Dupont


Bring NumPy to TypeScript!GitHubIssuesNumPy Docs

About

Full NumPy, in TypeScript/JavaScript (66% complete)

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •