# @tosiiko/mdl

MDL is a small authoring language for building clean HTML without writing raw
HTML by hand. Write `.mdl` files, add normal CSS and JavaScript, then use the
`mdl` CLI to check, build, and serve the project.

## Quick Start

Install inside a project folder:

```bash
mkdir my-mdl-site
cd my-mdl-site
npm install @tosiiko/mdl
source bin/activate
mdl serve
```

A local install runs `mdl init --quiet` when starter files are missing, so the
folder is immediately ready for development. `bin/activate` adds the
project-local command shims to your shell path, prefixes your prompt with
`(mdl:<folder>)`, and can be undone with `deactivate_mdl`.

Open `http://127.0.0.1:3999`, edit `apps/my-mdl-site/pages/index.mdl`, and
style it in `apps/my-mdl-site/css/components.css`.

Skip automatic initialization when you only want the package installed:

```bash
MDL_SKIP_INIT=1 npm install @tosiiko/mdl
```

Install globally when you want `mdl` available everywhere:

```bash
npm install -g @tosiiko/mdl
mdl new my-mdl-site
cd my-mdl-site
mdl serve
```

## What `mdl init` Creates

```text
my-mdl-site/
  README.md
  .gitignore
  bin/
    activate
  apps/
    my-mdl-site/
      mdl.json
      pages/
        index.mdl
      css/
        main.css
        layout.css
        components.css
      scripts/
        app.js
      assets/
        mdl-logo-tagline-light.png
```

The generated site works immediately:

```bash
mdl check
mdl build
mdl serve
```

If this workspace has one app, commands auto-select it. After adding more apps,
pass the app folder or short app name explicitly, such as `mdl serve apps/admin`
or `mdl check admin`.

`mdl check` validates configured files, source routes, local MDL/Markdown/CSS
image, media, font assets and recursive CSS imports, plus common
accessibility/form mistakes before you build. `mdl build` also writes
`dist/mdl-manifest.json` for generated page routes and output assets, plus
`*.html.mdlmap.json` sidecars that map generated HTML lines back to MDL source
lines. Use `mdl check --json` for editor, CI, or language-server diagnostics
with line/column ranges.

`mdl serve` starts the dev server on `http://127.0.0.1:3999`, watches the app
folder, and reloads the browser when files change.

Add another app to the same workspace without reinstalling:

```bash
mdl init --app admin --port 4001
mdl serve apps/admin
```

Public examples and issue tracking live at
<https://github.com/tosiiko/mdl-code>.

## Starter Page

```mdl
page:
  hero:
    .img@src(assets/mdl-logo-tagline-light.png)@alt(MDL logo)
    # my-mdl-site
    Built with MDL.

  nav:
    .link(home)

  section:
    ## Get started

    Edit `pages/index.mdl` to build your page.
    Style it in `css/components.css`.
```

## Project Config

Commands without an explicit `.mdl` file read `mdl.json` from the current
directory or from the only `apps/*/mdl.json` in the workspace. If there are
multiple apps, choose one with `mdl serve apps/admin`, `mdl check apps/shop`, or
the short form `mdl serve admin`. MDL supports `//` and `/* ... */` comments in
config files so unused areas can stay visible without becoming active.

```jsonc
{
  "name": "my-mdl-site",

  "lang": "en",
  "title": "my-mdl-site",
  "description": "Built with MDL.",
  // "canonical": "https://example.com/",
  "favicon": "assets/mdl-logo-tagline-light.png",
  "viewport": "width=device-width, initial-scale=1",
  "meta": [
    // { "property": "og:title", "content": "my-mdl-site" }
  ],
  "links": [
    // { "rel": "manifest", "href": "site.webmanifest" }
  ],
  "social": {
    "enabled": true,
    // "image": "assets/social-card.png"
  },

  // This config lives inside one app. Paths below are relative to this folder.

  "entry": "pages/index.mdl",
  "pages": "pages",
  "output": "dist",
  "css": {
    "runtime": true,
    "bundle": "dist/app.css"
  },
  "styles": [
    "css/main.css",
    "css/layout.css",
    "css/components.css"
    // , "css/theme.css"
  ],
  "head_scripts": [
    // "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"
  ],
  "scripts": [
    "scripts/app.js"
    // , "scripts/analytics.js"
  ],
  "assets": [
    "assets"
  ],
  "port": 3999
}
```

## Commands

```bash
mdl init
mdl new my-mdl-site
mdl check
mdl check --json
mdl format
mdl format --check
mdl build
mdl serve
mdl init --app admin --port 4001
mdl serve apps/admin
```

`mdl init` initializes the current folder. `mdl new my-mdl-site` creates a new
folder and runs the same scaffold logic inside it. `mdl init --app <name>` adds
another app under `apps/<name>/` and keeps the same workspace environment.

Without `mdl.json`, pass a file directly:

```bash
mdl check pages/index.mdl
mdl build pages/index.mdl --style css/main.css
mdl serve pages/index.mdl
```

## Package Contents

This npm package exposes the `mdl` command and runs the prebuilt Rust binary
for your operating system and CPU. The small `bin/mdl.js` launcher selects the
correct binary at runtime.

The published public package contains:

```text
bin/mdl.js
scripts/postinstall.mjs
vendor/darwin-arm64/mdl
vendor/darwin-x64/mdl
vendor/linux-arm64/mdl
vendor/linux-x64/mdl
vendor/win32-x64/mdl.exe
README.md
LICENSE-APACHE
SHASUMS256.txt
```

`SHASUMS256.txt` lists the SHA-256 checksum for each published file. Release
builds stage the public package with `npm run pack:public` before publishing so
the checksum file matches the tarball contents.

## Security Notes

- The npm package has no runtime npm dependencies.
- The launcher does not download code at runtime. It selects one bundled binary
  from `vendor/<platform>/`.
- Local installs run `mdl init --quiet` as a `postinstall` convenience only when
  no MDL project is present. It creates starter files in the install directory.
- Set `MDL_SKIP_INIT=1` to disable automatic project initialization.
- Global installs skip automatic initialization; use `mdl new <name>` instead.
- `mdl check` validates local page routes, Markdown links, images, media,
  stylesheets, recursive CSS imports, font assets, and common accessibility/form
  issues before build.
- Report package, example, or security issues at
  <https://github.com/tosiiko/mdl-code/issues> or by email at
  `techityuganda@gmail.com`.

## Troubleshooting

If `mdl` is not found after a local install, activate the project shell:

```bash
source bin/activate
```

You can also run the local binary through npm:

```bash
npm exec -- mdl check
npm exec -- mdl serve
```

If the starter files were skipped or deleted, recreate them:

```bash
mdl init --force
```

## License

The package is published with the `MIT OR Apache-2.0` license expression and
includes the Apache License 2.0 text in `LICENSE-APACHE`.
