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

ase-ts

v0.1.5

Published

ASE-compatible Atoms object and readers in TypeScript

Readme

ase-ts

TypeScript reimplementation of key ASE behavior for JS/TS environments.

Scope

  • Atoms core data model compatible with ASE-style usage (numbers, symbols, positions, cell, pbc, arrays, info, calc)
  • Core geometry/mutation methods (repeat, translate, wrap, COM, distances/angles/dihedral, rotation, formula)
  • Single-point result storage (SinglePointCalculator, getPotentialEnergy(), getForces())
  • ASE-style read/write API: read() / readAll(), write() / writeAll()
  • Fixed-atom constraint storage (fixed mask) for files that carry it
  • Implemented readers:
    • xyz
    • extxyz
    • cif
    • pdb
    • vasp (POSCAR / CONTCAR)
    • vasprun-xml (vasprun.xml, structure trajectory + selective F F F fixed mask + energy/forces when present)
    • orca-output (geometry frames + energy/forces from ORCA stdout when present)
    • traj (ASE native binary trajectory, ULM format)
  • Implemented writers:
    • xyz
    • extxyz (with move_mask for constraints)
    • vasp / poscar (with Selective dynamics for constraints)
    • pdb
    • traj (ASE native binary trajectory, ULM format, with FixAtoms)

Fixed Constraints

  • Stored in Atoms as a boolean mask per atom.
  • Read APIs:
    • atoms.getFixedMask()
    • atoms.getFixedIndices()
  • Auto-imported from:
    • extxyz move_mask (atoms with non-movable rows are marked fixed)
    • vasp selective dynamics (F F F rows are marked fixed)
    • vasprun-xml selective flags in structure name="initialpos" (F F F rows marked fixed)
    • traj FixAtoms constraint objects
  • Auto-exported to:
    • extxyz move_mask:L:1 column (F = fixed, T = movable)
    • vasp Selective dynamics section with F F F / T T T per-atom flags
    • traj FixAtoms constraint JSON with atom indices

Reference Source

Implementation was mapped against ASE source cloned from:

  • https://gitlab.com/ase/ase

Quick Start

import { Atoms, read, write } from "ase-ts";

const atoms = new Atoms({
  symbols: "H2O",
  positions: [[0, 0, 0], [0, 0, 1], [1, 0, 0]],
});

const xyz = `2\ncomment\nH 0 0 0\nO 0 0 1\n`;
const parsed = read(xyz, { data: true });

Calculation results from supported output formats are attached as single-point calculators:

const atoms = read(orcaOutputText, { data: true, format: "orca-output" }) as Atoms;
console.log(atoms.getPotentialEnergy()); // eV
console.log(atoms.getForces());          // eV / Angstrom

JS Project Usage

Node / Bundler

npm install ase-ts
import { read, readAll, write, writeAll } from "ase-ts";

// --- Reading ---

// text formats
const atoms = read(inputText, { data: true, format: "extxyz" });

// binary formats — pass a file path directly (extension detected automatically)
const traj = read("path/to/md.traj");             // last frame
const frames = readAll("path/to/md.traj");         // all frames

// --- Writing ---

// write single atoms object to a file (format inferred from extension)
write(atoms, "output.extxyz");
write(atoms, "POSCAR");                            // vasp format

// write trajectory
writeAll(frames, "output.traj");

// explicit format override
write(atoms, "out.txt", { format: "xyz" });

Writing with constraints:

import { Atoms, write } from "ase-ts";

const atoms = new Atoms({
  symbols: ["Si", "Si"],
  positions: [[0, 0, 0], [1.3575, 1.3575, 1.3575]],
  cell: [[5.43, 0, 0], [0, 5.43, 0], [0, 0, 5.43]],
  pbc: true,
});
atoms.setFixedMask([true, false]);   // first atom fixed

// extxyz → writes  move_mask:L:1  column  (F = fixed, T = movable)
write(atoms, "out.extxyz");

// POSCAR → writes  Selective dynamics  + F F F / T T T flags
write(atoms, "POSCAR");

// traj (binary) → writes FixAtoms JSON constraint with indices
write(atoms, "md.traj");

Binary formats (traj) in the browser

The browser build exposes readBinary / readAllBinary for ArrayBuffer input and writeBinary / writeAllBinary for ArrayBuffer output:

<script type="module">
  import { readBinary, writeBinary } from "https://cdn.jsdelivr.net/gh/<OWNER>/<REPO>@<TAG>/dist/browser.js";

  // Read
  const response = await fetch("md.traj");
  const buffer = await response.arrayBuffer();
  const atoms = readBinary(buffer, { format: "traj" });   // last frame
  console.log(atoms.getChemicalFormula("hill"));

  // Write — returns ArrayBuffer
  const outBuf = writeBinary(atoms, { format: "traj" });
  const blob = new Blob([outBuf], { type: "application/octet-stream" });
  const url = URL.createObjectURL(blob);
  // trigger download or send to server
</script>

The browser build also exposes write / writeAll (text + binary) and writeBinary / writeAllBinary:

<script type="module">
  import { write, writeBinary } from "https://cdn.jsdelivr.net/gh/<OWNER>/<REPO>@<TAG>/dist/browser.js";

  const xyzText = write(atoms, "xyz");                         // string
  const trajBuffer = writeBinary([atoms], { format: "traj" }); // ArrayBuffer
</script>

Browser (CDN) — text formats

<script type="module">
  import { read, write } from "https://cdn.jsdelivr.net/gh/<OWNER>/<REPO>@<TAG>/dist/browser.js";

  // Read
  const atoms = read("2\ncomment\nH 0 0 0\nO 0 0 1\n", { data: true, format: "xyz" });
  console.log(atoms.getChemicalFormula("hill"));

  // Write — returns string for text formats
  const extxyz = write(atoms, "extxyz");
  console.log(extxyz);

  // With constraints
  atoms.setFixedMask([true, false]);
  const poscar = write(atoms, "vasp");     // Selective dynamics included
  const extxyzWithMask = write(atoms, "extxyz");  // move_mask column included
</script>

Use a release tag (for example @v0.1.0) instead of branch names for stable caching.

Write options

| Option | Formats | Default | Description | |--------|---------|---------|-------------| | format | all | (from extension) | Explicit format override | | comment | xyz, extxyz | "" | Comment / title line | | direct | vasp | false | Write fractional (Direct) coords instead of Cartesian | | vasp5 | vasp | true | Include species-name header line (VASP5 format) | | sort | vasp | false | Sort atoms by species before writing |

Test

npm test

Build

npm run build

Build output is generated in dist/.

ASE Parity Test

Runs side-by-side comparison between:

  • TypeScript implementation output
  • ASE output from cloned source at .tmp_ase_ref
npm run test:parity

Notes:

  • parity runner uses Python with ASE and NumPy available on python3
  • compares numbers, positions, cell, pbc, formula, masses, COM, distances, scaled positions, fixed mask, and single-point energy/forces when present

Tutorial Demo

  • Notebook-style tutorial/demo page source: demo/index.html
  • Browser runtime script: demo/main.js

Deploy with GitHub Actions

GitHub-hosted runner workflow:

  • File: .github/workflows/deploy-demo.yml
  • Trigger: push to main (and manual workflow_dispatch)

Self-hosted runner workflow (manual only):

  • File: .github/workflows/deploy-demo-self-hosted.yml
  • Trigger: workflow_dispatch only (user clicks Run workflow)

Shared build/deploy chain:

  • npm ci -> npm run build:site
  • actions/configure-pages@v5 + actions/upload-pages-artifact@v3 + actions/deploy-pages@v4

One-time repo setup:

  1. Open repository settings -> Pages.
  2. Set source to GitHub Actions.
  3. Open Actions tab and run Deploy Demo (Self-Hosted) manually when needed.