Skip to main content
ClaudeWave
Skill259 repo starsupdated 2d ago

newsletter-publishing

This Claude Code skill provides structured workflows for journalists and researchers building and managing email newsletters, including content strategy frameworks, issue templates, and responsive HTML email designs. Activate it when creating newsletters from scratch, designing templates, segmenting subscriber lists, analyzing engagement metrics, planning editorial calendars, or optimizing deliverability and open rates for independent journalists, academic communicators, and media organizations.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/jamditis/claude-skills-journalism /tmp/newsletter-publishing && cp -r /tmp/newsletter-publishing/journalism-core/skills/newsletter-publishing ~/.claude/skills/newsletter-publishing
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Newsletter publishing

Practical workflows for building and managing email newsletters for journalism and academia.

## When to activate

- Creating a new newsletter from scratch
- Designing email templates for journalism content
- Building and segmenting subscriber lists
- Analyzing newsletter performance metrics
- Planning editorial calendars for newsletters
- Migrating between newsletter platforms
- Improving deliverability and open rates

## Newsletter architecture

### Content strategy framework

```markdown
## Newsletter strategy document

### Core identity
- **Name**:
- **Tagline** (one line):
- **What readers get**: [specific value proposition]
- **Frequency**: [ ] Daily [ ] Weekly [ ] Bi-weekly [ ] Monthly

### Target audience
- Primary reader:
- What they care about:
- Why they'll subscribe:
- What they'll do with this info:

### Content pillars
1. [Core topic 1] - [how often]
2. [Core topic 2] - [how often]
3. [Recurring feature] - [how often]

### Voice and tone
- Formal ↔ Conversational: [1-5]
- Serious ↔ Light: [1-5]
- Reported ↔ Personal: [1-5]

### Success metrics (first 6 months)
- Subscriber goal:
- Target open rate:
- Target click rate:
```

### Issue structure template

```markdown
## [Newsletter Name] - Issue #[XX]
**Date**: [Date]
**Subject line**: [Subject]
**Preview text**: [First 50-90 characters readers see]

---

### Opening hook
[2-3 sentences that make readers want to keep reading]

### Main story
[Your primary content - 300-600 words for most newsletters]

### Secondary items (if applicable)
- **Quick hit 1**: [Brief item with link]
- **Quick hit 2**: [Brief item with link]

### Recurring section
[Weekly column, data point, recommendation, etc.]

### Sign-off
[Personal note, call to action, or preview of next issue]

---

**Unsubscribe** | **Preferences** | **Forward to a friend**
```

## Technical implementation

### HTML email template (responsive)

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>{{newsletter_name}}</title>
  <style>
    /* Reset styles for email clients */
    body { margin: 0; padding: 0; width: 100%; }
    table { border-collapse: collapse; }
    img { border: 0; display: block; }

    /* Responsive container */
    .container {
      max-width: 600px;
      margin: 0 auto;
      font-family: Georgia, serif;
      font-size: 18px;
      line-height: 1.6;
      color: #333;
    }

    /* Dark mode support */
    @media (prefers-color-scheme: dark) {
      .container { background-color: #1a1a1a; color: #e0e0e0; }
      a { color: #6db3f2; }
    }

    /* Mobile styles */
    @media only screen and (max-width: 480px) {
      .container { padding: 15px !important; }
      h1 { font-size: 24px !important; }
    }
  </style>
</head>
<body>
  <table role="presentation" width="100%">
    <tr>
      <td align="center" style="padding: 20px;">
        <div class="container">
          <!-- Header -->
          <table width="100%">
            <tr>
              <td style="padding-bottom: 20px; border-bottom: 2px solid #333;">
                <h1 style="margin: 0;">{{newsletter_name}}</h1>
                <p style="margin: 5px 0 0; color: #666;">{{issue_date}}</p>
              </td>
            </tr>
          </table>

          <!-- Content -->
          <table width="100%">
            <tr>
              <td style="padding: 30px 0;">
                {{content}}
              </td>
            </tr>
          </table>

          <!-- Footer -->
          <table width="100%">
            <tr>
              <td style="padding-top: 20px; border-top: 1px solid #ddd; font-size: 14px; color: #666;">
                <p>You're receiving this because you subscribed to {{newsletter_name}}.</p>
                <p>
                  <a href="{{unsubscribe_url}}">Unsubscribe</a> |
                  <a href="{{preferences_url}}">Update preferences</a>
                </p>
              </td>
            </tr>
          </table>
        </div>
      </td>
    </tr>
  </table>
</body>
</html>
```

### Python newsletter sender

```python
from dataclasses import dataclass, field
from datetime import datetime
from typing import List, Dict, Optional
from enum import Enum
import hashlib

class SubscriberStatus(Enum):
    ACTIVE = "active"
    UNSUBSCRIBED = "unsubscribed"
    BOUNCED = "bounced"
    COMPLAINED = "complained"

@dataclass
class Subscriber:
    email: str
    name: Optional[str] = None
    subscribed_at: datetime = field(default_factory=datetime.now)
    status: SubscriberStatus = SubscriberStatus.ACTIVE
    tags: List[str] = field(default_factory=list)
    custom_fields: Dict = field(default_factory=dict)

    @property
    def hash_id(self) -> str:
        """Generate unique ID for unsubscribe links."""
        return hashlib.md5(self.email.encode()).hexdigest()[:12]

@dataclass
class NewsletterIssue:
    subject: str
    preview_text: str
    html_content: str
    plain_text: str
    scheduled_at: Optional[datetime] = None
    sent_at: Optional[datetime] = None
    issue_number: int = 0

    # Metrics
    sent_count: int = 0
    delivered_count: int = 0
    opened_count: int = 0
    clicked_count: int = 0
    bounced_count: int = 0
    unsubscribed_count: int = 0

    @property
    def open_rate(self) -> float:
        if self.delivered_count == 0:
            return 0.0
        return (self.opened_count / self.delivered_count) * 100

    @property
    def click_rate(self) -> float:
        if self.delivered_count == 0:
            return 0.0
        return (self.clicked_count / self.delivered_count) * 100

class NewsletterManager:
    """Core newsletter operations."""

    def __init__(self, name: str):
        self.name = name
        self.subscribers: List[Subscriber] = []
        self.issues: List[NewsletterIssue] = []

    def add_subscriber(self, email: str, name: str = None,
                       tags: List[str] = None) -> Subscriber
accessibility-complianceSkill

Web accessibility patterns for news sites, journalism tools, and academic platforms. Use when building accessible interfaces, auditing existing sites for WCAG compliance, writing alt text for news images, creating accessible data visualizations, or ensuring content reaches all readers including those using assistive technologies. Essential for newsroom developers and anyone publishing web content.

electron-devSkill

Electron desktop application development with React, TypeScript, and Vite. Use when building desktop apps, implementing IPC communication, managing windows/tray, handling PTY terminals, integrating WebRTC/audio, or packaging with electron-builder. Covers patterns from AudioBash, Yap, and Pisscord projects.

mobile-debuggingSkill

Remote JavaScript console access and debugging on mobile devices. Use when debugging web pages on phones/tablets, accessing console errors without desktop DevTools, testing responsive designs on real devices, or diagnosing mobile-specific issues. Covers Eruda, vConsole, Chrome/Safari remote debugging, and cloud testing platforms.

one-way-doorSkill

Use this skill when creating new files that represent architectural decisions — data models, infrastructure configs, auth boundaries, API contracts, CI/CD pipelines, or event systems. Flags irreversible decisions and forces a discussion about trade-offs before committing.

python-pipelineSkill

Python data processing pipelines with modular architecture. Use when building content processing workflows, implementing dispatcher patterns, integrating Google Sheets/Drive APIs, or creating batch processing systems. Covers patterns from rosen-scraper, image-analyzer, and social-scraper projects.

test-first-bugsSkill

This skill should be used when the user reports a bug, describes unexpected behavior, says something is "broken", "not working", "failing", mentions an "error", "issue", or "problem" in code, or asks to "fix" something. Enforces test-driven bug fixing workflow.

vibe-codingSkill

Methodology for effective AI-assisted software development. Use when helping users build software with AI coding assistants, debugging AI-generated code, planning features for AI implementation, managing version control in AI workflows, or when users mention "vibe coding," Claude Code, Cursor, GitHub Copilot, Aider, Continue, Cline, Codex, Windsurf, or similar AI coding tools. Provides strategies for planning, testing, debugging, and iterating on code written with LLM assistance.

web-scrapingSkill

Web scraping with anti-bot bypass, content extraction, undocumented APIs and poison pill detection. Use when extracting content from websites, handling paywalls, implementing scraping cascades or processing social media. Covers requests, trafilatura, Playwright with stealth mode, yt-dlp and instaloader patterns.