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

@williamcachamwri/markui-compiler

v0.2.0

Published

Markdown and directive compiler for MarkUI

Readme

@williamcachamwri/markui-compiler

Compiles Markdown, YAML frontmatter, GFM, and strict Markdown directives into the versioned, framework-neutral MarkUI AST.

Install

npm install @williamcachamwri/markui-compiler

Compile Markdown

import { compileMarkdown } from '@williamcachamwri/markui-compiler'

const result = compileMarkdown(`
---
title: Account
---

# {{ state.user.name }}

::input{name="email" bind="state.user.email"}

::::card{title="Actions"}
:::button{action="save"}
Save
:::
::::
`, {
  filename: 'src/pages/account.md',
})

if (!result.valid) {
  console.error(result.diagnostics)
}

Use ::name{...} for a leaf directive. Use matching fences of at least three colons for a directive containing Markdown children.

:::card{title="Profile"}
Content
:::

Nested containers require longer outer fences:

::::grid
:::card
Content
:::
::::

This rule matches the directive parser and removes ambiguity about which level a closing marker belongs to.

Strict validation

compileMarkdown performs a source-positioned directive scan before remark-directive creates the Markdown AST. A document with directive syntax errors is invalid and receives an empty renderable child list, preventing malformed marker text from reaching a renderer.

The validator ignores directive-looking content inside fenced code blocks, inline code, escaped text, and ordinary prose where the marker is not in directive position.

Stable directive diagnostic codes:

| Code | Meaning | |---|---| | MUI1001 | Malformed directive statement | | MUI1002 | Unclosed container directive | | MUI1003 | Unexpected closing marker | | MUI1004 | Invalid container nesting or fence width | | MUI1005 | Leaf-only component used as a container | | MUI1006 | Reserved for container-only syntax validation | | MUI1007 | Unknown directive/component | | MUI1008 | Invalid or duplicate attributes | | MUI1009 | Trailing directive marker | | MUI1010 | Ambiguous syntax or leaked marker invariant |

Example failure:

:::card
Missing close
src/pages/account.md:1:1 [MUI1002]
Container directive "card" is not closed.

Structured diagnostics

const result = compileMarkdown(source, {
  filename: 'src/pages/account.md',
})

for (const diagnostic of result.diagnostics) {
  console.log({
    code: diagnostic.code,
    severity: diagnostic.severity,
    file: diagnostic.file,
    line: diagnostic.line,
    column: diagnostic.column,
    endLine: diagnostic.endLine,
    endColumn: diagnostic.endColumn,
    message: diagnostic.message,
    hint: diagnostic.hint,
    related: diagnostic.related,
  })
}

Set throwOnError: true to throw MarkUICompileError containing the same diagnostics.

Options

interface CompileOptions {
  filename?: string
  registry?: ComponentRegistry
  allowHtml?: boolean
  throwOnError?: boolean
}
  • filename is included in diagnostics and the generated document.
  • registry controls which components, syntax forms, and props are valid.
  • allowHtml preserves raw HTML nodes. It does not sanitize them.
  • throwOnError throws when an error diagnostic exists.

Component schema validation

The compiler combines grammar validation with the component registry. It checks:

  • registered component names;
  • allowChildren and leaf/container syntax;
  • required props;
  • static prop types and enum values;
  • duplicate directive attributes;
  • unknown props, which currently produce warnings;
  • expression and template syntax.

A component with allowChildren: false, such as stat, cannot use container syntax:

:::stat{value="10"}
Invalid child content
:::

Use the leaf form instead:

::stat{value="10"}

URL policy

Link and image URLs allow:

  • relative and fragment URLs;
  • http: and https:;
  • mailto: and tel:.

Other explicit protocols, including javascript:, data:, and vbscript:, produce an error and compile to an empty URL. Control characters and whitespace cannot disguise a blocked protocol.

Raw HTML

Raw HTML is disabled by default and emitted as text with a warning. Setting allowHtml: true preserves a raw-html AST node:

const result = compileMarkdown('<b>trusted source</b>', {
  allowHtml: true,
})

The renderer must still require an explicit sanitizer. Enabling this option is not a substitute for sanitization.

Frontmatter logic

The compiler treats frontmatter as data. Resolution of a logic module is performed by @williamcachamwri/markui-vite, which only accepts relative module paths beginning with ./ or ../.

Compatibility

Generated documents include the current MARKUI_DOCUMENT_VERSION. Consumers should validate that version through @williamcachamwri/markui-core before rendering or transforming the AST.