You are a senior frontend engineer and educator. Your job is to refactor the 3d-planets project at the code level only — improving readability, reusability, and learning clarity for a YouTube tutorial audience.
- Do NOT change any 3D scene setup (Three.js, R3F canvas, lighting, camera, texture loading, atmosphere shaders, planet rotation).
- Do NOT change any animation or transition logic (loading animations, scroll behavior, route transitions).
- Do NOT change any UI layout, visual design, or Tailwind class names.
- Do NOT change routing behavior (
PlanetDetail.jsx,PlanetLists.jsxroute logic must remain identical). - Do NOT rename files or move files to different folders.
- Do NOT touch the
dist/folder — it is a build artifact, never edit it. - Do NOT touch
src/store/folder structure — it may be empty or contain future stores. - Business logic must remain identical before and after refactor.
- The project must still pass
yarn buildwith zero errors after every goal. - This project uses Yarn — do NOT use
npmcommands.
src/
├── components/
│ ├── models/ ← Planet 3D view components
│ │ ├── AuroraView.jsx
│ │ ├── BlazeonView.jsx
│ │ ├── EarthView.jsx
│ │ ├── IgnisMajorView.jsx
│ │ ├── NebulonView.jsx
│ │ ├── SmallPlanetsViewer.jsx
│ │ ├── SpectraView.jsx
│ │ ├── VerdantiaView.jsx
│ │ └── ZephyrionView.jsx
│ └── sections/ ← UI, sections, routes (all merged)
│ ├── Button.jsx
│ ├── CardsContainer.jsx
│ ├── CommonViewer.jsx
│ ├── EarthDetail.jsx
│ ├── EarthInfo.jsx
│ ├── HeroOverLay.jsx
│ ├── Home.jsx
│ ├── Nav.jsx
│ ├── PlanetDetail.jsx
│ ├── PlanetLists.jsx
│ ├── PlanetLoader.jsx
│ ├── RealHero.jsx
│ └── ScrollToTop.jsx
├── store/ ← empty, reserved
├── App.jsx
├── index.css
└── main.jsx
constant/ ← root-level sibling of public/
└── index.js
This is the highest-priority goal. Scan every file in src/ for hardcoded data arrays and object literals defined inside component functions or at module level inside component files.
Target patterns specific to this project:
- Planet list arrays (id, name, description, texture paths, atmosphere color, radius, etc.)
- Planet card data arrays used in
CardsContainer.jsxorPlanetLists.jsx - Navigation link arrays used in
Nav.jsx - Any array rendered with
.map()whose source data is defined inline in the file
Rules:
- Move every such array/object into
constant/index.jsas a named export. - Group exports with clear section comments:
// ─── Planet data ────────────────────────────── export const PLANETS = [ ... ]; // ─── Navigation ─────────────────────────────── export const NAV_LINKS = [ ... ]; // ─── Texture paths ──────────────────────────── export const TEXTURES = { ... };
- The component must import from
constant/index.jsand render using.map()— no inline array literals in JSX. - Do NOT move arrays that are computed at runtime (derived from props, state, or API calls).
- After extraction, verify that
SmallPlanetsViewer.jsx(which likely renders a list of small planet objects) also uses the sharedPLANETSarray — do not let it maintain a separate inline copy.
After Goal 1: run yarn build — fix any errors before proceeding.
Scan all section and model components for repeated JSX structures. If the same visual pattern appears 2 or more times (within one file or across files), extract it.
Target patterns specific to this project:
- Planet card layout (image/thumbnail + name + short description + CTA button) — likely repeated in
CardsContainer.jsxand possiblyPlanetLists.jsx - Planet stat row (label + value pair) — likely repeated in
EarthInfo.jsxandEarthDetail.jsx - Section heading/subheading block — if repeated across
RealHero.jsx,HeroOverLay.jsx - The
Button.jsxcomponent — verify it is used everywhere a button appears; if any file defines its own inline `` with repeated styling, replace it withButton.jsx - Loading/spinner pattern in
PlanetLoader.jsx— check if loading state is duplicated in any model component
Extraction rules:
- Extract into the same file if only used there; extract into
src/components/sections/if used across files. - The extracted component must accept props for all varying parts.
- Add JSDoc prop documentation above every extracted component:
/** * PlanetStatRow — displays a single label/value stat for a planet. * @param {string} label - Stat label (e.g. "Mass", "Radius"). * @param {string} value - Stat value (e.g. "5.97 × 10²⁴ kg"). */
- Do NOT extract a pattern if the prop interface would be more complex than the repetition it removes.
- Do NOT extract single-use components.
After Goal 2: run yarn build — fix any errors before proceeding.
Identify logic inside components that mixes state + side effects for a single concern. Extract each group into src/hooks/.
Target patterns specific to this project:
- Planet loading state management (loading flag + timeout or suspense wrapper) →
usePlanetLoader.js - Scroll-to-top behavior (
ScrollToTop.jsxlikely usesuseEffect+window.scrollTo) →useScrollToTop.js - Window resize / responsive breakpoint detection if used in JS →
useWindowSize.js - Any
useEffectthat sets up and tears down an event listener → extract to a named hook
Naming rules:
- File names and function names must start with
use. - One hook per concern.
- The hook must return exactly what the component needs — no over-exposure.
- After extraction, the component body should read like a description of intent, not implementation.
Example:
// src/hooks/useScrollToTop.js
export const useScrollToTop = () => {
const { pathname } = useLocation();
// Scroll to top on every route change
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
};After Goal 3: run yarn build — fix any errors before proceeding.
Apply these rules consistently across all src/ files:
Naming:
- Variables and functions:
camelCase. Components:PascalCase. - Event handlers:
handle[Event](e.g.handleCardClick,handleBack,handlePlanetSelect). - Boolean state/variables:
is[State]orhas[State](e.g.isLoading,isVisible,hasError). - Texture/asset import variables: use descriptive names matching the texture's role, not the filename (e.g.
earthDayMapnoted,ignisAtmospherenotia). - Avoid single-letter variable names except for
.map()index params.
Structure inside each component file — enforce this order:
1. imports (React → third-party → internal components → constants → assets)
2. file-level constants (if not in constant/index.js)
3. component function
a. refs
b. state (useState)
c. store / context
d. router hooks (useParams, useNavigate, useLocation)
e. derived values
f. custom hooks (src/hooks/)
g. event handlers (handle*)
h. useEffect blocks
i. return JSX
4. export
Comments:
- Add a single-line comment above each
useEffectblock explaining its purpose. - Add a single-line comment above each major JSX section (e.g.
{/* Planet grid */},{/* Detail overlay */},{/* Loading fallback */}). - Add a single-line comment above each texture/asset import group explaining which planet it belongs to.
- Do NOT comment self-evident code.
After Goal 4: run yarn build — fix any errors before proceeding.
Scan all files for hardcoded values with semantic meaning used in JavaScript (not Tailwind):
- Planet sphere radius values (e.g.
2.5,1.8,3.0) - Rotation speed values (e.g.
0.002,0.005) - Animation duration numbers (e.g.
300,1.2,2000) - Camera position values (e.g.
[0, 0, 5]) - Atmosphere thickness or opacity values
- Breakpoint pixel values used in JS
Add them to constant/index.js under dedicated groups:
// ─── 3D Scene config ──────────────────────────
export const SCENE = {
CAMERA_Z: 5,
ROTATION_SPEED_SLOW: 0.002,
ROTATION_SPEED_FAST: 0.005,
};
// ─── Planet sizes ─────────────────────────────
export const PLANET_RADIUS = {
EARTH: 2.5,
SMALL: 1.2,
LARGE: 3.5,
};
// ─── Animation ────────────────────────────────
export const ANIMATION = {
DURATION_FAST: 300,
DURATION_BASE: 600,
};Rules:
- Do NOT extract Tailwind class strings.
- Do NOT extract values that appear only once and carry no semantic ambiguity.
- After extraction, update every import site.
After Goal 5: run yarn build — fix any errors before proceeding.
Run goals strictly in order: 1 → 2 → 3 → 4 → 5.
After each goal:
- Run
yarn build— fix any errors before moving to the next goal. - Briefly state: which files changed, what was extracted or renamed.
Do NOT batch all goals together and edit everything at once.
When all goals are complete, provide:
- List of all new files created (hooks, extracted components)
- List of all files modified
- Final
yarn buildoutput log - A short per-goal summary: what changed and why it improves the code for a learner watching a YouTube tutorial