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

coffeehaml

v0.10.1

Published

Haml structure. CoffeeScript semantics. React runtime. Zero runtime. Vite-native.

Readme

☕ CoffeeHaml

Haml structure. CoffeeScript semantics. React runtime.

CoffeeHaml is a compiler that transforms an indentation-based, Haml-inspired authoring language into JavaScript using the modern React JSX runtime (react/jsx-runtime). It is not a UI framework. React remains the runtime. CoffeeHaml replaces JSX — with 50% fewer tokens.

%SimulatorPanel{source: "gyro", width: "auto", height: 500}
  - for servo in servos
    %ServoGraph{channel: servo.channel}
    %ServoPanel{servo: servo}

  %Button{onClick: save, disabled: !connected}
    Save

↓ compiles to ↓

import { jsxs, jsx, Fragment } from "react/jsx-runtime";

jsxs(SimulatorPanel, { source: "gyro", width: "auto", height: 500 },
  ...servos.map(servo => jsxs(Fragment, {},
    jsx(ServoGraph, { channel: servo.channel }),
    jsx(ServoPanel, { servo: servo })
  )),
  jsx(Button, { onClick: save, disabled: !connected }, "Save")
);

Why

| JSX | CoffeeHaml | |-----|------------| | <div className="box"><h1>Hello</h1><p>World</p></div> | %div.box%h1 Hello%p World | | Closing tags echo the opener verbatim | Indentation is structure | | 17 structural tokens | 8 structural tokens | | Angle brackets, braces, delimiters everywhere | Only semantic characters |

Every character carries weight. No syntactic ceremony — only meaning.

The Indentation Renaissance

Modern LLMs are increasingly trained on indentation-based languages — Python, YAML, Haml, Sass. Their tokenizers have internalized significant whitespace as structural signal. CoffeeHaml enters this cycle at precisely the right moment: the community is ready for a leap in expressiveness that removes boilerplate rather than adding another layer of abstraction.


Install

npm install coffeehaml

GitHub: dantiel/CoffeeHaml

CoffeeScript is an optional peer dependency — install it to compile CoffeeScript expressions in attributes and control flow:

npm install coffeescript

Without CoffeeScript, expressions pass through as-is (valid for most JS expressions like {onClick: handler} or {disabled: !connected}).


Usage

TextMate Bundle

A complete TextMate bundle ships with the repo at CoffeeHaml.tmbundle/. Install via symlink:

ln -sfn "$(pwd)/CoffeeHaml.tmbundle" \
  ~/"Library/Application Support/TextMate/Bundles/CoffeeHaml.tmbundle"

Includes syntax highlighting, Prettier formatting (⌃⌥F), compilation commands, snippets, and symbol navigation. See bundle README.

CLI

# Scaffold a new project (interactive wizard)
npx coffeehaml init

# One-shot compile
npx coffeehaml compile app.chaml -o app.js --wrap component

# Watch mode — recompiles on every change
npx coffeehaml watch src/ --wrap observer

| Flag | Description | |------|-------------| | init | Interactive project scaffold (Vite, dependency, samples) | | -o, --output | Write output to file | | --source-map | Emit inline source map | | --wrap <mode> | Wrap mode: component, observer, or comma-separated HOC list |

Accepts .coffeehaml, .cohaml, and .chaml extensions.

Vite plugin

// vite.config.ts
import coffeehaml from 'coffeehaml/vite';

export default {
  plugins: [coffeehaml()],
};

Now import .chaml files directly — they compile to React components with HMR.

Node API

import { compile, compileFile } from 'coffeehaml';

const result = compile('%div Hello', { filename: 'app.chaml' });
console.log(result.code);
// → import { jsx } from "react/jsx-runtime";
//   jsx("div", null, "Hello");

Syntax

| CoffeeHaml | Description | |------------|-------------| | %tag | HTML element (%div, %span, %button) | | %Component | React component (uppercase) | | .class | CSS class | | #id | Element ID | | {attr: val} / (attr: val) | Attributes (CoffeeScript expressions) | | {onClick} | Shorthand — onClick={onClick} | | = expression | Inline output (escaped); continuation via indented lines | | - if, - unless | Conditional | | - code | Arbitrary CoffeeScript statements; continuation via indented lines | | - for x in xs | Loop → .map() | | - else, - else if | Chain conditionals | | --- … --- | Fenced CoffeeScript block — render-time statements (multiline -) | | === … === | Fenced yield block — CoffeeScript whose final value renders (escaped) | | ~~~ … ~~~ | Fenced preamble block — module-scope code (imports, helpers, setup) | | -# comment | Haml comment (stripped) | | / comment | HTML comment | | .wrapper | Implicit div |

Full grammar: docs/grammar.md


Design Principles

  • Zero runtime — the compiler is the only artifact
  • Emitter-agnostic AST — future backends possible (Solid, Vue, Mithril)
  • Source-located errors — line/column hints for every compile failure
  • Source maps — debug in CoffeeHaml, not generated JS
  • Incremental compilation — Vite HMR out of the box
  • No invention — reuse Haml and CoffeeScript conventions

Status

v0.10.0 — production beta. The compiler pipeline (Lexer → Parser → Emitter) is complete. The Prettier plugin provides 16 deactivatable formatting options including attribute style preservation, statement merging, blank line handling, and CoffeeScript code formatting.

| Feature | Status | |---------|--------| | Elements, components, implicit divs | ✅ | | .class / #id modifiers | ✅ | | {attr: val} / (attr: val) + spread {props...} | ✅ | | attribute style preservation (braces/parens/bare) | ✅ | | Inline = expression output | ✅ | | = expression continuation (indented) | ✅ | | - statement continuation (indented) | ✅ | | - if / - unless / - else / - else if | ✅ | | - for item in items → .map() | ✅ | | - while | ✅ | | Statement merging (- blocks) | ✅ | | Haml/HTML comments | ✅ | | :filter blocks | ✅ | | Prologue passthrough (import, @decorator) | ✅ | | --- render-time CoffeeScript block | ✅ | | === yield block (fenced output) | ✅ | | ~~~ module-scope preamble block | ✅ | | Component / HOC wrapping (wrap: 'observer') | ✅ | | Vite plugin with HMR | ✅ | | CLI --wrap flag | ✅ | | CLI watch mode | ✅ | | CLI init scaffold | ✅ | | = expr -> arrow continuation | ✅ | | Source-located error messages | ✅ | | Multi-error parser recovery | ✅ | | Source maps | ✅ | | CoffeeScript expression compilation | ✅ (requires peer dep) | | React Fast Refresh annotations | ✅ | | Prettier formatter plugin (16 options) | ✅ | | TextMate bundle (commands, snippets, syntax) | ✅ |


License

MIT


Haml structure. CoffeeScript semantics. React runtime. Nothing more, nothing less.