> marko

You are an expert in Marko, the HTML-first UI framework by eBay that powers ebay.com. You help developers build high-performance web applications with streaming server rendering, automatic partial hydration, a concise tag-based syntax, and reactive state — optimized for fast first-paint and minimal client-side JavaScript through fine-grained reactivity and compiler optimizations.

fetch
$curl "https://skillshub.wtf/TerminalSkills/skills/marko?format=md"
SKILL.mdmarko

Marko — HTML-First UI Framework

You are an expert in Marko, the HTML-first UI framework by eBay that powers ebay.com. You help developers build high-performance web applications with streaming server rendering, automatic partial hydration, a concise tag-based syntax, and reactive state — optimized for fast first-paint and minimal client-side JavaScript through fine-grained reactivity and compiler optimizations.

Core Capabilities

Components

// components/product-card.marko — HTML-first syntax
<let/count=0/>

<div class="product-card">
  <img src=input.imageUrl alt=input.name />
  <h3>${input.name}</h3>
  <p class="price">$${input.price.toFixed(2)}</p>

  <div class="rating">
    <for|star| of=Array.from({length: 5})>
      <span class=(star < input.rating ? "filled" : "empty")>★</span>
    </for>
  </div>

  <div class="actions">
    <button onClick() { count++ }>
      Add to Cart ${count > 0 ? `(${count})` : ""}
    </button>
  </div>
</div>

style {
  .product-card {
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    padding: 16px;
    transition: box-shadow 0.2s;
  }
  .product-card:hover {
    box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  }
  .filled { color: #f59e0b; }
  .empty { color: #d1d5db; }
}

Streaming SSR

// pages/products.marko — Streaming server rendering
<let/products = fetch("/api/products").then(r => r.json()) />

<html>
<head>
  <title>Products</title>
</head>
<body>
  <h1>Our Products</h1>

  <!-- Streams immediately, fills in when data arrives -->
  <await|products| from=products>
    <@placeholder>
      <div class="skeleton-grid">
        <for|_| of=Array(8)>
          <div class="skeleton-card" />
        </for>
      </div>
    </@placeholder>

    <@then>
      <div class="product-grid">
        <for|product| of=products>
          <product-card
            name=product.name
            price=product.price
            imageUrl=product.image
            rating=product.rating
          />
        </for>
      </div>
    </@then>

    <@catch|error|>
      <div class="error">Failed to load products: ${error.message}</div>
    </@catch>
  </await>
</body>
</html>

Reactive State

// components/todo-list.marko
<let/todos=[]/>
<let/newTodo=""/>

<form onSubmit(e) {
  e.preventDefault();
  if (newTodo.trim()) {
    todos = [...todos, { id: Date.now(), text: newTodo, done: false }];
    newTodo = "";
  }
}>
  <input value=newTodo onInput(e) { newTodo = e.target.value }
    placeholder="Add a todo..." />
  <button type="submit">Add</button>
</form>

<ul>
  <for|todo, index| of=todos>
    <li class=(todo.done ? "done" : "")>
      <input type="checkbox" checked=todo.done
        onChange() {
          todos = todos.map((t, i) =>
            i === index ? { ...t, done: !t.done } : t
          );
        }
      />
      <span>${todo.text}</span>
    </li>
  </for>
</ul>

<p>${todos.filter(t => t.done).length}/${todos.length} completed</p>

Installation

npx @marko/create my-app
cd my-app && npm install
npm run dev                                # Dev server with hot reload

Best Practices

  1. HTML-first — Write HTML with embedded JS, not JS that returns HTML; natural template syntax
  2. Streaming SSR — Use <await> for async data; browser gets HTML progressively, no blank page
  3. Automatic partial hydration — Marko only sends JS for interactive components; static parts stay as HTML
  4. Fine-grained reactivity<let/> creates reactive state; only changed DOM nodes update
  5. Scoped styles — CSS in style {} is scoped to the component; no class name collisions
  6. Tags API — Components are custom tags; <product-card> auto-resolves from components/ directory
  7. eBay scale — Powers ebay.com serving billions of pages/day; battle-tested for performance
  8. Compiler optimized — Build step optimizes component boundaries, splits server/client code automatically

> related_skills --same-repo

> zustand

You are an expert in Zustand, the small, fast, and scalable state management library for React. You help developers manage global state without boilerplate using Zustand's hook-based stores, selectors for performance, middleware (persist, devtools, immer), computed values, and async actions — replacing Redux complexity with a simple, un-opinionated API in under 1KB.

> zoho

Integrate and automate Zoho products. Use when a user asks to work with Zoho CRM, Zoho Books, Zoho Desk, Zoho Projects, Zoho Mail, or Zoho Creator, build custom integrations via Zoho APIs, automate workflows with Deluge scripting, sync data between Zoho apps and external systems, manage leads and deals, automate invoicing, build custom Zoho Creator apps, set up webhooks, or manage Zoho organization settings. Covers Zoho CRM, Books, Desk, Projects, Creator, and cross-product integrations.

> zod

You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.

> zipkin

Deploy and configure Zipkin for distributed tracing and request flow visualization. Use when a user needs to set up trace collection, instrument Java/Spring or other services with Zipkin, analyze service dependencies, or configure storage backends for trace data.

┌ stats

installs/wk0
░░░░░░░░░░
github stars17
███░░░░░░░
first seenMar 17, 2026
└────────────

┌ repo

TerminalSkills/skills
by TerminalSkills
└────────────

┌ tags

└────────────