
Imagine you have a giant digital toy box. Inside, you keep the cool things you've built, the stories you've written, and a diary of all the interesting things you've learned. Fezcodex is that toy box. It is a special website that works like a personal museum on the internet. It is not just a boring page; it has moving parts, secret "Easter eggs," and little mini-apps like a sound mixer and a knowledge graph.
- Digital Garden: A space where blog posts and "logs" (mini-diaries about books, movies, or games) grow.
- Knowledge Graph: A 3D interactive visualization of how all content on the site is interconnected.
- Project Archives: A showcase of all the coding experiments and software I've built.
- Mini-Apps: Built-in tools like an Atmosphere Mixer, Cloud Music Player, Typing Tester, and a digital Rotary Phone.
- Visual Magic: Change how the whole site looks using the "Visual Matrix"—make it look like an old computer (CRT), a blueprint, or even a comic book.
- Achievements: Just like a video game, you get little trophies for exploring the site and finding hidden things.
Tech Stack (The Lego Bricks)
- Frontend: React 19, Tailwind CSS, and Framer Motion for smooth animations.
- 3D & Graphics: Three.js and react-force-graph-3d for the knowledge graph.
- Content: Markdown and PIML (Plain Old Markup Language) for structured content.
- Build Tools: Vite + Vike for the SPA build and shell generation; a Puppeteer-based crawler hydrates dynamic routes into static HTML for GitHub Pages.
- Persistence: Local Storage for settings, achievements, and persistent state.
- AI Tooling: Model Context Protocol (MCP) server for automated content management.
Model Context Protocol (MCP)
Fezcodex includes a custom MCP server to assist AI agents (like Gemini) in managing content.
- create_blog_post: Automates the creation of blog posts, including file generation, metadata registry updates, and RSS/Sitemap regeneration.
Integration with Gemini CLI:
To use this server with your Gemini CLI, run:
gemini mcp add fezcodex-blog-writer --command "node scripts/mcp-server/index.mjs"
# or
gemini mcp add --scope project fezcodex npm run mcp
Once added, the AI can create blog posts directly through its toolset.
- src/app/: Domain logic, core features, and views (Achievements, OS, Command Palette, etc.).
- src/components/: Reusable UI components (Buttons, Modals, Cards).
- src/context/: Global state management (Visual Settings, Toast, Animation).
- public/: The "pantry" where all actual content (PIML files, text, images, sounds) is stored.
- scripts/: Helper programs for generating RSS, sitemaps, and wallpapers.
Make sure you have Node.js installed on your computer.
git clone https://github.com/fezcode/fezcode.github.io.git
cd fezcode.github.io
This will open the site at http://localhost:5190 (the dev server port set in vite.config.mjs; if that port is busy, Vite falls back to the next free one — check the terminal output).
This project uses BrowserRouter for clean URLs. To support this on static hosts like GitHub Pages, the build runs in two passes:
- Vite + Vike produces the JS bundles and writes one empty-shell index.html per route listed in pages/routes.js plus every dynamic route discovered by pages/discoverRoutes.js (blog posts, series episodes, log entries, story book pages — ~460 routes total).
- scripts/prerender-crawl.mjs spins up a Vite preview server, loads each shell in headless Chromium, and replaces the empty #react-root with the hydrated HTML. Skipped routes fall back to SPA rendering at runtime — not a build failure.
| Command |
What it does |
When to use |
| npm run build |
Vite build + post-build + full prerender crawl |
Default. Produces a fully SSG'd dist/client/. |
| npm run build:fast |
Vite build + post-build only (no crawl) |
Fast iteration on components; skip the ~2–5 min crawler. |
| npm run build:retry |
Full crawl, then re-attempts any routes that missed the render gate |
Use when the default build reports many skipped routes (flaky JS/fetch under load). |
Tune the crawler via env vars: PRERENDER_CONCURRENCY=6 (default 6), PRERENDER_RETRY=1 (same as --retry).
npm run deploy # build (full crawl) + push dist/client to gh-pages
npm run deploy:fast # shell-only build + push (skipped routes become SPA-only)
npm run deploy:retry # full crawl with retry pass + push
gh-pages publishes the contents of dist/client/ to the gh-pages branch of the repo.
Stories are managed via git subtrees. Because subtree remotes are not tracked by git, you must initialize the remote once after cloning:
- npm run init-stories: Initialize the stories remote URL (only needed once).
- npm run pull-stories: Sync stories from the remote repository.
- npm run push-stories: Push local story changes to the remote repository.
- Contributing: Please read our CONTRIBUTING.md for guidelines on commit messages and content updates.
- Styling: We use Tailwind. Keep it Brutalist yet polished.
- Components: Always use CustomDropdown, BrutalistDialog, and CustomSlider for UI consistency.
- Icons: We use @phosphor-icons/react. Always use the ones ending in Icon (e.g., CpuIcon).
- Logic: Use Context for global settings like Visual Effects and Achievements.
Developer Guide: How to Update Things
If you are modifying or expanding the functionality of Fezcodex, follow these specific architectural patterns:
1. Adding or Updating Commands
Commands are used in the Commands Page and the Command Palette. To update them, you must touch three places:
- src/data/commands.js: Update the UI data (title, description, icon color) for the /commands page.
- src/hooks/useCommandRegistry.js: Implement the actual logic/handler for what the command does.
- src/hooks/useSearchableData.js: Update the customCommands list so the Command Palette (Ctrl + K) can "find" the command.
The site-wide search (Command Palette and Search bar) is powered by a unified registry:
- Automatic: Blog posts, Projects, and Logs are automatically indexed from their respective .json and .piml files in the public/ directory.
- Manual: Static pages and custom commands must be manually added to the staticRoutes or customCommands lists in src/hooks/useSearchableData.js.
3. Modifying Visual Themes (Brutalist vs. Luxe)
Every core component should be Theme-Aware:
- Switcher Components: Components like CommandPalette.jsx, SidePanel.jsx, and GenericModal.jsx act as controllers. They detect fezcodexTheme and render either a BrutalistX or LuxeX variant.
- Universal Styles: Prefer the variant="brutalist" or variant="paper" props for shared components like CustomDropdown to maintain consistency.
4. Global State & Persistence
- Use VisualSettingsContext.jsx for any UI state that needs to survive a page refresh (Invert mode, Theme selection, etc.).
- Use usePersistentState hook to automatically sync your context variables with localStorage.
5. AI-Assisted Content Creation (MCP)
If you are using an AI agent with MCP support:
- Blog Posts: Use the create_blog_post tool provided by the local MCP server. It handles file creation, metadata indexing, and build script execution in one step.
- Verification: Always run npm run lint after AI-generated changes to ensure style compliance.
Github Pages Configuration
- Deploy from a branch.
- Select the gh-pages branch
- Add fezcode.com as the custom domain.
Created by Ahmed Samil Bulbul.