Generate a brand-new interactive experience with every click. This project uses AI to create unique, interactive web pages and games on demand—no two generations are ever the same.
Live Demo: non-deterministic-website.onrender.com
Non-Deterministic Website is an experimental platform that leverages large language models (LLMs) to generate interactive web experiences in real-time. Each generation produces something unique:
- Interactive games with canvas animations, player controls, and game loops
- Complete web pages with layouts, styling, and interactive elements
- Dynamic content that adapts to user prompts or generates creative themes automatically
The system ensures variety through Vision-Grounded Prompting: a multimodal design reference (Design Matrix) guides the LLM to choose between Professional, Playful, Brutalist, or Cozy aesthetics based on the theme. To maximize throughput, we use Burst Streaming Generation: a single request to Gemini generates 20 distinct websites in a stream, multiplying daily capacity within API limits. An Interactive-First hierarchy ensures that the generated app is always the centerpiece, minimizing scrolling and maximizing immediate engagement.
Landing Page |
Generated Website |
Generated Website |
Generated Website |
Generated Website |
Generated Website |
Generated Website |
Generated Website |
Generated Website |
graph TD
A[User Clicks Generate] --> B[Frontend App]
B --> C{Check Prefetch Queue}
C -->|Available| D[Return Cached Result]
C -->|Empty| E[Request New Generation]
E --> F[FastAPI Backend]
F --> G[LLM Orchestrator]
G --> H{Try Gemini}
H -->|Vision Input| H2[Design Matrix Image]
H2 --> I[Receive JSON Response]
H -->|Fail| J{Try OpenRouter}
J -->|Success| I
J -->|Fail| K[Fallback to Groq API]
K --> I
I --> L[Normalize & Validate]
K --> L{Compliance Review}
L -->|Pass/Corrected| M{Check Deduplication}
L -->|Rejected| E
M -->|Unique| N[Render in Browser]
M -->|Duplicate| E
N --> O[Show Generated Experience]
O --> P[Burst Refills Queue]
P --> C
D --> N
subgraph Burst Generation
P1[Request 20-Site Batch]
P2[Streaming JSON Parser]
P3[Enqueue Site #1]
P4[Enqueue Sites #2-#20]
P1 --> P2
P2 -->|Site 1 Complete| P3
P2 -->|More Sites Complete| P4
end
P ---> P1
style A fill:#e1f5ff
style O fill:#d4edda
style L fill:#ffeaa7
style M fill:#fff3cd
style H fill:#f8d7da
style H2 fill:#e1f5ff
| Component | Location | Purpose |
|---|---|---|
| Frontend UI | templates/index.htmlstatic/ts-src/app.ts |
Landing page, generation controls, rendering engine |
| NDW Runtime | static/ts-src/ndw.ts |
Custom JavaScript runtime for games: loop(dt), input handling, canvas helpers, RNG |
| API Backend | api/main.py |
FastAPI server exposing /generate, /metrics, /prefetch endpoints |
| LLM Client | api/llm_client.py |
Orchestrates Gemini Burst generation with OpenRouter and Groq fallbacks. |
| Prefetch Engine | api/prefetch.py |
Background queue that pre-generates experiences for instant delivery using a streaming parser. |
| Deduplication | api/dedupe.py |
Content fingerprinting to prevent near-identical outputs |
| Validators | api/validators.py |
JSON schema validation and normalization |
| Compliance Reviewer (optional) | api/llm_client.py |
Calls Gemini to audit or auto-fix generations before serving and caches reviewer notes |
| Node.js Tooling | package.json, static/ts-src/ |
Tailwind + TypeScript build pipeline for frontend assets |
- Python 3.9+
- Node.js 16+
- API keys for Groq and/or OpenRouter
-
Clone the repository
git clone https://github.com/lesprgm/non-deterministic-website.git cd non-deterministic-website -
Set up Python environment
python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate pip install -r requirements.txt
-
Install Node dependencies
npm install
-
Configure API keys
Create a
.envfile in the project root:GROQ_API_KEY=your_groq_api_key_here OPENROUTER_API_KEY=your_openrouter_api_key_here
-
Build frontend assets
npm run build
-
Start the server
uvicorn api.main:app --reload
-
Open your browser
Navigate to
http://localhost:8000and click "Generate" to create your first experience!
For active development with auto-reloading:
# Terminal 1: Watch and rebuild TypeScript + CSS
npm run watch
# Terminal 2: Run FastAPI with hot reload
uvicorn api.main:app --reload- Visit the landing page at
http://localhost:8000 - Click "Generate" to create a random interactive experience
- Interact with the result - click, drag, use arrow keys, etc.
- Generate again to get something completely different!
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Landing page with generation controls |
/generate |
POST | Generate a new experience (returns JSON or HTML) |
/generate/stream |
POST | Streaming generation with progress updates |
/metrics/total |
GET | Count of total generated experiences |
/prefetch/status |
GET | Check prefetch queue status |
/prefetch/fill |
POST | Manually refill prefetch queue |
/llm/status |
GET | LLM provider configuration and status |
/llm/probe |
GET | Test LLM provider connectivity |
Configure behavior via environment variables:
| Variable | Description | Default |
|---|---|---|
GROQ_API_KEY |
Groq API authentication key | (required) |
GROQ_MODEL |
Primary Groq model | openai/gpt-oss-120b |
GROQ_FALLBACK_MODEL |
Backup model if primary fails | qwen/qwen3-32b |
GROQ_MAX_TOKENS |
Max output tokens for Groq | 15000 |
OPENROUTER_API_KEY |
OpenRouter API key (primary) | (required for production) |
OPENROUTER_MODEL |
Primary OpenRouter model | z-ai/glm-4.7-flash |
OPENROUTER_FALLBACK_MODEL_1 |
First OpenRouter fallback | google/gemini-2.0-flash-exp:free |
OPENROUTER_FALLBACK_MODEL_2 |
Second OpenRouter fallback | deepseek/deepseek-chat-v3.1:free |
FORCE_OPENROUTER_ONLY |
Force skipping Groq fallback | false |
LLM_TIMEOUT_SECS |
Request timeout in seconds | 75 |
GEMINI_GENERATION_MODEL |
Primary Gemini generation model | gemini-3-flash-preview |
GEMINI_REVIEW_ENABLED |
Enable Gemini-based compliance review | true |
GEMINI_API_KEY |
Google AI Studio API key | (optional) |
GEMINI_REVIEW_MODEL |
Gemini reviewer model slug | gemini-3-flash-preview |
OPENROUTER_REVIEW_MODEL |
OpenRouter compliance fallback model | openai/gpt-5-nano |
| Variable | Description | Default |
|---|---|---|
PREFETCH_ENABLED |
Enable background prefetch | true |
PREFETCH_DIR |
Directory for cached generations | cache/prefetch |
PREFETCH_LOW_WATER |
Queue size to trigger refill | 15 |
PREFETCH_FILL_TO |
Target queue size after refill | 20 |
DEDUPE_ENABLED |
Enable duplicate detection | true |
DEDUPE_RECENT_FILE |
Deduplication database file | cache/seen_pages.json |
PREFETCH_REVIEW_BATCH |
Number of items reviewed per batch during prefetch filling/top-up | 20 |
PREFETCH_PREWARM_COUNT |
Number of docs to generate before startup | 0 |
Prefetched experiences are saved as JSON files in cache/prefetch. Every /generate
request—regardless of which user triggers it—consumes the oldest entry before calling the
LLM again. That means each prefetched page only costs one model invocation, and whichever
user arrives next gets the cached experience until the queue empties.
| Variable | Description | Default |
|---|---|---|
ALLOW_OFFLINE_GENERATION |
Use stub generation (no LLM) for testing | false |
ALLOW_ORIGINS |
CORS allowed origins (comma-separated) | * |
Run the full test suite:
pytestRun specific test categories:
# Test LLM generation and prompt engineering
pytest tests/test_llm_generation.py
# Test frontend rendering
pytest tests/test_snippet_render_dom.py
# Test prefetch system
pytest tests/test_prefetch.py
# Test with coverage
pytest --cov=api --cov-report=htmlThe test suite includes 70+ tests covering:
- Prompt engineering and LLM response validation
- NDW runtime behavior and safety checks
- Schema normalization and validation
- Deduplication logic
- Prefetch queue management
- API endpoint behavior
- Frontend rendering (full HTML and NDW snippets)
- Gemini compliance reviewer integration (when enabled)
This project includes a render.yaml blueprint for one-click deployment:
-
Push to GitHub
git push origin main
-
Create Render Service
- Go to Render Dashboard
- Click New > Blueprint
- Connect your GitHub repository
- Render will detect
render.yamlautomatically
-
Configure Environment Variables
Add these in the Render dashboard under "Environment":
GROQ_API_KEYOPENROUTER_API_KEY(optional)- Any other custom settings from the Configuration section
-
Deploy
Render will automatically:
- Install Python dependencies
- Install Node dependencies
- Build frontend assets with
npm run build - Start the server with Uvicorn
- Auto-deploy on future pushes
For other platforms (Heroku, Railway, Fly.io, etc.):
-
Build step:
pip install -r requirements.txt npm install npm run build
-
Start command:
uvicorn api.main:app --host 0.0.0.0 --port $PORT
Traditional websites show the same content every time. This project explores the opposite: what if every visit generated something new? By leveraging AI, we create:
- Infinite variety - No two generations are identical
- Vision-Grounded Aesthetics - Uses a visual Design Matrix to choose from Professional, Playful, Brutalist, or Cozy vibes
- Interactive-First - Apps are the centerpiece; titles are compact and centered to avoid scroll fatigue
- Creative surprise - Unexpected combinations and themes
- Instant gratification - Prefetching makes it feel instantaneous
-
Two Rendering Modes
- Full HTML pages: Complete standalone experiences
- NDW snippets: Lightweight canvas-based games/visuals using our custom runtime
-
Smart Prefetching
- Background generation keeps a queue ready
- Users get instant results without waiting for LLM latency
- Queue automatically refills in the background
-
Deduplication System
- Content fingerprinting prevents boring repetition
- Recent generations are tracked and rejected if too similar
- Ensures fresh, varied outputs
-
Prompt Engineering
- Category rotation prevents repetitive themes
- Strict JSON schema ensures parseable outputs
- Runtime constraints (use
dtfor timing, proper game loop structure) - Automatic retry with fallback providers
-
Quality Guardrails
- Schema validation catches malformed responses
- Optional compliance review via Gemini API for safety and accessibility checks
- Runtime safety checks (canvas creation, error overlays)
- Comprehensive test coverage
non-deterministic-website/
├── api/ # FastAPI backend
│ ├── main.py # API routes and server
│ ├── llm_client.py # LLM orchestration
│ ├── prefetch.py # Background queue
│ ├── dedupe.py # Duplicate detection
│ └── validators.py # Schema validation
├── static/
│ ├── ts-src/ # TypeScript source
│ │ ├── app.ts # Main frontend logic
│ │ └── ndw.ts # NDW runtime
│ └── ts-build/ # Compiled JavaScript
├── templates/
│ └── index.html # Landing page
├── tests/ # Test suite
├── screenshots/ # Demo images by version
│ ├── v1.5/ # Latest screenshots
│ └── v1/ # Original release screenshots
└── package.json # Node dependencies
This project uses:
- Python: Black formatting, type hints preferred
- TypeScript: ESLint + Prettier
- Tests: pytest with extensive coverage
Format code before committing:
# Format Python
black api/ tests/
# Format TypeScript
npm run format
# Lint TypeScript
npm run lintNode.js powers the asset build workflow. The scripts in package.json run Tailwind’s CLI
(npm run build:css) and the TypeScript compiler (npm run build:ts) to produce
static/tailwind.css and the ES modules in static/ts-build/. During development you can
run npm run watch to keep both pipelines hot. Once those assets exist, the FastAPI server
serves them directly—no Node.js runtime is required in production.
- Groq API Docs: https://console.groq.com/docs
- OpenRouter API Docs: https://openrouter.ai/docs
- FastAPI Documentation: https://fastapi.tiangolo.com/
- Mermaid Diagrams: https://mermaid.js.org/
Contributions welcome! Areas for improvement:
- New prompt engineering techniques
- Additional validation logic
- NDW runtime features (WebGL, audio, etc.)
- Metrics dashboard
- Visual diff testing for generated pages
MIT License - see LICENSE file for details.
Built with ❤️ by Leslie | Report Issues | View Source








