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

@curio-sd/e-module-builder

v0.6.1

Published

A tool for building e-modules for Curio SD

Readme

@curio-sd/e-module-builder

A CLI build tool for creating interactive e-learning modules. It processes a structured content/ directory of Markdown files and produces a Vite-powered, single-page-style site with theory pages, quizzes, exercises, and assignments — one per week.

[!IMPORTANT] If you want to use the template for your own e-module, please go to https://github.com/curio-team/e-module-template and press 'Use this template' on the right.

Installation

npm install --save-dev @curio-sd/e-module-builder

Add these scripts to your project's package.json:

{
  "scripts": {
    "dev":     "e-module-builder dev",
    "build":   "e-module-builder build",
    "preview": "e-module-builder preview"
  }
}

Commands

| Command | Description | | ------- | ----------- | | dev | Start dev server at localhost:5173, watches content/ and hot-reloads | | build | Production build to dist/ | | preview | Locally preview the dist/ build |

Project structure

Your project only needs a content/ directory. Everything else (src/data/, pages/, index.html) is generated automatically.

content/
  module.md               ← module metadata (name, weeks, language, exercise mode)
  week1/
    theory.md             ← theory content (Markdown + YAML frontmatter)
    quiz.md               ← mid-week quiz questions
    assignment.md         ← hand-in assignment
    exercises/
      _meta.md            ← exercise set metadata (week, title, color)
      1.md                ← exercise 1
      2.md                ← exercise 2
      …
  week2/ … weekN/         ← same structure
  assessments/
    theory-assessment.md        ← final theory assessment (optional)
    practical-assessment.md     ← final practical assessment (optional)

Content file formats

content/module.md

---
name: CSS Grid
subtitle: E-module
weeks: 4
language: nl
exerciseMode: interactive   # or: external
description: Learn CSS Grid from the ground up.
youtube: https://www.youtube.com/watch?v=...
logoAlt: My module logo
algemeen:
  - I can explain the difference between Flexbox and Grid
---

| Field | Required | Description | | ----- | -------- | ----------- | | name | yes | Module title | | weeks | yes | Number of weeks to include (limits which weekN/ dirs are processed) | | exerciseMode | yes | interactive (Monaco editor) or external (link-out) | | language | no | UI language, default nl | | subtitle | no | Shown below the title | | description | no | Short module description | | youtube | no | Intro video URL | | algemeen | no | General learning outcomes added to the checklist |


content/weekN/theory.md

YAML frontmatter + Markdown body. The body supports standard Markdown, syntax-highlighted code blocks, and custom block-level elements (see Custom elements).

---
week: 1
title: The building blocks
goal: You understand what CSS Grid is and when to use it.
accent: indigo          # Tailwind color name used as the week's accent color
summary: Short summary shown on the home page.
leeruitkomsten:
  - I can explain what a grid container is
  - I can define columns with grid-template-columns
---

Markdown content here…

content/weekN/quiz.md

---
title: Mid-week quiz — Week 1
passScore: 70
questions:
  - id: q1
    question: What does display:grid do?
    options:
      - Creates a flex container
      - Activates CSS Grid on the element
    correct: 1
    explanation: display:grid activates CSS Grid.
---

content/weekN/assignment.md

The Markdown body is split on blank lines: the first paragraph becomes the case, the rest becomes the assignment description.

---
week: 1
title: Build a page layout
subtitle: Practical assignment
deliverables:
  - A working HTML/CSS page
criteria:
  - Grid is used for the overall layout
maxPoints: 10
tips:
  - Start with the grid container
---

Case description paragraph.

Assignment instructions paragraph.

content/weekN/exercises/_meta.md

---
week: 1
title: CSS Grid exercises
color: indigo
mode: interactive   # optional, overrides module-level exerciseMode for this set
---

content/weekN/exercises/N.md

Each file is a single exercise. The YAML frontmatter holds metadata; for text exercises the markdown body (content below the frontmatter) is rendered as the exercise content.

Text exercise with markdown body (recommended for rich content):

---
id: 1
difficulty: 1
title: Columns
type: text
---

Create a grid with **two equal columns** using `grid-template-columns`.

## Tips

- Use `repeat(2, 1fr)` for equal columns.
- `fr` stands for _fractional unit_.

The body can contain any markdown: headings, bold/italic, lists, images, code blocks, and custom elements. No CSS playground or external link is needed — teachers can write the full exercise content as plain markdown.

Shorthand (inline description in YAML, for very short exercises):

---
type: text
title: Columns
description: Create a grid with two equal columns.
---

When both a body and a description field are present the body takes precedence.

Linking theory pages (optional):

Use linked_theory to attach one or more theory pages to an exercise. A collapsible panel slides in from the right with a tab per week, embedding the theory page so students can look up content without leaving the exercise.

---
id: 3
type: text
title: Columns
linked_theory:
  - week1
  - week2
---

| Field | Required | Description | | ----- | -------- | ----------- | | linked_theory | no | List of week identifiers (e.g. week1). Renders a collapsible right-side panel with tabbed iframes — one per linked week. When absent, no panel or toggle button is shown. Theory pages load without their own navbar inside the panel. |


Interactive (Monaco editor) exercise:

---
type: interactive
title: Add a gap
starterHtml: "<div class='grid'>…</div>"
starterCss: ".grid { display: grid; }"
solution: ".grid { display: grid; gap: 16px; }"
---

External exercise (link-out):

---
type: external
title: Grid Garden
url: https://cssgridgarden.com
---

content/assessments/theory-assessment.md and practical-assessment.md

Same structure as quiz.md. Practical assessment questions may include a preview field with css and html for a live CSS preview alongside the question.


Custom elements in Markdown

Theory pages support these custom block elements in Markdown:

| Element | Purpose | | ------- | ------- | | <x-callout> | Highlighted note block. Add type="warning" for warnings. | | <x-card title="…"> | Content card with a title. | | <x-compare> / <x-compare-item title="…"> | Side-by-side comparison columns. | | <x-nav label="…"> | Bottom navigation links (one Markdown link per line). |

Example:

<x-callout type="warning">
Watch out: only **direct children** of the grid container become grid items.
</x-callout>

<x-compare>
<x-compare-item title="Flexbox — one direction">

Use for components: navbars, button rows.

</x-compare-item>
<x-compare-item title="Grid — two directions">

Use for full page layouts.

</x-compare-item>
</x-compare>

What gets generated

The build pipeline runs before Vite and produces:

| Output | Source | | ------ | ------ | | src/data/manifest.json | module.md + all week frontmatter | | src/data/theory-weekN.json | weekN/theory.md | | src/data/meetmoment-quiz-weekN.json | weekN/quiz.md | | src/data/exercises/weekN.json | weekN/exercises/ | | src/data/inleveropdracht-weekN.json | weekN/assignment.md | | src/data/checklist.json | leeruitkomsten from all weeks | | src/data/meetmoment-theorie.json | assessments/theory-assessment.md | | src/data/meetmoment-praktijk.json | assessments/practical-assessment.md | | pages/weekN-theorie.html | generated from template | | pages/weekN-oefeningen.html | generated from template | | pages/weekN-meetmoment.html | generated from template | | pages/weekN-oefening.html | generated from template | | pages/weekN-inleveropdracht.html | generated from template | | pages/checklist.html | generated from template | | pages/meetmoment-theorie.html | generated from template | | pages/meetmoment-praktijk.html | generated from template | | index.html | generated from template |

In dev mode, changes to content/ trigger an automatic rebuild and browser reload.