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

@takashi145/md-quiz

v0.2.0

Published

Generate interactive quizzes from Markdown.

Downloads

197

Readme

md-quiz

A library that generates quiz UI from Markdown.

md-quiz provides only DOM structure, answer processing, state classes, and events. It ships no styles — use your own CSS to control the appearance.

日本語版はこちら

Usage

<div id="app"></div>

<script type="module">
  import { loadQuiz } from '@takashi145/md-quiz';

  const app = document.getElementById('app');

  await loadQuiz('./quiz.md', app, {
    submitLabel: 'Submit',
    autoDisableSubmit: true,
    shuffleChoices: true,
    shuffleQuestions: true,
  });
</script>

loadQuiz() fetches a Markdown file, parses it, and renders the quiz into the specified container.

loadQuiz(src: string, container: HTMLElement, options?: QuizOptions): Promise<QuizInstance>

If you want to fetch or transform the Markdown string yourself, use parse() and createQuiz() directly.

import { parse, createQuiz } from '@takashi145/md-quiz';

const { questions, warnings } = parse(markdown);
const quiz = createQuiz(questions, container);

Markdown

Each question starts with a level-2 heading.

## Question text

Single Choice

Single-choice questions use parentheses.

## Choose one

- ( ) Wrong
- (x) Correct
- ( ) Wrong

Multiple Choice

Multiple-choice questions use square brackets.

## Choose all that apply

- [x] Correct
- [ ] Wrong
- [x] Correct

Fill-In

Fill-in questions use [[answer]].

## `typeof undefined === typeof null` is [[false]].

You can also place blanks in the body text.

## Fill in the blanks

Use arr.[[length]] to get an array length.

Options

interface QuizOptions {
  submitLabel?: string;
  autoDisableSubmit?: boolean;
  shuffleChoices?: boolean;
  shuffleQuestions?: boolean;
}
  • submitLabel: Label for the submit button. Defaults to 確認.
  • autoDisableSubmit: When true, the submit button is disabled until all questions have a selection or input. Defaults to false.
  • shuffleChoices: When true, choice order is randomized. Defaults to false.
  • shuffleQuestions: When true, question order is randomized. Defaults to false.

Events

After each answer, mq-answer is fired.

interface QuizAnswerEventDetail {
  index: number;
  correct: boolean;
  answers: string[];
  inputResults?: boolean[];
}

For fill-in questions, inputResults contains the correctness of each input. For example, if the first of two inputs is correct and the second is not, inputResults will be [true, false]. Choice questions do not include inputResults.

After all questions have been answered, mq-complete is fired.

interface QuizCompleteEventDetail {
  total: number;
  score: number;
}

Example:

app.addEventListener('mq-answer', (event) => {
  console.log(event.detail.correct);
});

app.addEventListener('mq-complete', (event) => {
  console.log(`answered ${event.detail.total} questions`);
});

Styling

md-quiz ships no CSS. Style the quiz using the generated classes below.

| Class | Applied to | | --- | --- | | .mq-quiz | Root element of the entire quiz | | .mq-question | Root element of each question | | .mq-question--single | .mq-question for single-choice questions | | .mq-question--multiple | .mq-question for multiple-choice questions | | .mq-question--fill | .mq-question for fill-in questions | | .mq-question--answered | .mq-question after the question is answered | | .mq-question--correct | .mq-question when answered correctly | | .mq-question--incorrect | .mq-question when answered incorrectly | | .mq-body | Wrapper for the question text and body | | .mq-question-text | Question text generated from the heading | | .mq-choices | Choice list | | .mq-choice | Label for each choice | | .mq-choice--selected | .mq-choice that was selected, shown after answering | | .mq-choice--correct | Correct .mq-choice, shown after answering | | .mq-radio | Radio input for single-choice questions | | .mq-checkbox | Checkbox input for multiple-choice questions | | .mq-input | Text input for fill-in questions | | .mq-input--correct | .mq-input that was correct, shown after answering | | .mq-input--incorrect | .mq-input that was incorrect, shown after answering | | .mq-submit | Submit button |

Some of these classes are also used for event handling and scoring. Do not remove or replace them from the DOM — only adjust their appearance with CSS.