---
title: "How to add a lightning with Claude (tested prompt and script)"
description: "The picture darkens to a stormy blue, then a jagged white bolt with an electric blue glow forks down the right side of the frame, dims for a beat and strikes again as the whole scene flashes. Install one skill and ask Claude Code, or run the Python script we tested yourself."
url: https://www.recharm.com/effects/lightning
---

# How to add a lightning with Claude

The picture darkens to a stormy blue, then a jagged white bolt with an electric blue glow forks down the right side of the frame, dims for a beat and strikes again as the whole scene flashes.

Made by the script on this page, from our own test clip.

## Get this effect

1. ### Switch to Code in your [Claude Desktop App](https://claude.com/download)

2. ### Install the skill (once)

   ```
   Install the Recharm video effects skill: download https://recharm-growth-staging.s3.us-east-2.amazonaws.com/website/downloads/recharm-video-effects.zip and unzip it into ~/.claude/skills
   ```

3. ### Ask for the effect

   ```
   Add a lightning to input.mp4
   Second the bolt strikes: 1.0
   How dark the storm gets before the strike (0 = not at all, 1 = black): 0.55
   ```

## Several videos, several effects, one ask

Put your clips in the folder, mention them with @, and ask for everything at once. Claude runs one tested script after another on each clip, then joins them.

Add a lightning to **@clip1.mp4**, put a sale badge on **@clip2.mp4**, give **@clip3.mp4** a VHS look, then join all three with crossfades.

## Settings you can change

Ask Claude to change any of these, or edit them at the top of the script.

| Setting        | Default                     | What it does                                                                  |
| -------------- | --------------------------- | ----------------------------------------------------------------------------- |
| `AT`           | `1.0`                       | Second the bolt strikes.                                                      |
| `DIM`          | `0.55`                      | How dark the storm gets before the strike (0 = not at all, 1 = black).        |
| `TOP, BOTTOM`  | `(0.66, 0.0), (0.86, 0.66)` | Where the bolt enters and where it ends, as shares across and down the frame. |
| `BRANCHES`     | `4`                         | Side forks off the main bolt.                                                 |
| `ROUGH`        | `0.16`                      | How jagged the bolt is. 0 is a straight line.                                 |
| `GLOW`         | `(110, 150, 255)`           | Color of the glow round the white core.                                       |
| `FLASH_AMOUNT` | `0.35`                      | How much the whole frame lights up while the bolt is on.                      |
| `SEED`         | `2`                         | Change it for a different bolt shape.                                         |

## Without the skill

Don’t want to install the skill? Paste this prompt into Claude Code and Claude writes the script itself.

```
Add a lightning strike to input.mp4. From 0.5s to 1.0s, darken the picture linearly toward dark blue (15, 20, 45), ending at 55% of the way there. At 1.0s a lightning bolt strikes: a jagged line (midpoint displacement, each midpoint pushed sideways by up to 16% of its segment's length, down to 12-pixel segments) from 66% across at the top edge to 86% across and 66% down, with 4 thinner jagged forks 12-25% of the frame height long branching off it downward. Draw it with Pillow as a 6px pure white (255, 255, 255) core (3px for the forks) over an electric blue (110, 150, 255) glow made by blurring 5x-wider copies of the lines (Gaussian blur radius 6 and 28). The strike's strength is 100% from 1.00s to 1.08s, 15% from 1.08s to 1.14s, 100% again from 1.14s to 1.26s, then fades linearly to 0 by 1.66s; the bolt's opacity follows it, and the whole frame also lightens toward pale blue (200, 215, 255) by 35% times the strength. After 1.66s the darkening lifts linearly back to the untouched picture by 2.46s. Before 0.5s and after 2.46s the video must be unchanged. Use Python with numpy and Pillow for the frames and ffmpeg to read and write them (no drawtext), keep the size, 30fps, length and audio, and save it as output.mp4.
```

## Run it without Claude

This is the exact script we tested. Save it as `lightning.py` and run:

```
python3 lightning.py input.mp4 output.mp4
```

```
#!/usr/bin/env python3
"""Lightning: the picture darkens to a stormy blue, then a jagged white bolt forks down from the top, flickers and flashes.

Usage: python3 lightning.py input.mp4 output.mp4
Needs ffmpeg, numpy and Pillow (pip install numpy pillow).
"""
import json
import subprocess
import sys

import numpy as np
from PIL import Image, ImageDraw, ImageFilter

AT = 1.0                    # second the bolt strikes
DIM_IN = 0.5                # seconds the picture takes to darken before the strike
DIM = 0.55                  # how dark the storm gets (0 = not at all, 1 = black)
FADE = 0.4                  # seconds the bolt takes to die away after the second flicker
CLEAR = 0.8                 # seconds the storm takes to lift after the bolt has gone
TOP = (0.66, 0.0)           # where the bolt enters (0-1 across and down the frame)
BOTTOM = (0.86, 0.66)       # where the main bolt ends
BRANCHES = 4                # side forks off the main bolt
ROUGH = 0.16                # how jagged the bolt is (0 = straight line)
STORM = (15, 20, 45)        # the dark blue the picture is pulled toward
GLOW = (110, 150, 255)      # electric blue glow round the white core
FLASH = (200, 215, 255)     # pale blue the whole frame lights toward at the strike
FLASH_AMOUNT = 0.35         # how far it lights up (0-1)
SEED = 2                    # change for a different bolt shape

def probe(path):
    info = json.loads(subprocess.check_output(["ffprobe", "-v", "error", "-select_streams", "v:0", "-show_entries",
                                               "stream=width,height,r_frame_rate", "-of", "json", path]))
    s = info["streams"][0]
    num, den = s["r_frame_rate"].split("/")
    return s["width"], s["height"], s["r_frame_rate"], float(num) / float(den)

def jagged(a, b, rough):
    """Points of a jagged line from a to b: split each segment at its midpoint and push that point sideways."""
    length = np.hypot(b[0] - a[0], b[1] - a[1])
    if length < 12:
        return [a, b]
    nx, ny = (a[1] - b[1]) / length, (b[0] - a[0]) / length  # unit vector across the segment
    push = rng.uniform(-rough, rough) * length
    mid = ((a[0] + b[0]) / 2 + nx * push, (a[1] + b[1]) / 2 + ny * push)
    return jagged(a, mid, rough)[:-1] + jagged(mid, b, rough)

def bolt():
    """The bolt as two masks (0-1): the thin white core and the soft glow around it."""
    main = jagged((TOP[0] * w, TOP[1] * h), (BOTTOM[0] * w, BOTTOM[1] * h), ROUGH)
    forks = []
    for _ in range(BRANCHES):
        x, y = main[rng.integers(len(main) // 5, len(main) * 3 // 4)]
        angle = rng.uniform(0.3, 1.1) * rng.choice([-1, 1])  # radians off straight down
        reach = rng.uniform(0.12, 0.25) * h
        forks.append(jagged((x, y), (x + reach * np.sin(angle), y + reach * np.cos(angle)), ROUGH))
    core, halo = Image.new("L", (w, h)), Image.new("L", (w, h))
    for line, width in [(main, 6)] + [(f, 3) for f in forks]:
        ImageDraw.Draw(core).line(line, fill=255, width=width, joint="curve")
        ImageDraw.Draw(halo).line(line, fill=255, width=width * 5, joint="curve")
    halo = np.maximum(np.asarray(halo.filter(ImageFilter.GaussianBlur(6)), np.float32) * 0.8,
                      np.asarray(halo.filter(ImageFilter.GaussianBlur(28)), np.float32) * 1.5)
    return np.asarray(core, np.float32)[..., None] / 255, np.clip(halo / 255, 0, 0.85)[..., None]

def strength(t):
    """How bright the strike is at time t (0-1): on, a quick dip, on again, then fading out."""
    dt = t - AT
    if dt < 0:
        return 0.0
    if dt < 0.08:
        return 1.0
    if dt < 0.14:
        return 0.15
    if dt < 0.26:
        return 1.0
    return max(0.0, 1 - (dt - 0.26) / FADE)

def darkness(t):
    """How far the storm has darkened the picture at time t (0-1)."""
    if t < AT:
        return float(np.clip((t - (AT - DIM_IN)) / DIM_IN, 0, 1))
    return float(np.clip(1 - (t - AT - 0.26 - FADE) / CLEAR, 0, 1))

src, out = sys.argv[1:3]
w, h, rate, fps = probe(src)
rng = np.random.default_rng(SEED)
core, halo = bolt()
storm, glow, flash = (np.array(c, np.float32) for c in (STORM, GLOW, FLASH))

reader = subprocess.Popen(["ffmpeg", "-v", "error", "-i", src, "-f", "rawvideo", "-pix_fmt", "rgb24", "-"],
                          stdout=subprocess.PIPE)
writer = subprocess.Popen(["ffmpeg", "-y", "-v", "error", "-f", "rawvideo", "-pix_fmt", "rgb24", "-s", f"{w}x{h}",
                           "-r", rate, "-i", "-", "-i", src, "-map", "0:v", "-map", "1:a?",
                           "-c:v", "libx264", "-crf", "18", "-pix_fmt", "yuv420p", "-c:a", "copy", "-shortest", out],
                          stdin=subprocess.PIPE)
i = 0
while raw := reader.stdout.read(w * h * 3):
    img = np.frombuffer(raw, np.uint8).reshape(h, w, 3)
    d, s = darkness(i / fps) * DIM, strength(i / fps)
    if d > 0:
        frame = img * (1 - d) + storm * d                              # stormy darkening
        frame += (flash - frame) * FLASH_AMOUNT * s                    # the whole sky lights up
        frame = frame * (1 - halo * s) + glow * halo * s               # blue glow round the bolt
        frame = frame * (1 - core * s) + 255 * core * s                # white-hot core on top
        img = np.clip(frame, 0, 255).astype(np.uint8)
    writer.stdin.write(img.tobytes())
    i += 1
writer.stdin.close()
if reader.wait() or writer.wait():
    sys.exit("ffmpeg failed")
```

## More overlays and light

- [Anamorphic streak **Anamorphic streak**](https://www.recharm.com/effects/anamorphic-streak)
- [Aurora **Aurora**](https://www.recharm.com/effects/aurora)
- [Blood splatter **Blood splatter**](https://www.recharm.com/effects/blood-splatter)
- [Bokeh lights **Bokeh lights**](https://www.recharm.com/effects/bokeh-lights)
- [Camera flash **Camera flash**](https://www.recharm.com/effects/camera-flash)

## Find 3x _winning ads_

Recharm cuts your ad footage into tagged, searchable clips: hooks, testimonials, product shots. Find the shots that win, add the effect with Claude, and ship 3x more ad edits.

[Start 14-day free trial](https://www.recharm.com/get-started)
