This is a submission for Weekend Challenge: Passion Edition
What I Built
Rivalry Generator is a highly polished, modern web application that generates dramatic, cinematic, and humorous AI-powered rivalry reports between any two competitors. Compare superheroes, food toppings, code style preferences, or historical figures in a premium cosmic interface.
Key Features
- ⚔️ Dynamic Clash Reports: Enter any two competitors and their combat domain to generate a dramatic narrative charting their legendary struggle.
- 📊 Hypothetical Battle Metrics: Generates a side-by-side comparison of 3 category-specific attributes (e.g., Speed, Charisma, Luck) out of 100 with witty explanations.
- 🤝 Forced Alliance Scenarios: Highlights a bizarre hypothetical scenario where the two competitors must team up to defeat an absurd, larger threat.
- 🖼️ Downloadable Posters: Download high-quality, high-resolution PNG posters of generated matchup cards locally (using
html-to-image) to share on social media. - 🔊 Interactive Synthesized Sound Effects: Custom sci-fi audio effects built using the browser's Web Audio API for clicks, charging states, success chords, and errors. Includes a global mute toggle.
- 📜 Local Clash History: Keeps track of your last 10 showdowns in LocalStorage, allowing instant click-to-load without re-calling the API.
- 🎲 Surprise Me Selector: Suggests random, pre-configured matchups (e.g., Tabs vs. Spaces, Cats vs. Dogs) across diverse categories to get users started instantly.
- 🔒 Security Scanning Pre-Build: Pre-build script that scans the codebase for secrets (API keys) and aborts compilation/commits if keys are accidentally exposed.
Screenshots / Videos
Below is a sneak peek at the cosmic user interface:
Main Interface
Code
The entire source code is fully open-source and available on GitHub:
scha54
/
rivalry-generator
This is a rivalry generator application created for the Dev.To Weekend Challenge
⚔️ Rivalry Generator - AI-Powered Clash Analysis
A highly polished, modern web application that generates dramatic, cinematic, and humorous AI-powered rivalry reports between any two competitors. Compare superheroes, food toppings, code style preferences, or historical figures in a premium cosmic interface.
✨ Features
- Cosmic Dark-Mode Aesthetics: Premium dark navy/purple gradient background with glassmorphic cards, custom scrollbars, and pulsing loading animations.
- Hypothetical Battle Metrics: Generates a side-by-side comparison of 3 category-specific attributes (e.g. Speed, Charisma, Luck) out of 100 with witty explanations.
- Forced Alliance Scenario: Highlights a bizarre hypothetical scenario where the two competitors must team up to defeat an absurd, larger threat.
-
Downloadable Posters: Download high-quality, high-resolution PNG posters of generated matchup cards locally (using
html-to-image). - Interactive Sound Effects: Custom synthesized audio effects built using the browser's Web Audio API for clicks, charging state builds, success chords, and errors. Includes a mute toggle.
- Local…
Includes automated test suites for input validation and the pre-build secret scanning tool.
How I Built It
The architecture was designed from the ground up to be secure, fast, and feature-rich, combining a solid Express backend proxy with a responsive React frontend.
1. Robust and Secure Backend
To prevent exposing API keys in the client's browser, the application uses an Express.js backend proxy (server.js). The server:
- Sanitizes and validates inputs (restricting names to 50 characters, ensuring competitors are different).
- Resolves the API key from environment variables or respects a user's custom key passed via the
x-api-keyheader (saved in the client's LocalStorage). - Integrates with the
@google/generative-aiSDK usinggemini-2.5-flash.
2. Synthesized Soundscapes with the Web Audio API
To avoid downloading heavy MP3/WAV assets and speed up page load times, I built a custom audio engine from scratch using the browser's native Web Audio API (src/utils/audio.js):
- Click Plucks: A clean triangle wave starting at 440Hz ramping exponentially to 880Hz over 150ms.
- Charging Rumble: A sawtooth wave that starts at a low bass rumble (80Hz) and ramps up to 400Hz over 4.5 seconds. I also wired a low-pass filter and an LFO (low-frequency oscillator) set to 8Hz to create a pulsing sci-fi vibrato effect.
- Success Chords: An arpeggiated major chord (C4, E4, G4, C5) synthesized using sine waves with precise delay envelopes to produce a glittering victory sound.
- Error Buzz: A descending sawtooth wave from 220Hz down to 100Hz with a lowpass filter sweep.
3. Cosmic Glassmorphism UI
The user interface is built with Vite and React 19 styled entirely with vanilla CSS. The design system uses custom CSS properties (variables), high-contrast gradients, deep indigo backdrops, and glassmorphic cards (backdrop-filter: blur()).
For sharing, we implemented a custom poster exporter using the html-to-image package. When a user clicks "Download Poster", the application grabs the DOM node of the battle card, configures high-pixel-ratio options, and exports a high-resolution PNG on-the-fly. This is paired with a celebratory burst of canvas-confetti when the generation resolves.
4. Custom Secret Scanner
To ensure developers don't accidentally commit secrets or API keys, I wrote a Node.js script (scripts/check-secrets.js) that runs automatically before Vite bundles the production assets. It recursively scans code files using high-entropy regexes to identify exposed Gemini, Groq, or OpenRouter keys, immediately failing the build if a secret is leaked.
Prize Categories
🌟 Best Use of Google AI
Our application relies completely on Google's Gemini 2.5 Flash model.
The highlight of this integration is the use of the new Structured JSON Output feature. Rather than requesting markdown and writing fragile regex patterns to parse variables (which are prone to breaking), we passed a strict JSON schema configuration (responseSchema) to the @google/generative-ai SDK:
const model = genAI.getGenerativeModel({
model: 'gemini-2.5-flash',
generationConfig: {
responseMimeType: 'application/json',
responseSchema: rivalryResponseSchema, // Strict JSON Schema
temperature: 0.7,
}
});
The model generates formatted JSON containing the story, scores, notes, winner, fun fact, and quote, which our React application immediately parses and binds to components. This guarantees 100% type safety and reliable rendering every single time.

Top comments (0)