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

@melker/melker

v2026.3.11

Published

*Run text with meaning*

Readme

Melker

Run text with meaning

Website: melker.sh

A TUI framework for apps you want to share safely.

Melker apps are documents you can read before you run them. Share via URL, declare permissions in a policy, inspect with Dev Tools.

Read the Manifesto for the philosophy behind this approach.

Read the FAQ for common questions.


Why Melker?

| Feature | Melker | Other TUI Frameworks | |------------------------------|:------:|:--------------------:| | Run from URL | Y | - | | Permission sandbox | Y | - | | App approval system | Y | - | | Inspect policy before run | Y | - | | Dev Tools (source, policy, inspect) | Y | - | | Literate UI (Markdown) | Y | - | | No build step | Y | Some |

See full comparison with Ink, Textual, Bubble Tea, Ratatui, and others.


Installation

Requirements

  • Deno 2.5+ or Node.js 25+ (experimental)
  • ANSI-compatible terminal
  • Nerd Fonts (recommended for graphics) - Melker uses sextant characters for canvas/image rendering. On macOS, install a Nerd Font and configure your terminal to use it. For terminals without Unicode support, use --gfx-mode=block (colored spaces), --gfx-mode=pattern (ASCII spatial), or --gfx-mode=luma (ASCII brightness).

Option 1: JSR (Deno)

deno install -g -A jsr:@melker/melker
melker app.melker

-A grants permissions to the launcher — apps run sandboxed with only the permissions they declare.

Option 2: Try Without Installing (Deno)

deno x jsr:@melker/melker app.melker

Option 3: Clone and Run (Deno)

git clone https://github.com/wistrand/melker.git
cd melker
./melker.ts examples/basics/hello.melker

Option 4: Global Install via Symlink (Deno)

# Clone to a permanent location
git clone https://github.com/wistrand/melker.git ~/melker

# Create symlink (ensure ~/.local/bin is in your PATH)
ln -s ~/melker/melker.ts ~/.local/bin/melker

# Run from anywhere
melker app.melker

The CLI is symlink-safe - it resolves its real path before importing dependencies.

Option 5: Node.js (Experimental)

Requires Node.js 25+. Apps run in a sandboxed subprocess with Node's --permission model. The binary is named melker-node.

npm install -g @melker/melker
melker-node app.melker

Releases

Melker uses CalVer (YYYY.MM.PATCH). List available releases:

git tag --list 'v*' | sort -V

Checkout a specific release:

git checkout v2026.03.1

Not Just Trust - Real UI

Melker apps look and feel like apps:

  • Flexbox layout, not just text dumps
  • CSS-like styling, 16M colors, theme auto-detection
  • Mouse and keyboard throughout
  • Tables with sorting and selection
  • Dialogs, menus, prompts

Showcase

A system monitor: View source

system monitor


Quick Start

Create hello.melker:

<melker>
  <policy>
  {
    "name": "Hello App",
    "permissions": {
      "env": ["TERM"]
    }
  }
  </policy>

  <container style="border: thin; padding: 1;">
    <text style="font-weight: bold; color: cyan;">Hello, Terminal!</text>
    <button label="Exit" onClick="$melker.exit()" />
  </container>
</melker>

Run it:

# Via the launcher
./melker.ts hello.melker

# Or via deno run
deno run --allow-all melker.ts hello.melker

# Or make the .melker file itself executable (add shebang as first line)
chmod +x hello.melker
./hello.melker

Why --allow-all? The launcher (melker.ts) needs full permissions to parse, bundle, and spawn your app. But your app runs in a subprocess with only the permissions declared in its <policy>. The launcher is trusted; the app is sandboxed.

Minimal launcher permissions: --allow-read --allow-write=/tmp --allow-env --allow-run

Before running, you can see:

  • The policy declares only env: TERM permission
  • The UI has one text element and one exit button
  • The handler calls $melker.exit(), nothing else

Press F12 to open Dev Tools to view source, policy, document tree, and system info.

For tutorials, see agent_docs/getting-started.md and the step-by-step tutorial.


Key Concepts

1. Document-First

Apps are documents, not opaque processes. A .melker file is readable markup with:

  • Declared permissions (<policy>)
  • Visible structure (HTML-like elements)
  • Inspectable handlers (onClick="...")

2. Explicit Policy

Permissions are document metadata, visible before execution:

<policy>
{
  "permissions": {
    "read": ["./data"],
    "write": ["./output"],
    "net": ["api.example.com"]
  }
}
</policy>

Run --show-policy to inspect without running:

./melker.ts --show-policy app.melker

3. Run from URL

Share apps via URL:

# Run directly from URL
./melker.ts https://example.com/app.melker

# Remote apps require explicit policy (enforced)
# First run prompts for approval (hash-based)

4. Three Abstraction Levels

Programmatic - TypeScript API:

const btn = createElement('button', { label: 'Click', onClick: () => count++ });

Declarative - .melker files:

<button label="Click" onClick="count++" />

Literate - .melker.md Markdown with embedded UI:

# My App

Documentation and UI in the same file:

<button label="Click" onClick="count++" />

5. Dev Tools

Press F12 to open Dev Tools:

  • View source, inspect policy, see system info
  • Inspect tab: Interactive element inspector with tree view, property/style editing, and live layout bounds
  • Config viewer, log viewer, actions panel

Features

Components

Core - no external dependencies:

| Category | Components | |-------------|---------------------------------------------------| | Layout | container, flexbox, tabs | | Text | text, markdown | | Input | input, textarea, checkbox, radio, slider | | Navigation | button, command-palette | | Data | table, data-table, list | | Dropdowns | combobox, select, autocomplete, command-palette | | Dialogs | dialog, alert, confirm, prompt | | Feedback | progress | | Files | file-browser |

Advanced - for specific needs:

| Component | Purpose | Requires | |---------------|--------------------------|-----------------------| | canvas | Pixel graphics, shaders | - | | img | Image display | - | | video | Media playback | FFmpeg | | oauth | Auth flows | net permission |

Layout

Flexbox with full support:

<container style="display: flex; flex-direction: row; gap: 2;">
  <text style="flex: 1;">Left</text>
  <text style="flex: 1;">Right</text>
</container>

Styling

CSS-like inline styles:

<container style="border: rounded; padding: 1; color: cyan; background-color: #222;">

Or <style> tags with selectors:

<style>
  button { background-color: blue; color: white; }
  #title { font-weight: bold; }
  .highlight { color: yellow; }
</style>

Themes

Auto-detects terminal capabilities by default. Manual override via CLI flag or env var:

./melker.ts --theme fullcolor-dark app.melker
# or
MELKER_THEME=fullcolor-dark ./melker.ts app.melker

Available: auto, bw-std, bw-dark, gray-std, gray-dark, color-std, color-dark, fullcolor-std, fullcolor-dark


Advanced Features

Canvas and Graphics

Pixel graphics using sextant characters (2x3 pixels per cell):

<canvas id="c" width="60" height="30" onPaint="draw(event.canvas)" />
function draw(canvas) {
  canvas.setPixel(x, y, 0xFF0000FF);  // RGBA packed
  canvas.line(0, 0, 59, 29, color);
  canvas.rect(10, 10, 20, 15, color);
}

Features: true color, auto-dither, retained mode with onPaint callback.

Video Playback

<video src="./video.mp4" width="80" height="24" autoplay="true" />

Uses FFmpeg for decoding, dithering for display.

Tables with Sorting and Selection

<table style="width: fill; height: 10;">
  <thead>
    <tr><th>Name</th><th>Role</th></tr>
  </thead>
  <tbody style="overflow: scroll" selectable="single">
    <tr data-id="1"><td>Alice</td><td>Admin</td></tr>
    <tr data-id="2"><td>Bob</td><td>User</td></tr>
  </tbody>
</table>

Click headers to sort. Arrow keys to navigate. Full keyboard and mouse support.

OAuth Built-in

<oauth
  wellknown="https://auth.example.com/.well-known/openid-configuration"
  clientId="my-app"
  scopes="openid profile"
  onToken="handleToken(event.token)"
/>

Handles browser redirect, token exchange, and secure storage.

State Persistence

MELKER_PERSIST=true deno run --allow-all melker.ts app.melker

Element state persists across runs using XDG state directory.


Running Apps

# Via the launcher
./melker.ts app.melker

# Or via deno run
deno run --allow-all melker.ts app.melker

# Or make the .melker file itself executable
# (add #!/usr/bin/env -S melker as first line, then chmod +x)
./app.melker

# Run from URL
./melker.ts https://example.com/app.melker

# Show policy without running
./melker.ts --show-policy app.melker

# Trust mode (for CI/scripts - bypasses approval prompt that would hang)
./melker.ts --trust app.melker

# Watch mode (auto-reload on changes)
./melker.ts --watch app.melker

# Enable server
./melker.ts --server-port 8080 app.melker

Deno Flags

These Deno flags are forwarded to the app subprocess:

./melker.ts --reload https://example.com/app.melker  # Reload remote modules
./melker.ts --no-lock app.melker                      # Disable lockfile
./melker.ts --no-check app.melker                     # Skip type checking
./melker.ts --quiet app.melker                        # Suppress diagnostic output
./melker.ts --cached-only app.melker                  # Offline mode

Running melker.ts from a remote URL: --reload before the URL is auto-detected and forwarded to the app subprocess — no need to pass it twice:

deno run --allow-all --reload https://melker.sh/melker.ts app.melker

TypeScript API

For programmatic use, import from mod.ts:

import { createElement, createApp } from './mod.ts';

const ui = createElement('container', {
  style: { border: 'thin', padding: 2 }
},
  createElement('text', { text: 'Hello!' }),
  createElement('button', { label: 'OK', onClick: () => app.exit() })
);

const app = await createApp(ui);

Or with template literals:

import { melker, createApp } from './mod.ts';

const ui = melker`
  <container style=${{ border: 'thin', padding: 2 }}>
    <text>Hello!</text>
    <button label="OK" onClick=${() => app.exit()} />
  </container>
`;

const app = await createApp(ui);

Note: melker.ts is the CLI entry point only. All library exports are in mod.ts.


Development

deno task check     # Type check
deno task test      # Run tests

Configuration

Configuration can be set via CLI flags (highest priority), environment variables, or config file (~/.config/melker/config.json). Priority order: default < policy < file < env < cli

# View current config with sources
./melker.ts --print-config

| Option | CLI Flag | Env Variable | Purpose | |----------------|------------------|--------------------------------|--------------------------------------------------| | Theme | --theme | MELKER_THEME | Theme selection (default: auto) | | Graphics mode | --gfx-mode | MELKER_GFX_MODE | sextant (default), block, pattern, luma | | Server port | --server-port | MELKER_SERVER_PORT | Enable server | | Headless | --headless | MELKER_HEADLESS | Headless mode for testing | | Alt screen | --no-alt-screen | MELKER_NO_ALTERNATE_SCREEN | Disable alternate screen buffer | | Persist | --persist | MELKER_PERSIST | Enable state persistence | | Log file | --log-file | MELKER_LOG_FILE | Log file path | | Log level | --log-level | MELKER_LOG_LEVEL | DEBUG, INFO, WARN, ERROR |

Project Structure

melker.ts              # CLI entry point (symlink-safe)
mod.ts                 # Library entry point (exports)
melker-launcher.ts     # Policy enforcement, subprocess spawning
src/
  melker-runner.ts     # .melker file runner
  engine.ts            # Application engine
  layout.ts            # Flexbox layout
  rendering.ts         # Render pipeline
  template.ts          # .melker file parsing
  policy/              # Permission system
  bundler/             # Runtime bundler
  components/          # UI components
  video/               # Video processing
  ai/                  # AI accessibility
examples/
  melker/              # .melker file examples
  ts/                  # TypeScript examples
docs/
  netlify/             # Netlify Edge Functions
    edge-functions/
      melker.ts        # Dynamic launcher (/melker.ts)

Examples

# Counter with state
./melker.ts examples/basics/counter.melker

# Markdown viewer (pass file as argument)
./melker.ts examples/showcase/markdown-viewer.melker README.md

# Dialog system
./melker.ts examples/basics/dialog-demo.melker

# Canvas animation
./melker.ts examples/canvas/analog-clock.melker

License

MIT License