Three.js hero section for Next.js
A particle hero that spells your word, loaded with next/dynamic and ssr: false so the server never touches WebGL.

Use it in Next.js
"use client";
import dynamic from "next/dynamic";
const ParticleMorph = dynamic(() => import("@/components/ParticleMorph"), {
ssr: false,
loading: () => <div className="h-full w-full bg-black" />,
});
export function Hero() {
return (
<section className="relative h-[80vh] overflow-hidden bg-black">
<ParticleMorph word="acme" className="absolute inset-0" />
<div className="pointer-events-none relative z-10 mx-auto max-w-3xl pt-24 text-center text-white">
<h1 className="text-5xl font-bold">Ship faster with Acme</h1>
</div>
</section>
);
}Good to know
- Three.js needs window and a GPU, so the import goes through next/dynamic with ssr: false. The loading box keeps the hero's height while the code downloads, so nothing jumps.
- It draws 9,000 particles by default. On older phones pass a smaller count, like 4000.
- Pixel ratio is capped at 2, which keeps phones with 3x screens from rendering three times the pixels.
- It doesn't pause when scrolled out of view and doesn't read Reduce Motion yet. Unmount it or render a still image for those visitors.
Install
- Copy from the zipPut
react/src/componentsintosrc/, thennpm i three. - Or ask your AIPaste PROMPT.md into Cursor, Lovable or v0.
Props
- word
- the text one shape spells
- count
- particles, 9000 by default
- colorA / colorB
- gradient colours
- className
- size it from the parent
How qodesign compares
- qodesign vs React BitsReact Bits is best for: text animations, animated backgrounds and creative effects.
- qodesign vs Aceternity UIAceternity UI is best for: teams building many marketing pages who want one big library.
All comparisons, with prices read on each library's own site.
Questions
Why do I get 'window is not defined'?
Something imported three.js on the server. Load the component with next/dynamic and ssr: false, as in the snippet.
Will it slow my page?
Three.js adds weight to the bundle. Loading it dynamically keeps it out of the first page load.
Can Cursor or v0 add it for me?
Yes. Each download has a PROMPT.md. Paste it into Cursor, Lovable, v0 or Claude Code and it fits the piece into your app.
Can I use it in client work?
Yes, in personal and client projects. You can't resell the code itself as a kit.