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

@falkenslab/moodle-driver

v0.13.0

Published

Full control of Moodle as any user, from code or the command line, with their own login: no web services, no tokens, no admin.

Readme

moodle-driver

Everything a person does in Moodle, from your Node.js code. With their own login: no web services, no tokens, no admin.

npm Node.js 20+ TypeScript Moodle 4.x and 5.x License: MIT

📖 Documentation · 📖 Documentación en español

moodle-driver is a Node.js library, and a moodle command, that works a Moodle site the way a person does: it lists their courses, reads content, submits assignments and answers quizzes as a student, and builds courses, grades with rubrics, runs forums and the gradebook as a teacher. It drives a real browser logged in as that person, calling the same AJAX services and filling the same forms Moodle's own pages use, so it works on any Moodle 4.x or 5.x site with no web service tokens, no administrator and no plugin. Results are plain typed data, and every function declares the kind of data it touches.

✨ Why moodle-driver

  • 🔑 The person's own login. They log in once in a window (SSO and two-factor included); the driver never sees a password.
  • 🧩 No web services. Many campuses don't enable them. The driver uses the same pages and AJAX services Moodle's own screens use: the services over plain HTTP with the person's session, the browser to log in, fill forms and read pages.
  • 🔐 Moodle decides. It can do what the person can do, and nothing more: every permission is Moodle's.
  • 🌍 Any language. Pages are read by structure (ids, data attributes, field names), never by their text.
  • 🐢 At a person's pace when acting as a student, so Moodle's logs and completion look like a person's; or fast when time matters.
  • 🛡️ Safe to hand to an agent. Every function declares the data it touches (own, course content, others' work, communication…), so a program can allow only some.
  • 📦 Plain data, typed. JSON results, ISO dates, long lists a page at a time, errors with stable codes, TypeScript types included.
  • 🖥️ A library and a command. The same operations from your code or from a terminal.

🚀 Quick start

You need Node.js 20+, a Moodle 4.x or 5.x site, and Edge or Chrome (or let it download Chromium, or Playwright's Firefox if you choose it). Add it to your project:

npm install @falkenslab/moodle-driver playwright-core

Then, in your program:

import { createMoodle } from "@falkenslab/moodle-driver";

await using moodle = createMoodle({ site: "https://campus.example.org/", profileDir: "/home/ada/.moodle-profile", headless: true, downloadBrowser: true });
await moodle.logIn(); // 🔑 the first time a window opens and the person logs in; afterwards, nothing

for (const course of await moodle.listCourses()) {
  const { pending } = await moodle.pendingActivities(course.id);
  console.log(`📚 ${course.fullname}: ${pending.length} things to do`);
}

That's it: no API keys, nothing to ask the administrator. The browser closes by itself at the end of the block. Step by step in installation and your first program.

Every method is also a command of moodle, which comes with the package:

npm i -g @falkenslab/moodle-driver
moodle login --site https://campus.example.org/   # 🔑 once: a window opens, you log in
moodle list-courses
moodle deadlines --days 7
moodle grade-submission 35 7 --grade 8.5 --feedback "<p>Great work!</p>" --notify
moodle my-grades 3 --json | jq '.[] | select(.grade) | .name'

Tables at a terminal, JSON for scripts, errors with their code and an exit status. moodle help lists every command, generated from the API so none is missing; --allow own,course-content refuses anything touching other people's data. moodle shell --show keeps one browser open while you type commands, to watch each act, and moodle open --show leaves one open for separate commands from any terminal (reachable only with a token of yours) until moodle close. See the command line.

🧪 A taste of the code

🧑‍🎓 A student's week, deadlines first:

for (const d of await moodle.deadlines({ days: 7 })) {
  console.log(`${d.date.slice(0, 10)}  ${d.activity}${d.overdue ? "  ⚠️ overdue" : ""}`);
}

👩‍🏫 A teacher grading what's waiting, with feedback the student gets notified of:

for (const s of await moodle.assignmentSubmissions(35)) {
  if (s.needsGrading) await moodle.gradeSubmission(35, s.userId, { grade: 8.5, feedback: "<p>Great work!</p>", notify: true });
}

🏗️ Building a course: every write tells you what it did:

const { changed } = await moodle.createActivity({ courseId: 3, sectionId: 7, type: "page", name: "Loops", content: "<p>for, while…</p>" });
console.log(changed); // Created page 42 "Loops" in section 2.

🤝 Sharing a unit with another teacher, anonymous, restored on their site where they want it:

const { file } = await moodle.backupCourse(3, "/home/ada/catalog", { sections: [12], activities: [57] }); // no names, no origin
const { activities } = await moodle.backupContents(file.path); // what it holds, read locally
await colleague.restoreCourse(file.path, { into: 8, afterSectionId: 30 }); // as new sections after section 30

📸 See it at work

A real session: the moodle command, logged in as a teacher of a Moodle 5.2 site, lists a course's participants and groups and reads a quiz, each in one line.

Complete programs for real tasks, commented, are in the examples.

🧰 What's inside

| Area | For example | | --- | --- | | 📚 Courses and content | Course structure and updates, pages, books, files and folders, H5P and SCORM content | | 🏗️ Building courses | Sections and activities of any type, settings, restrictions and completion, the course page's blocks, images embedded in rich text, databases' fields, templates and entries, external tools (LTI) | | 📝 Assignments and grading | Submissions, rubrics and marking guides, the marking workflow, extensions, feedback files | | ❓ Quizzes and questions | Attempts, results, statistics, manual grading, quiz layout and overrides, question banks with GIFT and Moodle XML import and export, their categories, the question types a site offers | | 📊 Gradebook and reports | The grader report, grade items and categories, exports, completion, badges and competencies, activity and participation reports, logs | | 👥 Participants and groups | Enrolments and their methods, roles, groups and groupings, notes about participants | | 💬 Forums and messages | Discussions, replies, ratings and subscriptions, workshops, glossary entries and their approval, wiki pages and their history, notifications and conversations | | 📅 Calendar and to-dos | Events, deadlines, what's pending and what changed, BigBlueButton meetings and their recordings | | 🔄 Course life cycle | Copies, resets, imports, backups and restores, whole or in part, anonymous for sharing | | 🧩 For your program | Typed results and errors, data categories, the session's low-level pieces, a fake Moodle for tests |

Every function, by area, is in the Moodle areas guide and the API reference.

📚 Documentation

  • 🏁 Getting started: install, log in, your first program.
  • 💡 Concepts: how it works, the browser, errors, pace, data categories.
  • 🖥️ Command line: the moodle command, to log in, run any operation and script it.
  • 🗺️ Moodle areas: every function, by area: courses, quizzes, grading, forums…
  • 📖 Examples: complete programs for real tasks, commented.
  • 📘 Glossary: Moodle's terms, explained for programmers.
  • ⌨️ Commands: every command, its arguments and options.
  • 🔎 API reference: generated from the code.

🛠️ Developing

npm install
npm run typecheck && npm run lint
npm run test:docker    # the tests open browsers: always in Docker, never on the desktop
npm run test:sandbox   # every function against a real Moodle (the sandbox), on demand (it takes hours)
npm run build          # dist/, with declarations
npm run docs:check     # every example in the docs compiles against the code

More in development; the design lives in .minispec/ (start with core/project.md and the decisions). Extracted from moodle-mcp, its first consumer.

Made with 💖 by Falken's Lab Team