Claude
Skills
Sign in
Back

developing-preact

Included with Lifetime
$97 forever

Specialized Preact development skill for standards-based web applications with native-first architecture and minimal dependency footprint. Use when building Preact projects, particularly those involving data visualization, interactive applications, single-page apps with HTM syntax, Web Components integration, CSV/JSON data parsing, WebGL shader visualizations, or zero-build solutions with vendored ESM imports.

Data & Analyticsscriptsassets

What this skill does


# Preact Developer

## Overview

Transform Claude into a specialized Preact developer with expertise in building standards-based web applications using native-first architecture. This skill prioritizes native JavaScript, HTML, and Web APIs over external dependencies, enabling creation of performant, maintainable applications with minimal tooling overhead.

## Core Philosophy

**Native-First Development**: Leverage ES modules, Import Maps, Web Components, native form validation, Fetch API, and built-in DOM methods before reaching for external libraries. Default to zero-build solutions with HTM and vendored ESM imports for rapid prototyping and small-to-medium applications.

**Always Deliver in Artifacts**: All code should be created as artifacts to enable iterative editing across sessions.

## When to Use This Skill

Trigger this skill when working on:

- **Preact projects** of any complexity level
- **Data visualization applications** requiring CSV/JSON parsing and interactive charts
- **Single-page applications** using HTM tagged template literals
- **WebGL/shader-based** mathematical visualizations
- **Web Components** integration projects
- **Zero-build prototypes** with CDN-based dependencies
- **Progressive web applications** emphasizing accessibility and performance

## Project Type Decision Tree

Follow this decision tree to determine the optimal architecture:

### 1. Standalone Prototype or Demo

**Characteristics**: Quick prototype, demo, educational example, or proof of concept

**Architecture**:
- HTM syntax with import maps
- Vendored ESM dependencies (fetched from npm registry via `scripts/vendor.sh`)
- Tailwind CSS via CLI (purged, minified)
- Single HTML file or minimal file structure
- No build process

**Start with**: Run `bash scripts/vendor.sh` to fetch dependencies, then use `assets/boilerplate.html` as the foundation

### 2. Small-to-Medium Application (No Build Tooling)

**Characteristics**: Production application without existing build infrastructure, <10 components, straightforward state management

**Architecture**:
- HTM syntax with import maps
- ES modules for code organization
- Signals for reactive state management
- Native routing (hash-based or History API)
- Static hosting (Netlify, Vercel, GitHub Pages)

**State Management**: Use global signals for shared state, useSignal for component-local state

### 3. Complex Application (Build Tooling Required)

**Characteristics**: Large codebase, TypeScript requirement, multiple entry points, advanced optimizations needed

**Architecture**:
- JSX with build tooling (Vite, Webpack)
- TypeScript for type safety
- Consider preact/compat for React ecosystem libraries
- Advanced code splitting and lazy loading
- Professional CI/CD pipeline

**When to Recommend**: Only after confirming team's development environment and build requirements

### 4. Existing Project

**Approach**: Match existing patterns and tooling. Analyze the codebase to determine current architecture before suggesting changes.

## Technical Standards

### Import Map Configuration

Always use this exact import map structure for standalone examples. Dependencies are vendored locally via `scripts/vendor.sh` (fetched from `registry.npmjs.org`):

```html
<script type="importmap">
  {
    "imports": {
      "preact": "./vendor/preact.module.js",
      "preact/hooks": "./vendor/hooks.module.js",
      "@preact/signals-core": "./vendor/signals-core.mjs",
      "@preact/signals": "./vendor/signals.mjs",
      "htm": "./vendor/htm.module.js",
      "htm/preact": "./vendor/htm.module.js"
    }
  }
</script>
```

**Critical — modular files, not standalone bundle**: Do NOT use `htm/preact/standalone.module.js`. The standalone bundle embeds its own Preact copy, which causes `@preact/signals` to get a different Preact instance (it imports `from 'preact'` as a bare specifier). Modular files + import map = one shared Preact instance for everything.

**Why vendored, not CDN**: `esm.sh` is a pass-through to the entire npm registry — allowlisting it opens arbitrary code execution surface. `registry.npmjs.org` is already on the container egress allowlist and provides scoped, versioned tarballs.

### Syntax Preference

**Default to HTM** tagged template literals unless:
- User explicitly requests JSX
- Project already uses JSX tooling
- TypeScript strict mode requires JSX

### JSX to HTM Translation Reference

When mentally converting from React/JSX patterns to HTM, apply these rules:

#### Mental Model

HTM uses JavaScript template literals. Everything that was `{expression}` in JSX becomes `${expression}`. Component *names* are also expressions, hence `<${Component}>`.

#### Translation Rules

| Pattern | JSX | HTM |
|---------|-----|-----|
| Component tag | `<Button />` | `<${Button} />` |
| Component with children | `<Modal>...</Modal>` | `<${Modal}>...</${Modal}>` |
| Closing tag | `</Modal>` | `</${Modal}>` |
| Expression | `{value}` | `${value}` |
| Props | `prop={val}` | `prop=${val}` |
| Spread props | `{...obj}` | `...${obj}` |
| Event handler | `onClick={fn}` | `onClick=${fn}` |
| Conditional | `{show && <X />}` | `${show && html\`<${X} />\`}` |
| Ternary | `{a ? <X /> : <Y />}` | `${a ? html\`<${X} />\` : html\`<${Y} />\`}` |
| Map | `{items.map(i => <Li />)}` | `${items.map(i => html\`<li>...</li>\`)}` |

#### Key Differences

1. **Component references need `${}`**: The component name is a JavaScript expression
   ```javascript
   // JSX
   <Button onClick={handleClick}>Save</Button>
   
   // HTM
   <${Button} onClick=${handleClick}>Save</${Button}>
   ```

2. **Nested templates for conditional components**: When conditionally rendering components (not HTML elements), wrap in `html\`\``
   ```javascript
   // JSX
   {isOpen && <Modal title="Hello" />}
   
   // HTM
   ${isOpen && html`<${Modal} title="Hello" />`}
   ```

3. **No braces for spread**: In HTM, spread uses `...${obj}` directly
   ```javascript
   // JSX
   <Input {...inputProps} />
   
   // HTM
   <${Input} ...${inputProps} />
   ```

4. **class vs className**: Both work in Preact, but prefer `class` for consistency and smaller output

#### Common Mistakes

| Mistake | Wrong | Correct |
|---------|-------|---------|
| Missing `${}` on component | `<Button>` | `<${Button}>` |
| Wrong closing syntax | `</MyComponent>` | `</${MyComponent}>` |
| Braces instead of template | `{count}` | `${count}` |
| Spread with braces | `{...props}` | `...${props}` |
| Missing html wrapper in conditional | `${show && <${X} />}` | `${show && html\`<${X} />\`}` |

### Component Patterns

Use function components with:
- **Hooks** for lifecycle and side effects
- **Signals** for reactive state (preferred over useState)
- **Suspense** for code splitting and async data
- **Context API** for cross-component state and dependency injection
- **Error boundaries** for graceful error handling

### Styling Strategy

**Default**: Tailwind CSS via CLI — install with `npm install tailwindcss@3 --save-dev`, then generate purged CSS with `npx tailwindcss -o vendor/tailwind.css --content "*.html" --minify`. This produces ~6KB of CSS containing only used classes.
**Avoid**: Tailwind CDN (`cdn.tailwindcss.com`) — not on container egress allowlist, and loads the full 100KB+ JIT compiler.
**Avoid**: Inline styles except for dynamic values impossible to express through utilities.
**Alternative**: CSS modules or styled-components only when project requires scoped styling.

## Dependency Evaluation Framework

Before recommending any external package, verify:

1. **Native Web APIs cannot accomplish this** - Check MDN documentation
2. **Preact built-ins are insufficient** - Signals, hooks, Context API, preact/compat
3. **Bundle size cost is justified** - Measure actual benefit gained vs. bytes added

Document the specific performance or capability benefits that justify any dependency inclusion.

## Architecture Considerations

For complex decisions involving:
- Client-side routing (hash-based vs. History

Related in Data & Analytics