DEV Community

deltacraft
deltacraft

Posted on

How I Built a 3D Developer Portfolio That Actually Stands Out (with React Three Fiber)Three Fiber (Step-by-Step)

How I Built a 3D Developer Portfolio That Actually Stands Out (with React Three Fiber)

Most developer portfolios look the same. A hero section, a projects grid, a contact form. Yours deserves better.

In this post, I’ll show you how to build a portfolio with an animated particle system background, 5 different 3D scene types for your project cards, and scroll-based animations — all without deep Three.js knowledge.

Here’s what the final result includes:

  • Floating particle field with dynamic connection lines in the hero section
  • 5 interchangeable 3D scenes: particles, orbit, wave, helix, sphere
  • Framer Motion scroll reveals
  • A single config.js file to customize everything — no Three.js needed

Tech Stack

  • React 18 + Vite
  • React Three Fiber
  • @react-three/drei
  • Framer Motion

The Core Idea: A Config-Driven Portfolio

The key architectural decision is a single config.js that controls everything — your name, bio, projects, colors, and even 3D scene settings:

const config = {
  name: 'Jane Doe',
  role: 'Creative Developer',
  headline: ['I Build', 'Digital', 'Experiences'],
  email: 'hello@yourname.com',

  scene: {
    heroParticleCount: 800,
    heroParticleSpeed: 0.3,
    accentColor: '#c8ff00',
  },
}
Enter fullscreen mode Exit fullscreen mode

No digging through components. Change one file, the whole site updates.

The Hero: Particle Field with Connection Lines

The most visually striking part is the hero background — 800 particles floating in 3D space, drawing lines between particles that get close enough to each other.

function ParticleField({ count = 800, connectionDistance = 1.5, color = '#c8ff00' }) {
  const pointsRef = useRef()

  useFrame(({ clock }) => {
    const pos = pointsRef.current.geometry.attributes.position.array
    const t = clock.getElapsedTime()

    for (let i = 0; i < count; i++) {
      const i3 = i * 3
      pos[i3] += Math.sin(t * 0.5 + i) * 0.001
      pos[i3 + 1] += Math.cos(t * 0.3 + i) * 0.001
    }
    pointsRef.current.geometry.attributes.position.needsUpdate = true
  })

  return (
    <points ref={pointsRef}>
      <bufferGeometry>
        <bufferAttribute attach="attributes-position" array={positions} count={count} itemSize={3} />
      </bufferGeometry>
      <pointsMaterial
        size={0.03}
        color={color}
        transparent
        opacity={0.8}
        blending={THREE.AdditiveBlending}
        depthWrite={false}
      />
    </points>
  )
}
Enter fullscreen mode Exit fullscreen mode

The AdditiveBlending is what gives it that glowing neon feel.

5 Scene Types for Project Cards

Each project card in the Projects section gets its own 3D scene. You pick which one per project in config.js:

projects: [
  {
    title: 'My SaaS App',
    description: 'Real-time analytics dashboard.',
    tags: ['React', 'Node.js'],
    sceneType: 'orbit',   // orbit | wave | helix | sphere | particles
  },
]
Enter fullscreen mode Exit fullscreen mode

The scenes:

Scene Visual Best For
particles Floating dots with connection lines Hero, general
orbit Particles orbiting a glowing center Data/analytics projects
wave Undulating grid of points Creative/design projects
helix DNA-style double helix Science/tech projects
sphere Pulsing particle sphere 3D/WebGL showcases

Animating Content with Framer Motion

The text content fades up on load using Framer Motion variants:

const fadeUp = {
  hidden: { opacity: 0, y: 30 },
  visible: (i) => ({
    opacity: 1,
    y: 0,
    transition: { duration: 0.8, delay: 0.5 + i * 0.2 }
  })
}

// Usage
<motion.h1 custom={1} initial="hidden" animate="visible" variants={fadeUp}>
  {config.headline[0]} <span>{config.headline[1]}</span>
</motion.h1>
Enter fullscreen mode Exit fullscreen mode

The custom prop staggers each element — role tag first, then headline, then bio, then buttons.

Customizing Colors

The accent color runs through both the 3D scenes and CSS. Update it in one place:

scene: {
  accentColor: '#c8ff00',  // Change this
},
theme: {
  accent: '#c8ff00',       // And this
}
Enter fullscreen mode Exit fullscreen mode

Popular alternatives: #00d4ff (electric blue), #ff3366 (hot pink), #a855f7 (purple glow).

Deploying to Vercel

npm run build
npx vercel
Enter fullscreen mode Exit fullscreen mode

Done. Free hosting, automatic HTTPS.


Want the Full Setup Without Starting from Scratch?

Building all of this from scratch takes a while to tune — getting the particle physics right, the connection line performance optimized, the Framer Motion timing dialed in.

I packaged the complete, production-ready version into a starter kit: R3F 3D Portfolio Starter Kit

It includes all 5 scene types, the full page structure (Hero, Projects, About, Contact, Footer), and the config-driven setup described above. Drop in your info, run npm install, done.


What 3D effects are you using in your portfolio? Drop a comment — I read every one.

Top comments (0)