Install
$ agentstack add skill-soham407-studio-kickstart-email-campaigns ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Email Campaigns
Build modern, on-brand marketing emails and send them via Resend. This skill encodes a complete pattern: asset hosting, reusable HTML components, GIF tooling, and the Resend send pipeline.
1. Asset hosting — use your own site as a CDN
Setup once. In a Next.js or any static-hosted project, create a folder served at the site root:
/public/email-assets/
/
hero.png
demo.gif
Anything in public/ is served at https://yourdomain.com/email-assets/.... Commit + push = instant CDN. No Cloudinary, no S3.
Rules for email-safe assets:
- Naming: lowercase, dashes only (
hero-image.jpg✅,Hero Image.jpg❌) - Images: JPG/PNG, ≤ 1 MB, max 600px wide
- GIFs: ≤ 1.5 MB, max 720px wide, 12-15 fps, keep under 8 seconds
- Video: MP4 in same folder, but NEVER embed `` — always use GIF thumbnail linking to MP4
- Version filenames instead of overwriting (
hero-v2.jpg) — email clients cache aggressively
Before sending: swap all local paths to absolute URLs (https://yourdomain.com/email-assets/...). Relative paths work in browser preview but break in recipients' inboxes.
2. Design system — reusable blocks
Use this building-block inventory. Copy from a previous campaign, don't redesign from scratch.
Outer shell
[PREHEADER — 1 sentence, shown in inbox preview]
Key tokens:
- Card bg: light sky gradient + 6% SVG noise texture for depth (subtle grain). Gradient direction
90deg= left→right. - Card shadow: layered soft shadow, no border
- Card radius: 4px (tight corners feel modern)
Header image
Full-width image flush with card top. Crop the top 3/4 of a wide image (1376×576 cropped from 1376×768) for hero; use the bottom 1/3 (256px) as a footer image inside the card.
Logo cards (frost-glass)
Five logos distributed across full card width via width="20%" columns. Each card 72×72, light fill (#f4f4f7 gradient), soft shadow, 3px radius.
Hero title + body
...
...
Feature list with black bullets (not green checks)
Keep bullets black • in a 20px cell, text 15px. Avoid green check pills — they look dated.
Video block (frost-glass with blurred bg)
Pre-blur your brand hero image with ffmpeg to use as a colorful bed behind videos:
ffmpeg -y -i header.png -vf "boxblur=luma_radius=30:luma_power=3" header_blur.png
Then:
Video title
In Apple Mail/iOS: backdrop-filter renders real glass. In Gmail/Outlook: the pre-blurred image underneath sells the effect on its own.
CTA button
Black pill, 4px radius, 14px 24px padding, optional small logo inline:
Connect your accounts →
Place one CTA immediately after the first proof video (highest conversion moment) and one at the bottom.
Typography scale
- H1: 26px
- Body/features/video titles: 15px
- Section labels/footer: 13px
- CTA button: 14px
Stick to this. No more than 3 sizes.
3. GIF optimization workflow
For each screen recording:
# Convert MP4 → optimized GIF (720px, 15fps, 2x speed, trim to 8s)
ffmpeg -y -i source.mp4 -t 8 \
-vf "setpts=0.5*PTS,fps=15,scale=720:-1:flags=lanczos,split[s0][s1];\
[s0]palettegen=max_colors=256[p];\
[s1][p]paletteuse=dither=sierra2_4a" \
-loop 0 output.gif
# Check file size — should be under 1.5 MB
ls -lh output.gif
If too big:
- Drop to 12fps
- Reduce width to 600px
- Trim to 5-6 seconds
- Drop palette to 128 colors, use
dither=bayer:bayer_scale=5
If too low quality:
- Bump to 720-900px
- 256 colors with
sierra2_4adither - Accept 1.5-2 MB ceiling
4. Sending via Resend
Setup (once per project)
npm install resend
Env var: RESEND_API_KEY=re_... (get from resend.com dashboard)
From domain: verify your sending domain in Resend settings first (DNS records take ~15 min to propagate). Use hello@yourdomain.com, not a free provider.
Send a single test email
// send.mjs
import { Resend } from 'resend';
import fs from 'fs';
const resend = new Resend(process.env.RESEND_API_KEY);
const html = fs.readFileSync('./email.html', 'utf-8');
const { data, error } = await resend.emails.send({
from: 'Ira ',
to: 'you@example.com',
subject: 'Claude Connector for Google/Meta Ads is live',
html,
// Optional plain-text fallback
text: 'We released the Claude connector. Connect in 1 click: https://...',
});
console.log(error ?? data);
Run: node send.mjs. Always send to yourself first.
Send to a list (batches)
Resend rate-limits at 10 req/sec (free) or 100 req/sec (paid). For larger lists use their batch API:
await resend.batch.send(
recipients.map(email => ({
from: 'Ira ',
to: email,
subject: '...',
html,
}))
);
Up to 100 emails per batch call. Chunk your list accordingly.
Sequences / drip campaigns
For a 3-email sequence (day 0, day 3, day 7), use a cron + a sent-state table in Postgres/Supabase:
// Pseudo
const dueToday = await db.campaigns.findMany({
where: { scheduled_date: today, status: 'pending' }
});
for (const c of dueToday) {
await resend.emails.send({ ...c });
await db.campaigns.update({ where: { id: c.id }, data: { status: 'sent' } });
}
Resend has webhooks for email.delivered, email.opened, email.clicked — use them to trigger the next email in the sequence rather than fixed timers.
5. Pre-send checklist
Before you hit send on a real list:
- [ ] All asset URLs are absolute (
https://...), not relative (/email-assets/...) - [ ] Preheader text set (first hidden div) — this is the inbox preview line
- [ ] Subject line tested for deliverability (no ALL CAPS, no exclamation spam)
- [ ] Every image has meaningful
alttext - [ ] Every link has
target="_blank" - [ ] GIFs under 2 MB each, total email under 5 MB
- [ ] Tested in at least: Gmail web, Gmail mobile, Apple Mail, Outlook
- [ ] Unsubscribe link in footer (required by CAN-SPAM / GDPR)
- [ ] Sent one test to yourself — clicked every link
- [ ]
fromaddress is on a verified domain in Resend
6. Conversion best practices
- One primary CTA — repeated twice (mid-email + bottom). Don't dilute with secondary actions.
- Video first, text second — a 3-second GIF shows product faster than 3 paragraphs.
- Specificity wins — "Connect in 1 click" > "Get started". "30-second setup" > "Easy to install".
- Claim + proof — every claim near a visual (GIF, screenshot, or logo strip showing integrations).
- Low-friction reply CTA — "Reply 'Guide' and I'll send you X" is high-intent and cheap to fulfill.
- Send Tuesday-Thursday, 9-11am recipient-local. Avoid Monday (full inboxes) and weekends (low open).
7. Template starter
To bootstrap a new campaign, copy the most recent working HTML from your repo (e.g. public/email-assets/preview/claude-connector.html) and edit in place. Keep the preview file checked in alongside the campaign folder:
public/email-assets/2026-05-launch/
hero.png
demo.gif
preview.html
Preview locally at http://localhost:3000/email-assets/2026-05-launch/preview.html.
8. What NOT to do
- ❌ Don't use `` tags — blocked in Gmail/Outlook
- ❌ Don't use CSS grid or flexbox — broken in Outlook. Use nested ``s.
- ❌ Don't use web fonts — most clients strip them. Stick to system font stack.
- ❌ Don't use background images on the `` if you need them on mobile Gmail — it ignores body bg. Put color inside the main card.
- ❌ Don't embed MP4 directly — always GIF preview → link to external MP4.
- ❌ Don't send without testing — render one in Litmus/Mailtrap or just send to yourself on 3 clients.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Soham407
- Source: Soham407/studio-kickstart
- License: MIT
- Homepage: https://www.npmjs.com/package/@studio-skills/kickstart
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.