나는 모든 포트폴리오를 3D 마인크래프트 세계로 바꾸는 리액트 컴포넌트를 만들었다.

작성자

카테고리:

← 피드로
DEV Community · Shivansh Goel · 2026-07-23 개발(SW)

I Built a React Component That Turns Any Portfolio Into a 3D Minecraft World

Every developer portfolio looks the same. Dark mode. Sans-serif font. “Hi, I’m X, a passionate developer.” Scroll. Skills section with floating icons. Scroll. Projects in a grid. Scroll. Contact form nobody will fill.

Sound familiar?

I’ve reviewed hundreds of developer portfolios — as a peer, during hackathons, while hiring. They all blur into one. The content might differ, but the experience is identical.

So I asked myself a stupid question:

What if your portfolio was a playable Minecraft world instead?

And then I actually built it.

Introducing CraftFolio

CraftFolio is an open-source React component library that transforms your developer portfolio into a live, interactive 3D voxel environment.

Your projects become structures you can walk up to. Your skills become minable ores. Your experience becomes terrain you traverse. No two portfolios look alike because the world is generated from your data.

One component. One config object. A portfolio nobody forgets.

import { CraftFolio } from 'craftfolio';

function App() {
  return (
    <CraftFolio
      name="Shivansh Goel"
      role="Full Stack Developer"
      skills={['TypeScript', 'React', 'Python', 'FastAPI', 'Three.js']}
      projects={[
        { name: 'Forkcast', url: 'https://github.com/...', block: 'diamond' },
        { name: 'GhostRelay', url: 'https://github.com/...', block: 'obsidian' },
        { name: 'ZipLink', url: 'https://github.com/...', block: 'emerald' },
      ]}
      theme="overworld"
    />
  );
}

Enter fullscreen mode Exit fullscreen mode

That’s the entire integration. Drop it in, customize the config, deploy.

Why I Built This

Let me give you a number: 4.7 million.

That’s how many repositories come up when you search “developer portfolio” on GitHub. Nearly five million variations of the same three-column layout with a hero section.

When a recruiter reviews 200 portfolios in a week, yours needs to be the one they remember at dinner.

“Honey, I saw this kid’s portfolio today — it was literally Minecraft.”

That’s the unfair advantage CraftFolio gives you.

What You Actually Get

When you drop CraftFolio into your React app, it renders:

  • A 3D voxel world — real-time Three.js rendering with a Minecraft aesthetic
  • Walkable terrain — procedurally generated from your data
  • Project structures — your repos become buildings you can approach and click
  • Skill ores — your tech stack appears as glowing blocks scattered through the world
  • Day/night cycle — dynamic lighting that shifts over time
  • Keyboard navigation — WASD movement, mouse to look, click to interact
  • Mobile touch controls — virtual joystick + tap interaction
  • Responsive fallback — gracefully degrades to a styled 2D view on very old devices

The Technical Deep-Dive

Architecture

CraftFolio/
├── src/
│   ├── components/
│   │   ├── VoxelWorld.tsx        — Three.js scene, camera, renderer
│   │   ├── Terrain.tsx           — Procedural world generation
│   │   ├── PlayerControls.tsx    — First-person camera + WASD movement
│   │   ├── ProjectStructure.tsx  — Interactive project buildings
│   │   ├── SkillOre.tsx          — Floating/glowing skill blocks
│   │   └── HUD.tsx               — Overlay UI (name, minimap, controls hint)
│   ├── shaders/
│   │   ├── voxel.vert            — Vertex shader for block geometry
│   │   └── voxel.frag            — Fragment shader with pixelated lighting
│   ├── systems/
│   │   ├── WorldGenerator.ts     — Perlin noise terrain + structure placement
│   │   ├── PhysicsEngine.ts      — Simple AABB collision detection
│   │   └── InteractionManager.ts — Raycasting for click detection
│   ├── config/
│   │   └── themes.ts             — Overworld, Nether, End color palettes
│   └── index.ts                  — Public API export

Enter fullscreen mode Exit fullscreen mode

Performance: 10,000+ Voxels at 60fps

The naive approach to rendering voxels is one mesh per block. At 10,000 blocks, that’s 10,000 draw calls per frame. Your GPU melts.

CraftFolio uses instanced rendering — a single geometry is drawn thousands of times in one draw call, with per-instance transforms stored in a buffer:

const blockGeometry = new THREE.BoxGeometry(1, 1, 1);
const blockMaterial = new THREE.MeshLambertMaterial({ map: textureAtlas });

const instancedMesh = new THREE.InstancedMesh(
  blockGeometry,
  blockMaterial,
  MAX_BLOCKS
);

// Set position for each block instance
blocks.forEach((block, i) => {
  const matrix = new THREE.Matrix4();
  matrix.setPosition(block.x, block.y, block.z);
  instancedMesh.setMatrixAt(i, matrix);
});

// One draw call for ALL blocks
scene.add(instancedMesh);

Enter fullscreen mode Exit fullscreen mode

Additional optimizations:

  • Frustum culling — don’t render blocks behind the camera
  • Face culling — don’t render faces between two adjacent solid blocks
  • LOD (Level of Detail) — distant blocks render as flat colored planes
  • Texture atlas — all block textures in one spritesheet = one texture bind

Result: Smooth 60fps on desktop, 30fps+ on mid-range mobile.

Terrain Generation with Perlin Noise

The world isn’t random — it uses layered Perlin noise to create natural-looking hills and valleys:

function generateTerrain(width: number, depth: number): BlockData[] {
  const blocks: BlockData[] = [];

  for (let x = 0; x < width; x++) {
    for (let z = 0; z < depth; z++) {
      const baseHeight = perlin2D(x * 0.05, z * 0.05) * 8;
      const hills = perlin2D(x * 0.02, z * 0.02) * 12;
      const detail = perlin2D(x * 0.1, z * 0.1) * 2;

      const height = Math.floor(baseHeight + hills + detail) + 10;

      for (let y = 0; y <= height; y++) {
        blocks.push({
          x, y, z,
          type: y === height ? 'grass' : y > height - 3 ? 'dirt' : 'stone'
        });
      }
    }
  }

  return blocks;
}

Enter fullscreen mode Exit fullscreen mode

Project structures are placed at terrain peaks — naturally visible from anywhere in the world.

The React + Three.js Marriage

Reconciling React’s declarative model with Three.js’s imperative scene graph is painful. Here’s how CraftFolio solves it:

  1. The scene lives in a ref — Three.js objects are created once and mutated, not re-rendered
  2. React controls state — UI, config changes, and user data flow through React state
  3. A bridge hook syncs themuseWorldSync() watches React state and imperatively updates the scene
function useWorldSync(config: CraftFolioConfig, sceneRef: RefObject<THREE.Scene>) {
  useEffect(() => {
    if (!sceneRef.current) return;

    rebuildProjectStructures(sceneRef.current, config.projects);
    rebuildSkillOres(sceneRef.current, config.skills);
    applyTheme(sceneRef.current, config.theme);
  }, [config.projects, config.skills, config.theme]);
}

Enter fullscreen mode Exit fullscreen mode

This avoids the “React re-renders destroy my 3D scene” problem while keeping the developer API fully declarative.

Three Hard Lessons I Learned

1. Mobile Performance Is a Different Beast

On desktop with a discrete GPU, you can afford expensive shaders. On a 2020 mid-range Android phone? You’re fighting for every millisecond.

I had to:

  • Reduce world size from 100×100 to 40×40 on mobile
  • Disable shadows on low-end devices
  • Implement a quality auto-scaler that drops render resolution if FPS dips below 24

2. Accessibility in a 3D World Is Hard (But Possible)

A recruiter using a screen reader can’t “walk through” a 3D world. So CraftFolio includes:

  • An aria-live region that narrates: “You are near the Forkcast project. Press Enter to view details.”
  • Keyboard-only navigation mode (arrow keys + tab)
  • A reduceMotion mode that shows a 2D card layout instead (respects prefers-reduced-motion)
  • All interactive elements in the tab order with proper labels

3. Bundle Size Wars

Three.js is ~150KB gzipped. For a portfolio component, that’s heavy. My approach:

  • Three.js is a peer dependency — if you’re already using it, no extra cost
  • Tree-shakeable imports — only pulling in what’s needed
  • CraftFolio-specific code is ~45KB gzipped
  • Lazy loading — the 3D world only initializes when entering the viewport

Themes: Choose Your Dimension

CraftFolio ships with three themes:

Theme Vibe Best For Overworld Green grass, blue sky, warm lighting Friendly, approachable portfolios Nether Dark red, lava lakes, dramatic shadows Edgy/gaming-focused developers End Purple void, floating islands, ethereal glow Creative/artistic portfolios
<CraftFolio theme="nether" />

Enter fullscreen mode Exit fullscreen mode

You can also pass a custom theme object for full control over colors, skybox, and block textures.

Who Is This For?

Use CraftFolio if you’re:

  • A junior dev who needs to stand out in a brutal job market
  • An experienced dev who wants something memorable for their personal brand
  • A game dev who wants their portfolio to demonstrate their passion
  • A content creator who needs a unique landing page
  • Anyone tired of the same Tailwind/Next.js portfolio template

Don’t use CraftFolio if:

  • Your target audience is strictly corporate/enterprise
  • You need perfect Lighthouse accessibility scores
  • You’re applying to a company that blocks WebGL

Get Started in 60 Seconds

Install

npm install craftfolio three @types/three

Enter fullscreen mode Exit fullscreen mode

Basic Usage

import { CraftFolio } from 'craftfolio';

export default function Portfolio() {
  return (
    <CraftFolio
      name="Your Name"
      role="Your Title"
      skills={['React', 'Node.js', 'Python']}
      projects={[
        {
          name: 'My Cool Project',
          description: 'A brief description',
          url: 'https://github.com/you/project',
          block: 'diamond',
        },
      ]}
      theme="overworld"
      controls="wasd"
      onProjectClick={(project) => window.open(project.url)}
    />
  );
}

Enter fullscreen mode Exit fullscreen mode

Deploy

Works with any React hosting:

  • vercel deploy
  • netlify deploy
  • GitHub Pages
  • Any static host

What’s on the Roadmap

  • Multiplayer mode — Visitors see each other as pixelated avatars
  • Custom block textures — Upload your own pixel art
  • NPM CLI scaffoldernpx create-craftfolio
  • Weather system — Rain, snow, or sunshine based on location
  • Sound effects — Footsteps, ambient music, interaction clicks
  • Analytics integration — Track which projects visitors interact with most

The Source

Final Thought

The best portfolio isn’t the one with the most impressive project list. It’s the one the recruiter remembers.

Five million portfolios on GitHub. Five million dark-mode hero sections. Five million “passionate developer” taglines.

Or… one Minecraft world that someone actually played for two minutes.

Which one do you think gets the callback?

Star it if you’d use it. Fork it if you’d improve it. And drop a comment with YOUR most creative portfolio idea — I want to see what this community comes up with.

Built by Shivansh Goel — AI & Full Stack Developer building intelligent web platforms.

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다