SmolCat is a retro-inspired virtual pet built with React, TypeScript, Vite, and Azure Functions. You can feed, pet, and put your cat to sleep, rename it, switch between pixel-art skins, and chat with it through a Gemini-powered backend that responds based on the cat's current mood and stats.
The project is set up for deployment on Azure Static Web Apps with Google authentication and Azure Table Storage for server-side persistence.
- Retro tamagotchi-style UI with animated pixel cat skins
- Local cat care loop with hunger, happiness, and energy stats
- AI chat powered by Gemini with mood-aware responses
- Persistent browser session IDs for chat continuity
- Google sign-in via Azure Static Web Apps authentication
- Azure Table Storage support for chat history and user session metadata
- Background music and PWA-style static assets
- React 19
- TypeScript
- Vite
- Plain CSS files per component
- Azure Functions v4
- Azure Table Storage via
@azure/data-tables - Google Gemini via
@google/generative-ai
- Azure Static Web Apps
- GitHub Actions CI/CD
The frontend renders a handheld virtual pet interface. Basic interactions like feeding, petting, sleeping, renaming the cat, choosing a skin, and storing the generated session ID happen in the browser.
When the user sends a message, the app posts the current cat stats, session ID, cat name, and user message to /api/chatWithCat. The Azure Function builds a system prompt from the cat's current state, optionally loads recent chat history from Azure Table Storage, sends the conversation to Gemini, and returns a short in-character response.
If the user is authenticated through Static Web Apps, the backend also stores session metadata tied to that identity.
- Frontend stat decay is handled in
src/useCatState.ts - Cat chat is handled by
api/src/functions/chatWithCat.ts - Google auth is configured in
staticwebapp.config.json - Vite proxies
/apirequests to the local Azure Functions host during development - The repo includes
getCatandupdateCatAPI endpoints for authenticated saved state, but the current frontend does not call them yet
That last point matters: today, cat stats are not restored from the backend on refresh. Name, skin, and session ID are stored in localStorage; the main pet stats currently live in frontend state during the session.
SmolCat/
|-- src/ # React frontend
| |-- App.tsx
| |-- TamagotchiContainer.tsx
| |-- useCatState.ts
| |-- PixelCat.tsx
| |-- BackgroundMusic.tsx
| `-- ...
|-- public/ # Static assets
|-- api/
| |-- src/functions/
| | |-- chatWithCat.ts
| | |-- getCat.ts
| | `-- updateCat.ts
| |-- host.json
| `-- package.json
|-- .github/workflows/ # Static Web Apps deploy pipeline
|-- staticwebapp.config.json # Auth and route rewrites
`-- package.json
Install these before running locally:
- Node.js 20+ recommended
- npm
- Azure Functions Core Tools v4
- An Azure Storage connection string for API-backed features
- A Gemini API key
Optional for a fuller local Azure experience:
- Azurite for local Table Storage emulation
- Azure Static Web Apps CLI if you want to test auth and frontend/API integration more closely
Root app:
npm installAPI app:
cd api
npm installCreate api/local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "node",
"GEMINI_API_KEY": "your-gemini-api-key"
}
}If you want to test Google auth in Azure Static Web Apps, you'll also need these app settings in Azure:
GOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRET
Those are referenced by staticwebapp.config.json. They are typically not required for basic local frontend development unless you are specifically testing auth flows.
From api/:
npm run build
npm startThe Functions host runs on http://localhost:7071 by default.
From the repo root:
npm run devThe Vite dev server runs on http://localhost:5173 by default and proxies /api/* to the Functions host.
npm run devstarts the Vite dev servernpm run buildbuilds the frontend with TypeScript and Vitenpm run lintruns ESLintnpm run previewpreviews the production frontend build
npm run buildcompiles the Azure Functions TypeScript sourcenpm startstarts the local Azure Functions runtimenpm run watchwatches and recompiles API TypeScript files
GEMINI_API_KEY: used bychatWithCatto generate cat responsesAzureWebJobsStorage: used for Azure Functions storage and Table Storage persistence
GOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRET
Chats with the cat and returns a short AI-generated response.
Example request body:
{
"sessionId": "a-session-id",
"catName": "SmolCat",
"stats": {
"hunger": 42,
"happiness": 81,
"energy": 63
},
"userMessage": "Do you want a snack?"
}Behavior:
- Requires
GEMINI_API_KEY - Loads up to 8 previous chat messages for the same session when storage is configured
- Stores chat history in the
CatChatHistorytable - Stores authenticated session metadata in the
CatSessionstable
Returns authenticated cat state from storage, applying time-based decay since the last update.
Behavior:
- Requires authenticated identity from Static Web Apps headers
- Requires
AzureWebJobsStorage - Reads from the
CatStatestable
Stores authenticated cat state in storage.
Example request body:
{
"hunger": 25,
"happiness": 90,
"lastUpdated": 1760000000000
}Behavior:
- Requires authenticated identity from Static Web Apps headers
- Requires
AzureWebJobsStorage - Upserts into the
CatStatestable
SmolCat is configured for Google login through Azure Static Web Apps auth.
Relevant routes:
/loginrewrites to/.auth/login/google/logoutrewrites to/.auth/logout/.auth/meis used by the frontend to detect the signed-in user
When signed in, the UI shows account information and the backend can associate saved data with the authenticated user.
This repo includes a GitHub Actions workflow in .github/workflows that deploys the frontend and API to Azure Static Web Apps when changes are pushed to main.
Build config used by the workflow:
- App location:
/ - API location:
api - Frontend output:
dist
To deploy successfully, the Static Web App needs the appropriate secrets and app settings configured in Azure.
- The current UI does not yet read from
getCator write toupdateCat - Cat stats reset on refresh because they currently live in client memory
- Auth behavior is easiest to test in Azure Static Web Apps or with a matching local auth setup
- Chat history persistence depends on valid Table Storage configuration
- Wire frontend stats to
getCatandupdateCat - Persist the full pet lifecycle across sessions
- Add richer cat animations and more moods
- Expand AI memory and personality controls
- Add automated tests for frontend state and API handlers