Back to blog
9 min read

Building a Terminal Header Generator with Cloudflare Workers

How I built a customizable terminal-style banner generator using Cloudflare Workers, SVG animations, and modern web technologies. Perfect for README files and project headers.

Cloudflare WorkersSVGWeb DevelopmentOpen Source

Introduction

As developers, we spend a lot of time creating README files for our projects. A visually appealing header can make your project stand out and create a memorable first impression. That's why I built Capsule Generator - a terminal-style header generator that creates beautiful, customizable SVG banners with animations.

Capsule Generator Interface

Try it live: capsule-generator.akszt.dev

The Problem

Most GitHub README headers are either:

  • Static images that require design tools and manual updates
  • Generic badges that lack personality
  • Complex setups requiring build tools and dependencies

I wanted something that was:

  • Dynamic - Generate headers on-the-fly via URL parameters
  • Beautiful - Modern terminal aesthetics with smooth animations
  • Fast - Instant generation with global edge delivery
  • Simple - Just paste a URL, no downloads or installations

Tech Stack

Cloudflare Workers

The entire application runs on Cloudflare's edge network, providing:

  • Global distribution - Under 50ms response time worldwide
  • Serverless architecture - No servers to manage
  • Zero cold starts - Always ready to serve
  • Free tier - 100,000 requests/day included

SVG + CSS Animations

I chose SVG for several reasons:

  • Scalable - Looks perfect at any size
  • Lightweight - Minimal file size (under 10KB)
  • Animated - Native CSS animation support
  • Embeddable - Works in Markdown, HTML, and web pages

Vanilla JavaScript

No frameworks needed! The UI uses:

  • Native Web APIs - Fetch, FormData, URLSearchParams
  • CSS Grid & Flexbox - Modern responsive layouts
  • Custom Properties - Easy theming
  • Real-time preview - Debounced updates

Key Features

1. Multiple Color Themes

I designed 5 distinct terminal-inspired themes:

const colorSchemes = {
  'modern-gradient': {
    primary: '#0d1421',    // Deep terminal black
    accent: '#00ff88',      // Classic green terminal
    wave: '#334155'         // Subtle wave overlay
  },
  'neon-blue': {
    primary: '#0a0e27',
    accent: '#00d9ff',      // Cyber blue glow
    wave: '#1e40af'
  },
  'cyberpunk': {
    primary: '#0c0c0c',
    accent: '#ff0080',      // Pink neon
    text: '#00ff41'         // Matrix green
  },
  // ... more themes
}

2. Smooth Wave Animations

The transparent wave effect creates depth without overwhelming the text:

const waveStartY = svgHeight * 0.7; // Waves start at 70% height
 
// Three layers of waves with different speeds
@keyframes wave1 {
  0%, 100% { /* Wave peak */ }
  50% { /* Wave trough */ }
}
 
.wave1 { animation: wave1 6s ease-in-out infinite; }
.wave2 { animation: wave2 4.5s ease-in-out infinite; }
.wave3 { animation: wave3 3s ease-in-out infinite; }

Each wave layer has:

  • Different frequencies - Creates natural motion
  • Gradient opacity - Fades from 15% to 0% transparency
  • Synchronized timing - Smooth continuous animation

3. Dynamic Text Effects

Multiple animation styles to match your project's vibe:

Wave Effect - Animated background waves

animation: 'wave'

Terminal Glow - Pulsing neon glow around text

@keyframes textGlow {
  0%, 100% { filter: drop-shadow(0 0 15px #00ff88); }
  50% { filter: drop-shadow(0 0 35px #00ff88); }
}

Typing Cursor - Simulates live terminal input

<rect class="cursor" /> // Blinking cursor

Float Effect - Text gently floats up and down

@keyframes float {
  0%, 100% { transform: translateY(0px); }
  50% { transform: translateY(-8px); }
}

4. Customizable Positioning

Full control over text placement with percentage-based positioning:

const titleX = url.searchParams.get('titleX') || '50'; // Center by default
const titleY = url.searchParams.get('titleY') || '35';
 
<g transform="translate(${titleX * 1200 / 100}, ${titleY * svgHeight / 100})">
  <text class="main-text">${name}</text>
</g>

5. Real-time Preview

The form updates the preview as you type using debounced API calls:

// Auto-update preview on input
const inputs = document.querySelectorAll('input, select');
inputs.forEach(input => {
  input.addEventListener('input', debounce(updatePreview, 300));
});
 
function debounce(func, wait) {
  let timeout;
  return function(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), wait);
  };
}

How It Works

Request Flow

  1. User visits capsule-generator.akszt.dev
  2. Worker serves HTML form (no name parameter)
  3. User customizes settings and clicks generate
  4. Form builds URL with all parameters:
    ?name=Akshat+Mehta
    &desc=Full+Stack+Developer
    &color=neon-blue
    &animation=wave
    &height=300
    &fontSize=80
    
  5. Worker generates SVG dynamically
  6. Preview updates in real-time
  7. Copy embed code to use anywhere

URL Parameters

All customization happens via query parameters:

ParameterTypeDefaultDescription
namestringrequiredMain title text
descstringoptionalSubtitle/description
colorstringmodern-gradientTheme name
animationstringwaveAnimation type
heightnumber300SVG height in pixels
fontSizenumber80Title font size
descFontSizenumber32Description font size
titleXnumber50Title X position (%)
titleYnumber35Title Y position (%)
descXnumber50Description X position (%)
descYnumber55Description Y position (%)

Example Usage

Basic Header:

![Header](https://capsule-generator.akszt.dev/?name=My+Project&desc=A+Cool+Tool)

Customized:

![Header](https://capsule-generator.akszt.dev/?name=Akshat+Mehta&desc=Full+Stack+Developer&color=neon-blue&animation=wave&height=300)

Result:

Example Terminal Header

Performance Optimizations

1. Edge Caching

SVGs are cached globally with smart cache control:

return new Response(svg, {
  headers: { 
    'Content-Type': 'image/svg+xml',
    'Cache-Control': 'public, max-age=3600' // 1 hour cache
  }
})

2. Minimal Dependencies

Zero external dependencies:

  • No npm packages
  • No build step
  • Pure JavaScript + SVG
  • ~15KB total size

3. Efficient SVG Generation

Template strings for fast concatenation:

function generateTerminalSVG(params) {
  return `<svg>...</svg>`; // Direct string return
}

Design Decisions

Why Cloudflare Workers?

Pros:

  • ✅ Global edge network (faster than traditional servers)
  • ✅ No cold starts (unlike AWS Lambda)
  • ✅ Simple deployment (wrangler deploy)
  • ✅ Generous free tier
  • ✅ Built-in CDN

Cons:

  • ❌ 10ms CPU time limit (not an issue for SVG generation)
  • ❌ No file system (not needed)

Why SVG Over Canvas?

SVG Advantages:

  • Scalable at any resolution
  • Native browser support
  • CSS animatable
  • Markdown compatible
  • Small file size
  • Accessible text

Canvas Limitations:

  • Raster output (pixelated when scaled)
  • Requires server-side rendering
  • Larger file sizes
  • No native animation

Why Vanilla JavaScript?

For this use case:

  • No state management needed
  • Simple DOM manipulation
  • Smaller bundle size
  • Faster load times
  • No framework lock-in

Challenges & Solutions

Challenge 1: Transparent Wave Overlay

Problem: Waves covering the text made it unreadable

Solution:

  • Used gradient opacity (15% → 0%)
  • Positioned waves at 70% height
  • Applied blur filters for smooth blending
<linearGradient id="waveGrad1">
  <stop offset="0%" stop-opacity="0.15"/>
  <stop offset="100%" stop-opacity="0"/>
</linearGradient>

Challenge 2: Font Rendering

Problem: Custom fonts don't load in SVG

Solution:

  • Used system monospace fonts with fallbacks
  • Specified font stack in SVG styles
  • Added font-weight for better rendering
font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', 'Consolas', monospace;

Challenge 3: Mobile Responsiveness

Problem: Fixed SVG dimensions didn't scale on mobile

Solution:

  • Made preview container responsive
  • Used viewBox for SVG scaling
  • Added max-width CSS
.preview-svg {
  max-width: 100%;
  height: auto;
}

Future Enhancements

Ideas for v2.0:

  1. Custom Fonts - Upload your own font files
  2. Image Backgrounds - Add logos or patterns
  3. Export to PNG - For platforms without SVG support
  4. Saved Presets - Save favorite configurations
  5. Batch Generation - Generate multiple headers
  6. API Endpoint - Programmatic access
  7. Analytics - Track popular themes and configs

Lessons Learned

1. Edge Computing is Powerful

Cloudflare Workers made deployment and scaling trivial. No servers, no DevOps, just deploy and forget.

2. SVG is Underrated

SVGs are perfect for dynamic graphics. The combination of XML structure and CSS styling is incredibly flexible.

3. URL Parameters > Config Files

For simple tools, URL parameters provide instant sharing and no database needed.

4. Real-time Preview Matters

Users expect immediate feedback. Debounced updates create a smooth experience without overwhelming the server.

5. Simplicity Wins

Vanilla JavaScript was the right choice. Sometimes the best framework is no framework.

Code Snippet: SVG Generation

Here's the core SVG generation logic:

function generateTerminalSVG(name, desc, colorScheme, fontSize, animation) {
  const scheme = colorSchemes[colorScheme] || colorSchemes['modern-gradient'];
  
  return `
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="300">
  <defs>
    <linearGradient id="bgGrad">
      <stop offset="0%" stop-color="${scheme.primary}"/>
      <stop offset="100%" stop-color="${scheme.secondary}"/>
    </linearGradient>
    
    <style>
      .main-text {
        font-family: 'JetBrains Mono', monospace;
        fill: url(#textGrad);
        ${animation === 'glow' ? 'animation: textGlow 3s infinite;' : ''}
      }
    </style>
  </defs>
  
  <rect width="1200" height="300" fill="url(#bgGrad)"/>
  
  <!-- Animated waves -->
  <path class="wave1" fill="url(#waveGrad1)"/>
  
  <!-- Text -->
  <text x="50%" y="35%" class="main-text" font-size="${fontSize}">
    ${name}
  </text>
  
  ${desc ? `<text x="50%" y="55%" class="desc-text">${desc}</text>` : ''}
</svg>`;
}

Try It Yourself

  1. Visit capsule-generator.akszt.dev
  2. Enter your name and description
  3. Choose a theme and animation
  4. Adjust positioning and sizing
  5. Copy the generated URL
  6. Paste in your README.md!

Open Source

The project is deployed on Cloudflare Workers and serves thousands of requests daily. Feel free to use it in your projects!

Live Demo: capsule-generator.akszt.dev

Conclusion

Building the Terminal Header Generator was a fun exercise in edge computing and SVG manipulation. It showcases how modern web technologies enable powerful tools with minimal complexity.

Key takeaways:

  • Edge computing reduces latency and simplifies deployment
  • SVG animations create engaging visuals with tiny file sizes
  • URL parameters enable instant sharing and configuration
  • Vanilla JavaScript is often all you need

Whether you're building a personal project or a production tool, sometimes the best solution is the simplest one.

Have you tried creating your own terminal header? What features would you add? Let me know in the comments!


Built with ☕ and deployed on Cloudflare Workers