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

@mwhepworth/canvas-lms-gradebook

v0.1.0-beta.1

Published

Canvas LMS gradebook utilities

Readme

@canvas-lms/gradebook

Utilities for managing gradebooks, submissions, and grading operations in Canvas LMS.

Installation

npm install @canvas-lms/gradebook @canvas-lms/core

Quick Start

import { CanvasAPI } from '@canvas-lms/core';
import { GradebookUtils } from '@canvas-lms/gradebook';

const api = new CanvasAPI('https://your-school.instructure.com', 'your-api-token');
const gradebook = new GradebookUtils(api);

// Get all submissions for an assignment
const submissions = await gradebook.getSubmissions('123', '456');

// Update a single grade
await gradebook.updateSubmissionGrade('123', '456', '789', {
  posted_grade: '95',
  comment: { text_comment: 'Excellent work!' }
});

// Get grade statistics
const stats = await gradebook.getGradeStatistics('123', '456');
console.log(`Average: ${stats.average}, Range: ${stats.min}-${stats.max}`);

Features

  • 📊 Grade Management - Update individual and bulk grades
  • 📈 Statistics - Calculate grade statistics and analytics
  • 📋 Submission Tracking - Find ungraded, missing, and late submissions
  • 📤 Export Capabilities - Export grades to CSV format
  • 📐 Curve Application - Apply curves to assignment grades
  • 🎯 Filtering - Filter submissions by status, date, and other criteria

API Reference

GradebookUtils

Main class for gradebook operations.

Constructor

import { GradebookUtils } from '@canvas-lms/gradebook';
import { CanvasAPI } from '@canvas-lms/core';

const api = new CanvasAPI(baseURL, token);
const gradebook = new GradebookUtils(api);

Methods

Submission Management

getSubmissions(courseId, assignmentId, options)

Get all submissions for an assignment.

const submissions = await gradebook.getSubmissions('123', '456', {
  include: ['user', 'submission_comments', 'rubric_assessment']
});

getUngradedSubmissions(courseId, assignmentId)

Find submissions that need grading.

const ungraded = await gradebook.getUngradedSubmissions('123', '456');
console.log(`${ungraded.length} submissions need grading`);

getMissingSubmissions(courseId, assignmentId)

Find students who haven't submitted.

const missing = await gradebook.getMissingSubmissions('123', '456');
console.log(`${missing.length} students haven't submitted`);

getLateSubmissions(courseId, assignmentId)

Find late submissions.

const late = await gradebook.getLateSubmissions('123', '456');
console.log(`${late.length} late submissions`);
Grade Updates

updateSubmissionGrade(courseId, assignmentId, userId, gradeData)

Update a single submission grade.

await gradebook.updateSubmissionGrade('123', '456', '789', {
  posted_grade: '88',
  comment: { text_comment: 'Good improvement!' }
});

bulkUpdateGrades(courseId, assignmentId, gradeUpdates)

Update multiple grades at once.

const updates = [
  { userId: '789', grade: '95', comment: 'Excellent work!' },
  { userId: '790', grade: '87', comment: 'Good job!' },
  { userId: '791', grade: '92', comment: 'Very good!' }
];

const results = await gradebook.bulkUpdateGrades('123', '456', updates);
// Results include success/failure status for each update
Statistics and Analytics

getGradeStatistics(courseId, assignmentId)

Calculate comprehensive grade statistics.

const stats = await gradebook.getGradeStatistics('123', '456');
console.log(stats);
// {
//   totalSubmissions: 25,
//   gradedSubmissions: 20,
//   average: 85.5,
//   min: 65,
//   max: 98,
//   median: 87
// }

getGradebookSummary(courseId)

Get a complete gradebook summary for a course.

const summary = await gradebook.getGradebookSummary('123');
console.log(`Course has ${summary.totalAssignments} assignments`);
summary.assignments.forEach(assignment => {
  console.log(`${assignment.name}: avg ${assignment.stats.average}`);
});
Grade Modifications

applyCurve(courseId, assignmentId, curvePoints)

Apply a curve by adding points to all grades.

// Add 5 points to all grades
const results = await gradebook.applyCurve('123', '456', 5);
console.log(`Applied +5 curve to ${results.length} submissions`);
Export and Reporting

exportGradesToCSV(courseId, assignmentId)

Export grades to CSV format.

const csvData = await gradebook.exportGradesToCSV('123', '456');
console.log(`Exported: ${csvData.filename}`);
console.log(csvData.content); // CSV content

Common Use Cases

Grading Workflow

// 1. Find ungraded submissions
const ungraded = await gradebook.getUngradedSubmissions('123', '456');
console.log(`${ungraded.length} submissions to grade`);

// 2. Grade them (example: auto-grade based on submission status)
const gradeUpdates = ungraded.map(submission => ({
  userId: submission.user_id,
  grade: submission.submitted_at ? '80' : '0',
  comment: submission.submitted_at ? 'Submitted on time' : 'Missing submission'
}));

// 3. Apply the grades
const results = await gradebook.bulkUpdateGrades('123', '456', gradeUpdates);

// 4. Report results
const successful = results.filter(r => r.success).length;
console.log(`Updated ${successful} grades successfully`);

Assignment Analysis

// Get comprehensive assignment statistics
const stats = await gradebook.getGradeStatistics('123', '456');
const late = await gradebook.getLateSubmissions('123', '456');
const missing = await gradebook.getMissingSubmissions('123', '456');

console.log(`Assignment Analysis:
  - Average Grade: ${stats.average}%
  - Grade Range: ${stats.min}% - ${stats.max}%
  - Late Submissions: ${late.length}
  - Missing Submissions: ${missing.length}
  - Completion Rate: ${((stats.totalSubmissions - missing.length) / stats.totalSubmissions * 100).toFixed(1)}%`);

Course-wide Grading

// Process all assignments in a course
const summary = await gradebook.getGradebookSummary('123');

for (const assignment of summary.assignments) {
  console.log(`\n${assignment.name}:`);
  console.log(`  Average: ${assignment.stats.average}%`);
  console.log(`  Graded: ${assignment.stats.gradedSubmissions}/${assignment.stats.totalSubmissions}`);
  
  // Apply curve if average is below 75%
  if (assignment.stats.average < 75) {
    const curvePoints = 75 - assignment.stats.average;
    console.log(`  Applying +${curvePoints} curve...`);
    await gradebook.applyCurve('123', assignment.id, curvePoints);
  }
}

Export and Backup

// Export grades for all assignments
const assignments = await api.getAssignments('123');

for (const assignment of assignments) {
  try {
    const csvData = await gradebook.exportGradesToCSV('123', assignment.id);
    // Save or process CSV data
    console.log(`Exported: ${csvData.filename}`);
  } catch (error) {
    console.error(`Failed to export ${assignment.name}:`, error.message);
  }
}

Data Privacy

The GradebookUtils class handles student data responsibly:

  • Grade Updates: Only updates grades, doesn't store student information
  • Export Functions: Includes student names/IDs only in exported data
  • Statistics: Aggregated data doesn't expose individual student information
  • Error Handling: Errors don't leak sensitive student data

Performance Tips

  • Bulk Operations: Use bulkUpdateGrades() instead of individual updateSubmissionGrade() calls
  • Filtered Requests: Use specific submission queries (ungraded, missing, late) instead of getting all submissions
  • Caching: Cache assignment and course data when processing multiple assignments
  • Rate Limiting: Built on @canvas-lms/core which handles Canvas API rate limiting

Error Handling

try {
  await gradebook.updateSubmissionGrade('123', '456', '789', { posted_grade: '95' });
} catch (error) {
  if (error.message.includes('not found')) {
    console.error('Assignment or student not found');
  } else if (error.message.includes('permission')) {
    console.error('Insufficient permissions to update grades');
  } else {
    console.error('Grade update failed:', error.message);
  }
}

Related Packages

License

ISC © Matthew Hepworth