A minimalist, performance-obsessed developer portfolio
bilingual · 3D WebGL · inertia scroll · fluid cursor · SSR-safe i18n
- Overview
- Highlights
- Tech stack
- Architecture
- Project structure
- Getting started
- Scripts
- Performance
- Internationalization
- Deployment
- Contributing
- License
wwew.tech is a full-stack developer's personal landing page — a single-page experience designed around three principles: speed, restraint, and craft. The site is built on the Next.js App Router with React Server Components, a Lenis-driven smooth-scroll pipeline, a Three.js holographic scene, and a bilingual (RU / EN) copy system that stays hydration-safe.
Not a template. Every section — from the shiny-text hero to the fluid cursor — is written in-house.
Live at wwew.tech.
|
|
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, RSC, streaming) |
| Language | TypeScript 5 (strict) |
| Styling | Tailwind CSS v4 with CSS-variable design tokens |
| Animation | Framer Motion 12 + hand-written CSS keyframes |
| 3D / WebGL | Three.js · @react-three/fiber · @react-three/drei · postprocessing |
| Scroll | Lenis 1.3 (inertia, RAF-synchronized) |
| Icons | Lucide React |
| Fonts | Geist Sans (next/font, preloaded, fallback-adjusted) |
| CI | GitHub Actions (lint · typecheck · build) |
| Hosting | Vercel (edge runtime, automatic AVIF/WebP) |
┌──────────────────────────────────────────────────┐
│ app/layout.tsx │
│ Metadata · JSON-LD · Viewport · Global fonts │
└──────────────────────────────────────────────────┘
│
┌──────────────────┼──────────────────┐
▼ ▼ ▼
AppProvider LenisProvider FluidCursorWrapper
(i18n state) (inertia scroll) (deferred canvas)
│
▼
┌──────────────────┐
│ app/page.tsx │ ← SSR hero skeleton
└──────────────────┘
│
▼
ClientHomePage (hydrates)
│
┌───────────────┬───────┴────────┬───────────────┐
▼ ▼ ▼ ▼
Hero Philosophy Projects ContactHub
+ +
HolographicScene StackGrid
(Three.js) (lazy)
Rendering strategy. The hero is server-rendered as a skeleton for an instant LCP, then ClientHomePage hydrates on top of it. FluidCursorWrapper mounts a canvas deferred behind requestIdleCallback, and heavy below-the-fold components (HolographicScene, StackGrid) are dynamically imported.
src/
├── app/
│ ├── layout.tsx Root layout · metadata · JSON-LD
│ ├── page.tsx SSR entry · hero skeleton
│ ├── opengraph-image.tsx Dynamic OG image
│ ├── twitter-image.tsx Dynamic Twitter card
│ ├── sitemap.ts Sitemap generation
│ ├── robots.ts Robots policy
│ └── globals.css Tokens · keyframes · utilities
│
├── components/
│ ├── ClientHomePage.tsx Client shell that composes sections
│ ├── layout/ Navbar · Footer
│ ├── providers/ LenisProvider · FluidCursorWrapper
│ ├── sections/ Hero · Philosophy · ContactHub
│ └── ui/ HolographicScene · FluidCursor · ShinyText · StackGrid · InteractiveBlob
│
├── context/
│ └── AppContext.tsx Language context · RU/EN translation dictionary
│
└── lib/
└── utils.ts cn() and shared helpers
- Node.js ≥ 18
- npm, yarn, or pnpm
git clone https://github.com/wwewtech/wwew.tech.git
cd wwew.tech
npm installnpm run devOpen http://localhost:3000.
npm run build && npm run startNo environment variables are required. Optionally set NEXT_PUBLIC_SITE_URL to override the canonical URL used in metadata.
| Command | Purpose |
|---|---|
npm run dev |
Start the Next.js dev server with HMR |
npm run build |
Create an optimized production build |
npm run start |
Serve the production build on port 3000 |
npm run lint |
Run ESLint with the Next.js config |
npx tsc --noEmit |
Type-check the project without emitting files |
The site is engineered for sub-second interaction on mid-range mobile hardware.
- LCP-first hero — plain-text H1 rendered server-side, zero animation on the critical path
- Code splitting —
HolographicScene,FluidCursor, and the projects grid are dynamic imports - Font strategy —
next/fontwithdisplay: swap,adjustFontFallback, and preload - Image pipeline — AVIF → WebP fallback, custom
deviceSizes, immutable 1-year cache on hashed assets - Bundle size —
optimizePackageImportsapplied toframer-motion,three,@react-three/*,lucide-react,lenis - Source maps — disabled in production to shrink artifacts
- Caching headers —
public, max-age=31536000, immutablefor static assets and/_next/static/*
Language state is managed by a lightweight context in src/context/AppContext.tsx:
- Translation dictionaries for Russian and English live inline — no network round-trip
- The default language is rendered in SSR so the first paint is never empty
- The toggle persists to
localStorageand updates<html lang>on the client
Adding a locale is a matter of extending the translations record and the Language union.
The project is deployed continuously to Vercel from the main branch.
To deploy your own copy:
- Fork this repository
- Import it into Vercel
- Accept the defaults — no environment variables required
- (Optional) Set
NEXT_PUBLIC_SITE_URLto your custom domain
CI (lint + type-check + build) runs on every push and pull request via .github/workflows/ci.yml.
Issues and pull requests are welcome. Please:
- Open an issue first for non-trivial changes — templates are in .github/ISSUE_TEMPLATE
- Keep commits focused and write meaningful messages
- Make sure
npm run lintandnpx tsc --noEmitboth pass - Follow the existing style — no comment noise, no speculative abstractions
Released under the MIT License.