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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@mzebley/mark-down

v1.2.2

Published

mark↓ core runtime and shared utilities

Downloads

545

Readme

mark↓ Core Runtime

(published as @mzebley/mark-down)

This package provides the framework-agnostic SnippetClient and supporting types used to fetch, cache, and render Markdown snippets at runtime. For a monorepo overview visit the root README.

Table of contents

  1. Installation
  2. Quick start
  3. Client options
  4. Working with snippets
  5. SSR and custom fetch functions
  6. Static sites / CDN usage
  7. Zero-build inline mode
  8. Testing & type safety
  9. Related packages
  10. Roadmap

Installation

Install the runtime alongside your application code:

npm install @mzebley/mark-down

You will also need a manifest file generated by the CLI. See the CLI documentation for steps to build snippets-index.json.

Quick start

import { SnippetClient } from "@mzebley/mark-down";

const client = new SnippetClient({
  manifest: "/snippets-index.json",
});

const hero = await client.get("getting-started-welcome");
const components = await client.listByType("component");

console.log(hero.title);

The client lazily loads the manifest when first needed, then fetches Markdown files on demand. Results are cached for the lifetime of the client instance.

Client options

SnippetClient accepts a single configuration object:

  • manifest (string | SnippetMeta[] | () => Promise<SnippetMeta[]>) – where to load the manifest. Provide a URL, an in-memory array, or an async factory.
  • base (string) – optional base path prepended to relative snippet paths. The client infers the directory from the manifest URL when omitted.
  • fetch ((url: string) => Promise<Response | string>) – inject a custom fetch implementation. Use this for SSR, testing, or advanced caching.
  • frontMatter (boolean, default true) – toggle YAML front-matter parsing.
  • cache (boolean, default true) – enable or disable per-snippet and manifest memoisation.
  • verbose (boolean) – log helpful warnings (for example, slug mismatches) during development.
  • render ((markdown: string) => string | Promise<string>) – override the default marked renderer when you need custom HTML output.

All options are optional except manifest. Results are rendered with marked by default; override at the application level if you need a different Markdown pipeline.

Working with snippets

Commonly used APIs:

  • client.get(slug) – fetch a single snippet. Throws SnippetNotFoundError if the manifest does not include the slug.
  • client.listAll() – return a copy of every manifest entry.
  • client.listByType(type) / client.listByGroup(group) – targeted manifest filters.
  • client.search({ type, group, tags, tagsMode }) – multi-field search helper with tag matching.
  • client.getHtml(slug) – convenience wrapper that resolves directly to HTML.
  • client.invalidate() / client.invalidateSlug(slug) – clear caches to force refetching.

Metadata is preserved exactly as declared in front matter. Standard keys (slug, title, etc.) are copied onto SnippetMeta, additional properties live inside extra, and the resolved Snippet includes both rendered HTML and an optional raw Markdown string (without front matter) for advanced use cases.

SSR and custom fetch functions

The runtime runs in browsers, Node.js, or edge runtimes. For server-side rendering:

import fetch from "node-fetch";
import { SnippetClient } from "@mzebley/mark-down";

const client = new SnippetClient({
  manifest: () => import("./snippets-index.json"),
  fetch: (url) => fetch(url).then((response) => {
    if (!response.ok) {
      throw new Error(`Request failed with status ${response.status}`);
    }
    return response;
  }),
});

You can also pre-seed snippets by passing an array to manifest to avoid network requests entirely. When cache is disabled the client re-fetches both manifest and snippet payloads on every request.

Static sites / CDN usage

Need to run mark↓ inside a plain <script type="module"> context? Use the pre-bundled browser build published at dist/browser.js. It automatically polyfills the minimum Buffer APIs required by the runtime.

<script type="module">
  import { SnippetClient } from "https://cdn.jsdelivr.net/npm/@mzebley/mark-down/dist/browser.js";

  const client = new SnippetClient({ manifest: "./snippets-index.json" });
  const hero = await client.get("marketing-hero");
  document.querySelector("#hero").innerHTML = hero.html;
</script>

As long as you host snippets-index.json (generated by the CLI) alongside your static assets, this bundle works without any additional tooling or manual Buffer shims.

Zero-build inline mode

Introduction

Need Markdown inside plain HTML without a manifest, build step, or Node runtime? mark↓ ships a lightweight inline helper that scans the DOM for raw Markdown, renders it with the same marked pipeline used by SnippetClient, and progressively enhances the page. Content stays inside the HTML you ship, so crawlers and no-JS users can still read the raw Markdown even before JavaScript runs.

Installation

Install the core package as usual:

npm install @mzebley/mark-down
  • Bundlers / ESM: import the inline helper directly.

    import { enhanceInlineMarkdown } from "@mzebley/mark-down/inline";
  • Static <script> usage: include the prebuilt UMD bundle that exposes window.markDownInline.

    <script src="/node_modules/@mzebley/mark-down/dist/mark-down-inline.umd.js"></script>
    <script>
      document.addEventListener("DOMContentLoaded", () => {
        window.markDownInline.enhanceInlineMarkdown();
      });
    </script>

Host the UMD file yourself or load it from a CDN—no build tooling required.

Basic usage (happy path)

Write plain Markdown directly in your HTML. The helper finds [data-markdown] blocks by default.

<div data-markdown>
# Hello

This is inline markdown with no build step.
</div>

<script src="path/to/mark-down-inline.umd.js"></script>
<script>
  document.addEventListener("DOMContentLoaded", function () {
    window.markDownInline.enhanceInlineMarkdown();
  });
</script>

The Markdown text remains in the DOM for SEO while JavaScript enhances it to semantic HTML for users.

Advanced usage (power path with front matter)

You can optionally prepend YAML front matter to provide metadata for each block. Fields are parsed with the same utilities used by the manifest flow.

<div data-markdown>
---
slug: intro
title: Introduction
tags: [hero]
variant: lead
---

# Introduction

This block has metadata.
</div>
  • slug → sets id="intro" if no ID exists and data-slug="intro", allowing deep links.
  • title → stored in data-title for TOC/index generation.
  • tags → serialized to data-tags="hero" (comma-separated when multiple) for light-weight client-side filtering.
  • variant → adds a class like md-block--lead so you can theme specific sections.

You still get fully rendered HTML, but additional attributes unlock progressive enhancement such as TOCs or custom styling.

Options

Configure the helper per page:

enhanceInlineMarkdown({
  selector?: string; // defaults to "[data-markdown]"
  processFrontMatter?: boolean; // defaults to true
  applyMetaToDom?: boolean; // defaults to true
});
  • Use selector to target different attributes or classes.
  • Disable processFrontMatter when the block contains literal --- fences that should stay visible.
  • Set applyMetaToDom to false if you only care about rendered HTML and not DOM metadata.

SEO & progressive enhancement

  • Raw Markdown lives directly in your HTML, so crawlers can index the text before scripts execute.
  • Users without JavaScript still see readable Markdown; JavaScript simply upgrades it to semantic HTML, adds IDs, and decorates DOM attributes for richer UX.
  • This inline mode is ideal for small/medium static pages or marketing sites. Larger doc sites should continue using the manifest-driven snippet system for better caching and composition.

Testing & type safety

  • Use SnippetMeta and Snippet TypeScript types to describe props and state in your application.
  • Mock the client by providing a manifest array or by stubbing the fetch option.
  • Run the workspace tests with npm run test -- core to exercise Vitest suites that cover caching, filtering, and Markdown conversion.

Related packages

  • CLI – generate and watch manifests during development.
  • Angular adapter – DI-aware provider, service, and component abstractions.
  • React adapter – Hooks and components for React and Next.js applications.

Looking for a step-by-step walkthrough? Start from the Quick start guide in the root README.

Roadmap

  • Tag-aware helpers – add listByTag and listByExtra filters for common metadata structures.
  • Prefetch & hydration APIs – expose utilities for bundling snippets with static builds or preloading ahead of navigation.
  • Search integration – optional fuzzy search index built from manifest data.
  • Cache policies – allow LRU or time-based eviction strategies to better suit long-lived sessions.