> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bfl.ml/llms.txt
> Use this file to discover all available pages before exploring further.

# Cookbook

> Runnable FLUX recipes, with the output they produced.

export const RecipeList = ({items = []}) => <div className="not-prose cookbook-list" style={{
  margin: "0.75rem 0 2.5rem"
}}>
    {items.map((item, i) => <a key={i} href={item.href} target={item.external ? "_blank" : undefined} rel={item.external ? "noreferrer" : undefined} className="cookbook-list__row" style={{
  display: "flex",
  alignItems: "center",
  justifyContent: "space-between",
  gap: "1.25rem",
  padding: "0.85rem 0.6rem",
  textDecoration: "none",
  color: "inherit",
  borderRadius: "0.45rem"
}}>
        <span className="cookbook-list__title" style={{
  fontSize: "0.92rem",
  fontWeight: 500,
  lineHeight: 1.4,
  display: "inline-flex",
  alignItems: "center",
  gap: "0.4rem",
  minWidth: 0
}}>
          {item.title}
          {item.external && <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" style={{
  opacity: 0.5,
  flexShrink: 0
}}>
              <path d="M7 17 17 7" /><path d="M7 7h10v10" />
            </svg>}
        </span>
        {item.tags && item.tags.length > 0 && <span className="cookbook-tags" style={{
  display: "flex",
  gap: "0.8rem",
  fontSize: "0.74rem",
  fontWeight: 550,
  whiteSpace: "nowrap",
  flexShrink: 0
}}>
            {item.tags.map((t, j) => <span key={j}>{t}</span>)}
          </span>}
      </a>)}
  </div>;

export const FeaturedCards = ({items = []}) => <div className="not-prose cookbook-featured" style={{
  display: "grid",
  gridTemplateColumns: "repeat(auto-fit, minmax(min(100%, 15rem), 1fr))",
  gap: "1.6rem 1.25rem",
  margin: "1.25rem 0 2.5rem"
}}>
    {items.map((item, i) => <a key={i} href={item.href} className="cookbook-featured__card" style={{
  display: "flex",
  flexDirection: "column",
  gap: "0.7rem",
  textDecoration: "none",
  color: "inherit"
}}>
        <span style={{
  display: "block",
  position: "relative",
  aspectRatio: "2.05 / 1",
  borderRadius: "0.7rem",
  overflow: "hidden",
  border: "1px solid rgba(72,106,88,0.18)",
  background: "#0c1512"
}}>
          <img src={item.img} alt={item.title} loading="lazy" className="cookbook-featured__img" style={{
  display: "block",
  width: "100%",
  height: "100%",
  objectFit: "cover",
  transition: "transform 300ms ease"
}} />
        </span>
        <span className="cookbook-featured__title" style={{
  fontFamily: '"Instrument Sans", sans-serif',
  fontSize: "1rem",
  fontWeight: 600,
  letterSpacing: "-0.015em",
  lineHeight: 1.35
}}>
          {item.title}
        </span>
        {item.tags && item.tags.length > 0 && <span className="cookbook-tags" style={{
  display: "flex",
  flexWrap: "wrap",
  gap: "0.35rem 0.8rem",
  fontSize: "0.76rem",
  fontWeight: 550
}}>
            {item.tags.map((t, j) => <span key={j}>{t}</span>)}
          </span>}
      </a>)}
  </div>;

export const CookbookHero = ({eyebrow, title, lede, meta = [], clip}) => {
  const [playing, setPlaying] = useState(false);
  return <div className="not-prose cookbook-hero" style={{
    display: "grid",
    gridTemplateColumns: "repeat(auto-fit, minmax(min(100%, 22rem), 1fr))",
    gap: "2.2rem",
    alignItems: "center",
    margin: "0.5rem 0 2.8rem"
  }}>
      <div style={{
    display: "flex",
    flexDirection: "column",
    gap: "1rem"
  }}>
        {eyebrow && <span className="cookbook-hero__eyebrow" style={{
    fontSize: "0.78rem",
    fontWeight: 700,
    letterSpacing: "0.14em",
    textTransform: "uppercase",
    color: "var(--aspen-evergreen, #486a58)"
  }}>
            {eyebrow}
          </span>}
        <span role="heading" aria-level={1} className="cookbook-hero__title" style={{
    fontFamily: '"Instrument Sans", sans-serif',
    fontSize: "clamp(1.9rem, 3.4vw, 2.7rem)",
    fontWeight: 550,
    letterSpacing: "-0.035em",
    lineHeight: 1.08
  }}>
          {title}
        </span>
        <p className="cookbook-hero__lede" style={{
    margin: 0,
    fontSize: "1.02rem",
    lineHeight: 1.65
  }}>
          {lede}
        </p>
        {meta.length > 0 && <p className="cookbook-hero__meta" style={{
    margin: "0.2rem 0 0",
    fontSize: "0.84rem",
    fontWeight: 500
  }}>
            {meta.map((m, i) => <span key={i}>
                {i > 0 && <span aria-hidden="true" style={{
    display: "inline-block",
    width: "1px",
    height: "0.8em",
    margin: "0 0.65rem -0.08em",
    background: "rgba(72,106,88,0.4)"
  }} />}
                {m}
              </span>)}
          </p>}
      </div>

      {clip && <figure style={{
    margin: 0
  }}>
          <div style={{
    position: "relative",
    borderRadius: "1.1rem",
    overflow: "hidden",
    border: "1px solid rgba(72,106,88,0.22)",
    background: "#0c1512",
    boxShadow: "0 24px 60px -30px rgba(22,49,38,0.45)"
  }}>
            {playing ? <video src={clip.src} poster={clip.poster} controls autoPlay playsInline style={{
    display: "block",
    width: "100%",
    aspectRatio: clip.aspectRatio || "16 / 9",
    objectFit: "cover"
  }} /> : <button type="button" onClick={() => setPlaying(true)} aria-label={`Play: ${clip.label || "showcase clip"} (with sound)`} style={{
    display: "block",
    width: "100%",
    padding: 0,
    border: "none",
    background: "none",
    cursor: "pointer",
    position: "relative"
  }}>
                <img src={clip.poster} alt={clip.label || "Generated clip poster"} style={{
    display: "block",
    width: "100%",
    aspectRatio: clip.aspectRatio || "16 / 9",
    objectFit: "cover"
  }} />
                <span aria-hidden="true" style={{
    position: "absolute",
    inset: 0,
    background: "linear-gradient(180deg, rgba(8,17,13,0) 45%, rgba(8,17,13,0.72) 100%)"
  }} />
                <span aria-hidden="true" style={{
    position: "absolute",
    top: "50%",
    left: "50%",
    transform: "translate(-50%, -50%)",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    width: "3.6rem",
    height: "3.6rem",
    borderRadius: "50%",
    background: "rgba(246,241,231,0.92)",
    color: "#163126",
    boxShadow: "0 10px 30px -8px rgba(0,0,0,0.5)"
  }}>
                  <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" style={{
    marginLeft: "3px"
  }}>
                    <polygon points="6 3 21 12 6 21" />
                  </svg>
                </span>
                {clip.label && <span style={{
    position: "absolute",
    left: "1rem",
    right: "1rem",
    bottom: "0.9rem",
    display: "flex",
    alignItems: "baseline",
    justifyContent: "space-between",
    gap: "1rem",
    color: "rgba(246,241,231,0.95)",
    fontSize: "0.88rem",
    fontWeight: 600,
    textAlign: "left"
  }}>
                    {clip.label}
                    <span style={{
    fontSize: "0.74rem",
    fontWeight: 700,
    letterSpacing: "0.08em",
    textTransform: "uppercase",
    color: "rgba(246,241,231,0.75)",
    whiteSpace: "nowrap"
  }}>
                      Sound on
                    </span>
                  </span>}
              </button>}
          </div>
          {clip.note && <figcaption className="recipe-clip__caption" style={{
    marginTop: "0.6rem"
  }}>
              {clip.note}
            </figcaption>}
        </figure>}
    </div>;
};

<div className="cookbook-index" />

<CookbookHero
  title="From a first clip to a finished film"
  lede="FLUX recipes, from API calls to open weights. Each page is the notebook that ran: the code as written and the output it returned. Read it here or run it from the repo."
  clip={{
src: "/images/cookbook/showcase/05_lighthouse_keeper.mp4",
poster: "/images/cookbook/showcase/posters/05_lighthouse_keeper.jpg",
label: "\u201CStorm\u2019s coming in.\u201D Voice, lip-sync, wind, and surf in one call",
note: "Click to play, sound on.",
}}
/>

## Featured

<FeaturedCards
  items={[
{
title: "Video quickstart",
img: "/images/cookbook/showcase/posters/10_detectives_car.jpg",
tags: ["t2v", "settings", "speech"],
href: "/cookbook/video_quickstart",
},
{
title: "Start from images",
img: "/images/cookbook/showcase/posters/02_sailboat_orbit.jpg",
tags: ["keyframes", "reference_images"],
href: "/cookbook/video_start_from_images",
},
{
title: "Recast and continue",
img: "/images/cookbook/clips/posters/03_source.jpg",
tags: ["reference_video", "start_video"],
href: "/cookbook/video_edit_recast_continue",
},
{
title: "Multi-shot films",
img: "/images/cookbook/showcase/posters/09_latte_montage.jpg",
tags: ["multi-shot", "concurrency", "ffmpeg"],
href: "/cookbook/video_multishot_films",
},
]}
/>

## All recipes

<RecipeList
  items={[
{
title: "Video quickstart",
tags: ["t2v", "settings", "speech"],
href: "/cookbook/video_quickstart",
},
{
title: "Start a video from images",
tags: ["keyframes", "reference_images"],
href: "/cookbook/video_start_from_images",
},
{
title: "Recast and continue video",
tags: ["reference_video", "start_video"],
href: "/cookbook/video_edit_recast_continue",
},
{
title: "Multi-shot films",
tags: ["multi-shot", "concurrency", "ffmpeg"],
href: "/cookbook/video_multishot_films",
},
{
title: "Prompting video with audio",
tags: ["prompt guide"],
href: "https://github.com/black-forest-labs/bfl_cookbook/blob/main/video/PROMPTING.md",
external: true,
},
{
title: "Fine-tune FLUX.2 [klein]",
tags: ["LoRA", "GPU"],
href: "https://github.com/black-forest-labs/bfl_cookbook/tree/main/fine-tuning",
external: true,
},
{
title: "Run FLUX.2 [klein] locally",
tags: ["diffusers", "GPU"],
href: "https://github.com/black-forest-labs/bfl_cookbook/tree/main/images/klein-local",
external: true,
},
{
title: "Agent skill for the video API",
tags: ["SKILL.md", "CLI"],
href: "https://github.com/black-forest-labs/bfl_cookbook/tree/main/video/agent-skill",
external: true,
},
]}
/>
