DEV Community

Tosiiko
Tosiiko

Posted on

I built MDL — a tiny authoring language so you never write raw HTML again

The problem

Every web project starts the same way. You open a blank file and start typing angle brackets.

HTML is fine. But writing it by hand is noisy, repetitive, and forces you to think about tags instead of content.

What I built

MDL (Markdown Language) is a tiny authoring language that compiles to clean, semantic HTML.

The idea is three rules:

  • .mdl files handle structure and content
  • .css files handle layout and design
  • .js files handle logic

You never write a single HTML tag.

What it looks like

page:
  hero:
    ## Sign in
    Welcome back.

  form@id(loginForm)@submit(handleLogin):
    field:
      label:
        Email
      .input@type(email)@id(email)@required

    actions:
      .btn-primary@id(loginBtn)(Sign in)
      .btn-ghost@click(handleForgot)(Forgot password?)
Enter fullscreen mode Exit fullscreen mode

That compiles to:

<main class="mdl-page">
  <div class="mdl-hero">
    <h2>Sign in</h2>
    <p>Welcome back.</p>
  </div>
  <form class="mdl-form" id="loginForm" data-mdl-on-submit="handleLogin">
    <div class="mdl-field">
      <label class="mdl-label">Email</label>
      <input class="mdl-input" type="email" id="email" required>
    </div>
    <div class="mdl-actions">
      <button class="mdl-btn-primary" id="loginBtn">Sign in</button>
      <button class="mdl-btn-ghost" data-mdl-on-click="handleForgot">Forgot password?</button>
    </div>
  </form>
</main>
Enter fullscreen mode Exit fullscreen mode

Clean, semantic HTML. No divs you didn't ask for. No inline styles. Every element has a predictable .mdl-* class that CSS can target.

How CSS and JS talk to it

CSS targets .mdl-* classes directly. No configuration needed.

JS uses standard DOM APIs. The @id() attribute compiles to a real HTML id. The @submit() and @click() attributes wire events to functions in your external JS file.

// scripts/auth.js
export async function handleLogin(e) {
  e.preventDefault()
  const email = document.querySelector('#email').value
  // your logic here
}
Enter fullscreen mode Exit fullscreen mode

No framework. No runtime. No magic. Just the platform.

How to install

npm install -g @tosiiko/mdl
mdl --help
Enter fullscreen mode Exit fullscreen mode

The CLI is a prebuilt Rust binary. Fast, no dependencies, works on Mac, Linux, and Windows.

Links

Would love to hear what you think.

Top comments (0)