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

ocw-sdk

v0.2.0

Published

TypeScript SDK for MIT Open Learning API - search and access MIT courses, programs, and educational resources

Readme

ocw-sdk

A TypeScript SDK for the MIT Open Learning API - access MIT courses, programs, and educational resources.

npm version License: MIT

Features

  • 📚 Access 49 API endpoints including courses, programs, topics, podcasts, videos, and more
  • 🎓 Browse courses and programs with pagination support
  • 🎙️ Discover podcasts and episodes from MIT
  • 📹 Explore educational videos
  • 🏷️ Search topics to discover related content
  • Manage favorites and learning lists (authentication required)
  • 🔐 Authentication support with Bearer tokens and session cookies
  • 📘 Full TypeScript support with auto-generated types from OpenAPI
  • Built on openapi-fetch for type-safe API calls
  • 🎯 Raw client access for any endpoint with full type safety

Installation

npm install ocw-sdk

or using pnpm:

pnpm add ocw-sdk

or using yarn:

yarn add ocw-sdk

Quick Start

import { OCWClient } from 'ocw-sdk';

// Create a client instance
const client = new OCWClient();

// List courses
const results = await client.listCourses({
  limit: 10,
  offset: 0
});

console.log(results.data);

Usage

Basic Client Initialization

import { OCWClient } from 'ocw-sdk';

// Use default configuration
const client = new OCWClient();

Client with Configuration

import { OCWClient } from 'ocw-sdk';

const client = new OCWClient({
  baseUrl: 'https://api.example.com',  // Optional: custom base URL
  token: 'your-api-token',              // Optional: Bearer token authentication
  sessionCookie: 'session-id',          // Optional: session cookie for auth
  headers: {                            // Optional: custom headers
    'User-Agent': 'MyApp/1.0'
  }
});

Listing Courses

Get a paginated list of all courses:

const courses = await client.listCourses({
  limit: 50,
  offset: 0
});

if (courses.data) {
  console.log(`Total courses: ${courses.data.count}`);
  courses.data.results.forEach(course => {
    console.log(course.title);
  });
}

Getting a Specific Course

Retrieve detailed information about a course by ID:

const course = await client.getCourseById(123);

if (course.data) {
  console.log(course.data.title);
  console.log(course.data.description);
}

Working with Programs

// List all programs
const programs = await client.listPrograms({
  limit: 10,
  offset: 0
});

// Get a specific program
const program = await client.getProgramById(456);

if (program.data) {
  console.log(program.data.title);
}

Exploring Topics

const topics = await client.listTopics({
  limit: 100
});

if (topics.data) {
  topics.data.results.forEach(topic => {
    console.log(topic.name);
  });
}

Working with Podcasts

// List all podcasts
const podcasts = await client.listPodcasts();

if (podcasts.data) {
  podcasts.data.forEach(podcast => {
    console.log(podcast.title);
  });
}

// Get a specific podcast
const podcast = await client.getPodcastById(1);

// Get episodes for a podcast (ID is a string)
const episodes = await client.getPodcastEpisodes('1', {
  limit: 10,
  offset: 0
});

// Get recent podcasts
const recent = await client.getRecentPodcasts();

Browsing Videos

// List videos with pagination
const videos = await client.listVideos({
  limit: 20,
  offset: 0
});

// Get a specific video
const video = await client.getVideoById(123);

// Get newly published videos
const newVideos = await client.getNewVideos();

Managing Favorites (Authentication Required)

// Configure client with authentication
const client = new OCWClient({
  token: 'your-api-token'
});

// List your favorites
const favorites = await client.listFavorites({
  limit: 50
});

// Get a specific favorite by ID
const favorite = await client.getFavoriteById('abc123');

Working with User Lists (Authentication Required)

// List your user lists
const userLists = await client.listUserLists({
  limit: 10
});

// Get a specific user list
const userList = await client.getUserListById(123);

// Get items in a user list
const items = await client.getUserListItems(123, {
  limit: 20
});

Browsing Staff Lists

// List all staff-curated lists
const staffLists = await client.listStaffLists({
  limit: 10
});

// Get a specific staff list
const staffList = await client.getStaffListById(456);

// Get items in a staff list
const items = await client.getStaffListItems(456, {
  limit: 20
});

Advanced: Direct API Access

For full control, access the underlying openapi-fetch client:

const client = new OCWClient();

// Use the raw client for any endpoint
const response = await client.raw.GET('/custom-endpoint/', {
  params: {
    query: { custom_param: 'value' }
  }
});

API Reference

OCWClient

Constructor

constructor(config?: ClientConfig)

ClientConfig Options:

  • baseUrl?: string - Custom API base URL
  • token?: string - Bearer token for authentication
  • sessionCookie?: string - Session cookie for authenticated requests
  • headers?: HeadersInit - Custom HTTP headers

Methods

The SDK provides 27 convenience methods for the most commonly used endpoints, plus a raw client for accessing all 49 API endpoints with full type safety.

Courses
  • listCourses(params?) - List all courses with pagination
    • audience?: 'open' | 'professional'
    • offered_by?: string (e.g., 'OCW', 'MITx')
    • offset?: number
    • limit?: number
  • getCourseById(id) - Get course by ID
  • getFeaturedCourses() - Get featured courses
  • getNewCourses() - Get new courses
  • getUpcomingCourses() - Get upcoming courses
Programs
  • listPrograms(params?) - List all programs with pagination
    • offset?: number
    • limit?: number
  • getProgramById(id) - Get program by ID
Topics
  • listTopics(params?) - List all topics with pagination
    • offset?: number
    • limit?: number
  • getTopicById(id) - Get topic by ID
Podcasts
  • listPodcasts() - List all podcasts
  • getPodcastById(id) - Get podcast by ID
  • getRecentPodcasts() - Get recent podcast episodes
  • getPodcastEpisodes(id, params?) - Get episodes for a podcast
    • id: string - Podcast ID
    • offset?: number
    • limit?: number
Podcast Episodes
  • listPodcastEpisodes(params?) - List all podcast episodes
    • offset?: number
    • limit?: number
  • getPodcastEpisodeById(id) - Get podcast episode by ID
Videos
  • listVideos(params?) - List all videos with pagination
    • offset?: number
    • limit?: number
  • getVideoById(id) - Get video by ID
  • getNewVideos() - Get newly published videos
Favorites (Authentication Required)
  • listFavorites(params?) - List user's favorites
    • offset?: number
    • limit?: number
  • getFavoriteById(id) - Get favorite by ID
    • id: string - Favorite ID
User Lists (Authentication Required)
  • listUserLists(params?) - List user's learning lists
    • offset?: number
    • limit?: number
  • getUserListById(id) - Get user list by ID
  • getUserListItems(userListId, params?) - Get items in a user list
    • userListId: number
    • offset?: number
    • limit?: number
Staff Lists
  • listStaffLists(params?) - List staff-curated lists
    • offset?: number
    • limit?: number
  • getStaffListById(id) - Get staff list by ID
  • getStaffListItems(staffListId, params?) - Get items in a staff list
    • staffListId: number
    • offset?: number
    • limit?: number
Raw Client Access
  • raw - Get the underlying openapi-fetch client for direct access to all 49 API endpoints with full type safety

TypeScript Support

This SDK is written in TypeScript and provides full type safety:

import { OCWClient, type ClientConfig, type paths, type components } from 'ocw-sdk';

// All API responses are fully typed
const client = new OCWClient();
const response = await client.listCourses({ limit: 10 });

// TypeScript knows the shape of response.data
if (response.data) {
  response.data.results.forEach(course => {
    // Auto-complete works here!
    console.log(course.title);
  });
}

// Access OpenAPI types directly
type Course = components['schemas']['Course'];
type Podcast = components['schemas']['Podcast'];
type Video = components['schemas']['Video'];

// Use the raw client with full type safety for all 49 endpoints
const podcasts = await client.raw.GET('/api/v0/podcasts/');
const videos = await client.raw.GET('/api/v0/videos/', {
  params: { query: { limit: 10 } }
});

// TypeScript knows all available paths and their parameters
type AllPaths = keyof paths;
// '/api/v0/courses/', '/api/v0/programs/', '/api/v0/topics/',
// '/api/v0/podcasts/', '/api/v0/videos/', etc.

Error Handling

The SDK uses openapi-fetch which returns responses with data or error:

const response = await client.listCourses({ limit: 10 });

if (response.error) {
  console.error('API Error:', response.error);
  // Handle error
} else {
  console.log('Success:', response.data);
  // Handle success
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT

Links

Author

tupe12334