openalex-client
v1.2.0
Published
TypeScript SDK for OpenAlex academic database API
Maintainers
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-clientQuick 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 yearField 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 cleanAPI Reference
For detailed API documentation, visit OpenAlex API Documentation.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
MIT License - see LICENSE file for details.
Support
Changelog
See CHANGELOG.md for version history and updates.
