Become a polyglot by singing songs
A multilingual song lyrics analysis and pronunciation learning application built with SvelteKit.
- π΅ Lyric Analysis: AI-powered word-by-word translation and phonetic transcription
- π Multi-language Support: English, Chinese (Mandarin), Cantonese, Japanese, Korean, Spanish, French, German, Italian, Portuguese, Russian
- π Text-to-Speech: Click to hear pronunciation of individual words or entire lines
- π€ Multiple AI Providers: Doubao (default), DeepSeek, OpenAI, Anthropic Claude, Google Gemini, Local (Ollama), and custom providers
- π± Responsive Design: Works on desktop and mobile devices
- πΎ History Tracking: Save and revisit your analyzed lyrics
- π― Two-step Analysis: Overall translation + detailed word-by-word breakdown
The application supports two database modes:
- Perfect for local development and testing
- No external dependencies required
- Automatic setup with
npm run db:setup
- Recommended for production deployments
- Compatible with Vercel and other cloud platforms
- Easy setup with Supabase
See docs/SUPABASE_SETUP.md for detailed setup instructions.
# Clone and setup everything automatically
git clone <repository-url>
cd polyglot-singer
./start.shThis will automatically:
- Check and setup environment configuration
- Install dependencies
- Setup database
- Start the development server
git clone <repository-url>
cd polyglot-singer
npm installCopy the environment template:
cp env.example .envEdit .env with your configuration:
# Database (choose one)
DATABASE_TYPE=sqlite # For local development
DATABASE_URL=sqlite:dev.db
# Or for production with Supabase:
# DATABASE_TYPE=postgres
# DATABASE_URL=postgresql://user:password@host:port/database
# AI Provider (Doubao is default)
AI_PROVIDER=doubao
DOUBAO_API_KEY=your_doubao_api_key_here
# Security
SESSION_SECRET=your_random_32_character_secretnpm run db:setupnpm run devVisit http://localhost:5173 to start using the application.
| Command | Description |
|---|---|
./start.sh |
Recommended: Complete setup and start (Shell version) |
npm run start |
Smart startup with environment checks (Node.js version) |
npm run start:shell |
Call shell startup script via npm |
| Command | Description |
|---|---|
npm run env:check |
Check for new environment variables and update .env |
node scripts/check-env.js |
Direct environment check script |
| Command | Description |
|---|---|
npm run db:setup |
Setup database (generate + migrate) |
npm run db:generate |
Generate migrations |
npm run db:migrate |
Apply migrations |
npm run db:studio |
Open Drizzle Studio |
npm run db:reset |
Reset SQLite database (dev only) |
| Command | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Build for production |
npm run preview |
Preview production build |
npm run check |
Type checking |
npm run lint |
Lint code |
npm run format |
Format code |
npm run test |
Run tests |
See docs/SCRIPTS_USAGE.md for detailed script documentation.
The application supports multiple AI providers:
- Doubao (default): ByteDance's high-quality language model
- DeepSeek: Cost-effective and high-quality
- OpenAI: GPT-4 models for premium quality
- Anthropic Claude: Excellent for nuanced translations
- Google Gemini: Fast and reliable
- Local (Ollama): Run models locally for privacy
- Custom: Bring your own OpenAI-compatible API
-
Set up Supabase database (see docs/SUPABASE_SETUP.md)
-
Configure environment variables in Vercel:
DATABASE_TYPE=postgresDATABASE_URL=your_supabase_connection_stringAI_PROVIDER=doubao(or your preferred provider)DOUBAO_API_KEY=your_api_keySESSION_SECRET=random_32_character_string
-
Deploy:
npm run build vercel --prod
The application can be deployed to any platform that supports Node.js and PostgreSQL:
- Railway
- Render
- DigitalOcean App Platform
- Heroku
- AWS/GCP/Azure
src/
βββ lib/
β βββ components/ # Svelte components
β βββ server/
β β βββ database/ # Database schemas and connections
β β βββ services/ # Business logic (AI, auth)
β βββ styles/ # Global styles
β βββ types/ # TypeScript definitions
βββ routes/ # SvelteKit routes
βββ scripts/ # Automation scripts
βββ docs/ # Documentation
βββ app.html # HTML template
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
For issues and questions:
- Check the docs/SUPABASE_SETUP.md for database setup
- Review the environment variables configuration
- See docs/SCRIPTS_USAGE.md for script documentation
- Open an issue on GitHub
Become a polyglot by singing songs
A innovative language learning platform that combines the joy of singing with effective vocabulary acquisition through AI-powered lyric analysis and phonetic annotation.
- User inputs song lyrics in target language
- AI processes lyrics for word-by-word translation and phonetic transcription
- Display formatted lyrics with aligned pronunciation and meaning
- User sings along while learning vocabulary contextually
- Lyric Input Interface: Multi-line text input with language detection
- AI-Powered Analysis:
- Word-level segmentation and tokenization
- Phonetic transcription (IPA or simplified phonetics)
- Contextual translation (meaning within the song context)
- Specialized Display Format:
[phonetic] [phonetic] [phonetic] Original lyrics here [meaning] [meaning] [meaning] - Alignment System: Precise word-to-annotation mapping
- Multi-language Support: Initially focus on popular language pairs
- Song Library: Save and organize processed lyrics
- Learning Progress: Track vocabulary acquisition
- Audio Integration: Optional audio playback synchronization
- Social Features: Share processed lyrics with community
- Performance: Real-time processing for short verses (<5 seconds)
- Accuracy: 95%+ accurate translations and phonetics
- Responsiveness: Mobile-first design for singing practice
- Accessibility: Screen reader compatible, keyboard navigation
SvelteKit Full-Stack App
βββ Frontend (Svelte Components)
βββ API Routes (Server-side)
βββ Database (SQLite/PostgreSQL)
βββ AI Services Integration
- Framework: SvelteKit (Full-stack solution)
- Runtime: Node.js with TypeScript
- Build Tool: Vite (built-in with SvelteKit)
- Package Manager: npm/pnpm
- Deployment: Vercel/Netlify (with adapters)
- UI Components: Svelte 5 with runes
- Styling: Tailwind CSS + Custom CSS Grid for lyric alignment
- State Management: Svelte stores + page data
- Form Handling: SvelteKit form actions
- Real-time Updates: Server-Sent Events (SSE) or WebSockets
- API: SvelteKit server routes (
src/routes/api/) - Database:
- Development: SQLite with better-sqlite3
- Production: PostgreSQL with pg
- ORM: Drizzle ORM (lightweight, TypeScript-first)
- Caching: Built-in SvelteKit caching + Redis for production
- Authentication: Lucia Auth (SvelteKit-optimized)
- Multi-Provider Support: DeepSeek AI, OpenAI GPT, Anthropic Claude, Google Gemini, Local Models (Ollama), Custom Providers
- Dynamic Configuration: Environment-based provider selection with fallback
- Phonetics: Custom phonetic service with IPA libraries
- Language Detection: Browser API + server-side validation
- Processing: Server-side in API routes with streaming responses
.lyric-line {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
gap: 0.5rem;
align-items: center;
}
.word-unit {
display: flex;
flex-direction: column;
text-align: center;
min-width: fit-content;
}- Language detection using AI or langdetect
- Custom tokenization rules per language family
- Handling of contractions, compound words, and particles
// src/routes/api/analyze/+server.ts
import type { RequestHandler } from './$types';
import { analyzeToLyrics } from '$lib/server/services/ai-service';
export const POST: RequestHandler = async ({ request }) => {
const { lyrics, sourceLanguage, targetLanguage } = await request.json();
const analysis = await analyzeToLyrics(lyrics, sourceLanguage, targetLanguage);
return new Response(JSON.stringify(analysis), {
headers: { 'Content-Type': 'application/json' }
});
};
// Type definition
interface LyricAnalysis {
word: string;
phonetic: string;
translation: string;
context: string;
position: { line: number; index: number };
}- SSR for First Load: Server-side render initial page for fast loading
- Progressive Enhancement: JavaScript enhances the experience but isn't required
- Form Actions: Use SvelteKit form actions for reliable form submission
- Streaming: Stream AI responses using SvelteKit's streaming capabilities
- Caching: Leverage SvelteKit's built-in caching mechanisms
- Code Splitting: Automatic route-based code splitting
// src/service-worker.ts
import { build, files, version } from '$service-worker';
// Cache processed lyrics for offline access
const CACHE_NAME = `polyglot-singer-${version}`;
const LYRIC_CACHE = 'lyric-cache-v1';
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll([
'/',
'/analyze',
'/library',
...files // Cache static assets
]);
})
);
});
// Cache processed lyrics when user saves them
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/api/lyrics/')) {
event.respondWith(
caches.open(LYRIC_CACHE).then((cache) => {
return cache.match(event.request).then((response) => {
return response || fetch(event.request).then((fetchResponse) => {
cache.put(event.request, fetchResponse.clone());
return fetchResponse;
});
});
})
);
}
});
// Background sync for saving progress
self.addEventListener('sync', (event) => {
if (event.tag === 'save-progress') {
event.waitUntil(syncProgress());
}
});Offline Benefits for Language Learning:
- Practice Anywhere: Users can practice saved lyrics without internet
- Reduced Data Usage: Cache lyrics to avoid repeated API calls
- Better Focus: No distractions from network issues during practice
- Consistent Experience: Same performance regardless of connection quality
- Full-Stack Solution: No need for separate frontend/backend - everything in one codebase
- File-based Routing: Intuitive project structure that scales well
- Server-Side Rendering: Fast initial page loads crucial for mobile users
- Progressive Enhancement: Works without JavaScript, enhanced with it
- TypeScript First: Better developer experience and fewer runtime errors
- Built-in Performance: Automatic code splitting, optimizations, and caching
- Streaming & Real-time: Perfect for AI response streaming
- Deployment Flexibility: Deploy anywhere with adapters
- Mobile-First: SvelteKit's SSR ensures fast loading on mobile devices
- SEO Friendly: Server-rendered pages for better discoverability
- Offline Capable: Service workers for practicing lyrics without internet
- Cache processed lyrics for offline practice
- Background sync for saving progress when connection returns
- Push notifications for daily practice reminders
- Real-time AI: Stream AI responses as they're generated
- Form Handling: Robust form actions for reliable lyric submission
- Type Safety: End-to-end TypeScript for better code quality
// src/routes/+layout.svelte - Global layout
<script>
import '$lib/styles/global.css';
import Navigation from '$lib/components/Navigation.svelte';
</script>
<Navigation />
<main>
<slot />
</main>
// src/routes/analyze/+page.svelte - Analysis page
<script>
import { enhance } from '$app/forms';
import LyricInput from '$lib/components/LyricInput.svelte';
</script>// src/routes/analyze/+page.server.ts
import type { Actions } from './$types';
import { analyzeToLyrics } from '$lib/server/services/ai-service';
export const actions: Actions = {
analyze: async ({ request }) => {
const data = await request.formData();
const lyrics = data.get('lyrics')?.toString();
if (!lyrics) {
return { error: 'Lyrics are required' };
}
const analysis = await analyzeToLyrics(lyrics);
return { success: true, analysis };
}
};// src/routes/library/+page.server.ts
import type { PageServerLoad } from './$types';
import { getUserSavedLyrics } from '$lib/server/database/lyrics';
export const load: PageServerLoad = async ({ locals }) => {
const user = locals.user;
const savedLyrics = await getUserSavedLyrics(user.id);
return {
savedLyrics
};
};// src/app.d.ts
import type { User } from '$lib/types/user';
declare global {
namespace App {
interface Locals {
user?: User;
}
interface PageData {
user?: User;
}
}
}polyglot-singer/
βββ src/
β βββ routes/ # File-based routing
β β βββ +layout.svelte # Root layout
β β βββ +page.svelte # Home page
β β βββ analyze/
β β β βββ +page.svelte # Lyric analysis page
β β β βββ +page.server.ts # Server-side data loading
β β β βββ +page.ts # Client-side data loading
β β βββ library/
β β β βββ +page.svelte # Saved lyrics library
β β β βββ +page.server.ts
β β βββ api/ # API routes
β β β βββ analyze/
β β β β βββ +server.ts # POST /api/analyze
β β β βββ lyrics/
β β β β βββ +server.ts # CRUD for lyrics
β β β β βββ [id]/
β β β β βββ +server.ts # GET/PUT/DELETE /api/lyrics/[id]
β β β βββ auth/
β β β βββ login/
β β β β βββ +server.ts
β β β βββ register/
β β β βββ +server.ts
β β βββ (auth)/ # Route groups for auth pages
β β βββ login/
β β β βββ +page.svelte
β β βββ register/
β β βββ +page.svelte
β βββ lib/ # Shared utilities and components
β β βββ components/
β β β βββ LyricInput.svelte
β β β βββ LyricDisplay.svelte
β β β βββ WordUnit.svelte
β β β βββ LanguageSelector.svelte
β β β βββ ui/ # Reusable UI components
β β β βββ Button.svelte
β β β βββ Card.svelte
β β β βββ Loading.svelte
β β βββ stores/ # Svelte stores
β β β βββ lyrics.ts
β β β βββ user.ts
β β β βββ preferences.ts
β β βββ server/ # Server-side utilities
β β β βββ database/
β β β β βββ schema.ts # Drizzle schema
β β β β βββ connection.ts
β β β βββ services/
β β β β βββ ai-service.ts
β β β β βββ phonetic-service.ts
β β β β βββ auth-service.ts
β β β βββ utils/
β β β βββ validation.ts
β β β βββ response.ts
β β βββ types/ # TypeScript type definitions
β β β βββ lyric.ts
β β β βββ user.ts
β β β βββ api.ts
β β βββ utils/ # Client/server shared utilities
β β βββ constants.ts
β β βββ formatting.ts
β β βββ validation.ts
β βββ app.html # HTML template
β βββ app.d.ts # App type definitions
β βββ hooks.server.ts # Server hooks (auth, etc.)
βββ static/ # Static assets
β βββ favicon.png
β βββ images/
βββ tests/ # Testing
β βββ unit/
β βββ integration/
βββ drizzle/ # Database migrations
βββ package.json
βββ svelte.config.js # SvelteKit configuration
βββ vite.config.ts # Vite configuration
βββ tailwind.config.js # Tailwind CSS config
βββ drizzle.config.ts # Drizzle ORM config
βββ .env.example # Environment variables template
- Project Setup: Create SvelteKit project with TypeScript, Tailwind CSS
- Core UI Components: LyricInput, LyricDisplay, WordUnit components
- API Routes:
/api/analyzeendpoint for lyric processing - AI Integration: Multi-provider support (DeepSeek, OpenAI, Claude, Gemini, Local)
- Basic Phonetics: Simple phonetic transcription using IPA libraries
- CSS Grid Layout: Perfect word-to-annotation alignment
- Form Actions: Progressive enhancement for lyric submission
- Database Setup: SQLite with Drizzle ORM for development
- Language Support: English β Chinese/Spanish initial implementation
- Authentication: Lucia auth integration with SvelteKit
- User Data: Save and manage personal lyric libraries
- SSR Optimization: Server-side rendering for better performance
- Responsive Design: Mobile-first responsive layout
- Error Handling: Comprehensive error boundaries and user feedback
- Loading States: Skeleton loaders and progress indicators
- Caching Strategy: Cache frequently used translations
- Language Detection: Automatic source language detection
- Production Database: PostgreSQL setup with migrations
- Real-time Processing: Streaming responses using SvelteKit SSE
- Audio Integration: Optional audio playback with lyric synchronization
- Progress Tracking: Learning analytics and vocabulary retention
- Social Features: Share processed lyrics with the community
- Offline Support: Service worker for basic offline functionality
- Advanced Phonetics: More accurate IPA transcription
- Multiple Languages: Support for 10+ language pairs
- Performance Monitoring: Analytics and performance tracking
npx sv create polyglot-singer
npx sv add @tailwindcss/typography drizzle lucia
# Core components and basic API routes# AI integration, database schema, form actions
npm run db:generate && npm run db:migrate
# Deploy to Vercel for testing# Authentication, responsive design, error handling
npm run test # Unit and integration tests# Real-time features, audio integration, analytics
npm run build && npm run preview- Minimal Cognitive Load: Clean, distraction-free interface
- Immediate Feedback: Real-time processing and display
- Flexible Input: Support paste from various sources
- Mobile Optimized: Primary use case is mobile singing practice
- Typography First: Optimized for reading while singing
- Consistent Alignment: Perfect vertical alignment of annotations
- High Contrast: Readable in various lighting conditions
- Responsive Spacing: Adapts to different screen sizes
- User Engagement: Average session duration >10 minutes
- Learning Effectiveness: User-reported vocabulary retention
- Technical Performance: <3s average processing time
- User Satisfaction: >4.5/5 user rating
# Create new SvelteKit project with our template
npx sv create polyglot-singer --template github:forchain/polyglot-singer-template
cd polyglot-singer
# Install dependencies
npm install
# Set up environment variables
cp .env.example .env
# Start development server
npm run dev# Create new SvelteKit project
npx sv create polyglot-singer
cd polyglot-singer
# Add recommended integrations
npx sv add @tailwindcss/forms @tailwindcss/typography
npx sv add lucia # for authentication
npx sv add drizzle # for database
# Install additional dependencies
npm install openai better-sqlite3 @types/better-sqlite3
# Set up environment variables
echo "DEEPSEEK_API_KEY=your_deepseek_api_key_here" > .env
echo "DATABASE_URL=sqlite:dev.db" >> .env
# Start development server
npm run dev# Run database migrations
npm run db:generate && npm run db:migrate
# Run tests
npm run test
# Build for production
npm run build
# Preview production build
npm run previewMIT License - see LICENSE file for details
Made with β€οΈ for language learners and music lovers