Waking the server…
It naps when nobody’s around. Give it a few seconds.
Waking the server…
It naps when nobody’s around. Give it a few seconds.
Case study
A full-stack portfolio site for Demi Taylor Nimmo — Software Engineer. A monorepo with three apps (frontend, backend API, admin CMS), deployed to Vercel with Supabase as the database.

Portfolio is a full-stack portfolio website showcasing Demi Taylor Nimmo's work as a Software Engineer. It's built as a monorepo with three separate applications — each deployed independently to Vercel — connected by a shared backend API backed by Supabase.
The site has five main sections: Homepage (professional introduction), Projects (development work showcase), Learning (current skills and completed courses), Work History (professional experience timeline), and Blog (technical articles and thoughts). An admin CMS allows content management through a React-based interface.
It's designed to be both a professional showcase and a demonstration of full-stack development capability — the site itself is built with the same technologies and architecture patterns used in the projects it showcases.
Most developer portfolios are static sites — pretty but empty. They show work but don't demonstrate how you build things. A portfolio that needs its own content management, blog posts, and project updates shouldn't be harder to maintain than a README file.
How might we build a portfolio that demonstrates full-stack capability while being easy to update and maintain?
The project is structured as an npm monorepo with three packages: frontend (Next.js), backend (Express.js API), and admin (React CMS). Each package has its own build system, dependencies, and deployment target. A root-level package.json orchestrates development (npm run dev starts all three services) and testing (npm test runs tests across all packages).
The backend uses Supabase as the database layer (PostgreSQL in production, SQLite in development). It provides RESTful endpoints for blog posts, projects, work history, and learning records. An admin CMS built with React and TanStack Query provides a content management interface.
Next project
LunaLore Platform

Professional introduction with animated sections, skills overview, and project highlights. Uses Framer Motion for scroll-triggered animations.
Showcase of development work with descriptions, tech stacks, and links to case studies. Includes Ingle (local-first AI coding assistant), InfinityTracker (project management), AetherHub (gaming voice chat), and others.
Professional experience timeline with company names, roles, dates, and descriptions. Demonstrates career progression.
Technical articles and thoughts rendered from Markdown using react-markdown. Supports GFM (GitHub Flavored Markdown) with tables, code blocks, and task lists.
React-based content management system for editing projects, work history, learning records, and blog posts. Uses TanStack Query for data fetching and caching. JWT authentication for security.
Express.js REST API with Supabase integration. Endpoints for all content types (projects, work history, learning, blog posts). Rate limiting, input validation, and security headers.
Automated GitHub Actions workflow pings the Supabase free-tier database every 3 days to prevent it from sleeping. Uses a lightweight /api/keepalive endpoint that queries the blog_posts table.
Each Vercel project uses ignoreCommand to only trigger builds when relevant files change. Saves build minutes and prevents unnecessary deployments.
Challenge
npm workspaces with a root-level package.json that orchestrates everything. npm run dev starts all three services concurrently using concurrently. npm test runs tests across all packages. Each package has its own build script and can be built independently. The monorepo structure keeps everything in one place while respecting each technology's requirements.
Challenge
A GitHub Actions workflow (keep-database-alive.yml) that runs every 3 days at 2 AM UTC. It pings a lightweight /api/keepalive endpoint on the backend, which performs a simple SELECT COUNT(*) FROM blog_posts query. The workflow uses GitHub's free tier for scheduled runs, keeping the database active at zero cost.
Challenge
A minimal React-based admin CMS built with Vite (not Next.js) for faster builds. It uses TanStack Query for data fetching and caching, react-markdown for content preview, and JWT authentication for security. The admin panel provides CRUD operations for projects, work history, learning records, and blog posts — nothing more. No database visualisation, no user management, no role-based access control beyond basic JWT auth.
Challenge
Each Vercel project uses an ignoreCommand in its vercel.json configuration that only triggers builds when relevant files change. The frontend deploys only when packages/frontend/ or shared files change; the backend deploys only when packages/backend/ or shared files change; the admin deploys only when packages/admin/ or shared files change. This saves build minutes and prevents unnecessary deployments.
Challenge
Each package has its own unit test runner (Vitest for frontend and admin, Jest for backend). E2E tests use Cypress with Cucumber BDD preprocessor for acceptance tests. Feature files cover key user flows: homepage rendering, admin login, blog posts, and admin CRUD operations. The root-level package.json has a test:e2e script that runs all Cypress tests in one command.
3 Apps
Frontend (Next.js), Backend (Express.js), Admin CMS (Vite)
3 Vercel deployments
demitaylornimmo.com, api.demitaylornimmo.com, admin.demitaylornimmo.com
Supabase database
PostgreSQL production, SQLite development, free-tier keep-alive system
E2E testing
Cypress with Cucumber BDD preprocessor
Conditional deploy's
Each Vercel project only builds when relevant files change
ignoreCommand is essential. It prevents unnecessary rebuilds and speeds up the feedback loop.