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

openalex-client

v1.2.0

Published

TypeScript SDK for OpenAlex academic database API

Readme

OpenAlex client

A comprehensive TypeScript client for the OpenAlex academic database API. This SDK provides type-safe access to scholarly works, authors, institutions, sources, and concepts.

Features

  • 🎯 Full TypeScript support with comprehensive type definitions
  • 🔄 Complete API coverage for all OpenAlex entities
  • Built-in retry logic with exponential backoff
  • 🌐 Native fetch API - no external HTTP dependencies
  • 📄 Pagination support with async generators
  • 🔍 Advanced search capabilities and filters
  • 🏗️ Modular architecture with service-based organization
  • ⏱️ Request timeout and abort support

Requirements

  • Node.js 18+ (for native fetch support)
  • TypeScript 5+ (for development)

Installation

npm install openalex-client

Quick Start

import { OpenAlex } from "openalex-client";

// Initialize the SDK
const openAlex = new OpenAlex({
  userAgent: "MyApp/1.0.0 (mailto:[email protected])",
});

// Search for works
const works = await openAlex.works.list({
  search: "artificial intelligence",
  per_page: 10,
});

console.log(`Found ${works.meta.count} works`);

// Get a specific work by DOI
const work = await openAlex.works.getByDoi("10.1038/nature12373");
console.log(work.title);

// Get author information
const author = await openAlex.authors.get("A2208157607");
console.log(`${author.display_name} has ${author.works_count} works`);

Configuration

const openAlex = new OpenAlex({
  baseURL: "https://api.openalex.org", // API base URL
  userAgent: "MyApp/1.0.0", // Required: Your app identifier
  timeout: 30000, // Request timeout in ms
  retries: 3, // Number of retry attempts
  retryDelay: 1000, // Base delay between retries
});

Core Services

Works Service

// Search works
const works = await openAlex.works.list({
  search: "machine learning",
  filter: {
    publication_year: "2023",
    "open_access.is_oa": true,
  },
  sort: "cited_by_count:desc",
});

// Get works by author
const authorWorks = await openAlex.works.getByAuthor("A2208157607");

// Get citations
const citations = await openAlex.works.getCitedBy("W2741809807");

// Get open access works
const oaWorks = await openAlex.works.getOpenAccess({
  filter: { publication_year: "2023" },
});

Authors Service

// Get author by ORCID
const author = await openAlex.authors.getByOrcid("0000-0002-1825-0097");

// Get authors from institution
const institutionAuthors = await openAlex.authors.getByInstitution("I27837315");

// Get highly cited authors
const topAuthors = await openAlex.authors.getHighlyCited({ per_page: 50 });

// Get co-authors
const coAuthors = await openAlex.authors.getCoAuthors("A2208157607");

Institutions Service

// Get institution by ROR
const institution = await openAlex.institutions.getByRor("05dxps055");

// Get institutions by country
const usInstitutions = await openAlex.institutions.getByCountry("US");

// Get university-type institutions
const universities = await openAlex.institutions.getUniversities();

// Get institution's works
const institutionWorks = await openAlex.institutions.getWorks("I27837315");

Sources Service

// Get source by ISSN
const journal = await openAlex.sources.getByIssn("0028-0836");

// Get open access journals
const oaJournals = await openAlex.sources.getOpenAccess();

// Get journals in DOAJ
const doajJournals = await openAlex.sources.getDoajSources();

// Get sources by publisher
const springerJournals =
  await openAlex.sources.getByPublisher("Springer Nature");

Concepts Service

// Get concept hierarchy
const hierarchy = await openAlex.concepts.getHierarchy("C41008148");

// Get works related to concept
const conceptWorks = await openAlex.concepts.getWorks("C41008148");

// Get top-level concepts
const topConcepts = await openAlex.concepts.getTopLevel();

// Find similar concepts
const similar = await openAlex.concepts.findSimilar(
  "machine learning algorithms",
);

Advanced Usage

Pagination

// Using async generator for automatic pagination
for await (const work of openAlex.works.paginate({
  search: "climate change",
})) {
  console.log(work.title);
}

// Manual pagination
let page = 1;
let hasMore = true;

while (hasMore) {
  const response = await openAlex.works.list({
    search: "quantum computing",
    page,
    per_page: 100,
  });

  // Process works
  response.results.forEach((work) => {
    console.log(work.title);
  });

  hasMore = response.results.length === 100;
  page++;
}

Complex Filtering

const works = await openAlex.works.list({
  filter: {
    "authorships.institutions.country_code": "US",
    publication_year: "2020-2023",
    "open_access.is_oa": true,
    cited_by_count: ">100",
    "concepts.id": "C41008148", // Computer Science
  },
  sort: "publication_date:desc",
});

Grouping and Aggregation

const worksByYear = await openAlex.works.list({
  group_by: "publication_year",
  filter: {
    "concepts.id": "C41008148",
  },
});

console.log(worksByYear.group_by); // Aggregated results by year

Field Selection

// Select only specific fields to reduce response size
const works = await openAlex.works.list({
  select: "id,title,publication_year,cited_by_count",
  search: "artificial intelligence",
});

Error Handling

try {
  const work = await openAlex.works.getByDoi("invalid-doi");
} catch (error) {
  if (error.status_code === 404) {
    console.log("Work not found");
  } else {
    console.error("API Error:", error.message);
  }
}

Rate Limiting and Best Practices

  • Use a descriptive User-Agent: Include your email for faster support
  • Be respectful: Don't make excessive requests
  • Use filters: Be specific to reduce response sizes
  • Implement caching: Cache responses when appropriate
  • Handle errors gracefully: Implement proper error handling

Development

# Install dependencies
npm install

# Build the project
npm run build

# Run linting
npm run lint

# Fix linting issues
npm run lint:fix

# Clean build directory
npm run clean

API Reference

For detailed API documentation, visit OpenAlex API Documentation.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

License

MIT License - see LICENSE file for details.

Support

Changelog

See CHANGELOG.md for version history and updates.