DEV Community

Harshit Sharma
Harshit Sharma

Posted on

Language-Tutor

Hacktoberfest Weekend Challenge: Build for a Friend Submission 🀝

Hacktoberfest 2026: Build for a Friend β€” Submission

What I Built

Language Tutor β€” A local-first AI language tutor that runs entirely in your terminal. Practice 15+ languages with complete privacy β€” all conversations, vocabulary, and progress data stays on your machine in SQLite. Only API calls leave your device for AI inference.

Built for: My friend who wants to learn Spanish privately without subscriptions, data tracking, or cloud sync. They needed something that works offline for review, respects privacy, and costs $0.

Problems solved:

  • βœ… No monthly fees β€” uses NVIDIA's generous free API tier (14,400 req/day)
  • βœ… Works offline β€” review vocab, view progress, export data without internet
  • βœ… Zero data leaves your machine except API prompts β€” SQLite stored locally
  • βœ… Customizable β€” 4 tutor personalities, 6 CEFR levels, 8 AI models
  • βœ… Portable β€” single binary, JSON export/import for backup or sharing

Demo

Terminal Demo (ASCII Recording)

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ πŸ—£οΈ  Language Tutor                    v0.1.0                  β”‚
β”‚ Step 1/3: Setup                                                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ 1. Add API Key                                                    β”‚
β”‚ 2. Pick Language                                                  β”‚
β”‚ 3. Start Chatting                                                 β”‚
β”‚                                                                   β”‚
β”‚ πŸ—£οΈ  Language Tutor                                                β”‚
β”‚ Practice any language with AI β€” 100% private, runs in terminal   β”‚
β”‚                                                                   β”‚
β”‚ Step 1 of 2: Get your free API key                                β”‚
β”‚ 1. Open https://build.nvidia.com in your browser                 β”‚
β”‚ 2. Sign in (Google/GitHub/Email) β€” it's free                     β”‚
β”‚ 3. Click "Get API Key" and copy it                               β”‚
β”‚ 4. Paste it below and press Enter                                 β”‚
β”‚                                                                   β”‚
β”‚ ❯ nvapi-xxxxxxxxxxxxβ–ˆ                                             β”‚
β”‚                                                                   β”‚
β”‚ βœ“ Connected! Press Enter to continue.                             β”‚
β”‚ Your key is saved locally. Only used for AI responses.           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ πŸ—£οΈ  Language Tutor                    v0.1.0                  β”‚
β”‚ Step 2/3: Chat                                                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ πŸ’¬ Chat                                          Spanish β”‚ encouraging β”‚ A1 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ You                                                         β”‚ β”‚
β”‚ β”‚ Hola, ΒΏcΓ³mo estΓ‘s?                                          β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ πŸ€– Tutor                                                    β”‚ β”‚
β”‚ β”‚ Β‘Hola! Estoy muy bien, gracias por preguntar. ΒΏY tΓΊ?        β”‚ β”‚
β”‚ β”‚ (Hello! I'm very well, thanks for asking. And you?)         β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ You                                                         β”‚ β”‚
β”‚ β”‚ Estoy bien. Quiero aprender espaΓ±ol para viajar.            β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ πŸ€– Tutor                                                    β”‚ β”‚
β”‚ β”‚ Β‘Excelente! (Excellent!) Viajar es una gran razΓ³n.          β”‚ β”‚
β”‚ β”‚ ΒΏQuΓ© paΓ­ses hispanohablantes quieres visitar?               β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”‚ ❯ Estoy bien. Quiero aprender espaΓ±ol para viajar.β–ˆ             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Ctrl+Shift+H for shortcuts  |  Ctrl+1-5 to navigate  |  Esc for chat β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

Key Features in Action

Feature Demo
Vocabulary Review (SM-2) Ctrl+2 β†’ Grade words with 0/1/3/5 (Again/Hard/Good/Easy)
Scenarios Ctrl+3 β†’ Restaurant, Travel, Interview, Doctor, Emergency + Custom
Progress Dashboard Ctrl+4 β†’ Streaks, heatmap, stats, Ctrl+E export, Ctrl+I import
Settings Ctrl+5 β†’ Model, Personality, Difficulty, API Key, Simple Mode
Help Ctrl+Shift+H β†’ All keyboard shortcuts

Code

Repository: https://github.com/H-sharma63/language-tutor

Project Structure

language-tutor/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts              # CLI entry (Commander.js + TTY check)
β”‚   β”œβ”€β”€ app.tsx               # Main Ink app with screen routing
β”‚   β”œβ”€β”€ screens/
β”‚   β”‚   β”œβ”€β”€ Welcome.tsx       # 3-step onboarding (API β†’ Language β†’ Chat)
β”‚   β”‚   β”œβ”€β”€ Chat.tsx          # Streaming chat with message bubbles
β”‚   β”‚   β”œβ”€β”€ VocabReview.tsx   # SM-2 spaced repetition UI
β”‚   β”‚   β”œβ”€β”€ Scenarios.tsx     # 8 roleplay scenarios + custom
β”‚   β”‚   β”œβ”€β”€ Progress.tsx      # Streaks, stats, heatmap, export/import
β”‚   β”‚   └── Settings.tsx      # 4 tabs: Chat, Learning, Account, Advanced
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ Header.tsx        # Step indicator (like berwapp)
β”‚   β”‚   └── MessageBubble.tsx # User/assistant message rendering
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ llm.ts            # NVIDIA API client (streaming + non-stream)
β”‚   β”‚   β”œβ”€β”€ conversation.ts   # Chat persistence & history
β”‚   β”‚   β”œβ”€β”€ vocabulary.ts     # Vocab CRUD + SM-2 SRS algorithm
β”‚   β”‚   β”œβ”€β”€ progress.ts       # Analytics + JSON export/import
β”‚   β”‚   └── prompts.ts        # System prompt builder (personalities + CEFR)
β”‚   └── utils/
β”‚       β”œβ”€β”€ db.ts             # SQLite + schema (7 tables, WAL mode)
β”‚       └── paths.ts          # Cross-platform data directories
β”œβ”€β”€ templates/prompts/        # 15 language-specific system prompts
β”œβ”€β”€ dist/                     # Built output (single ESM file)
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ tsup.config.ts
β”œβ”€β”€ README.md
β”œβ”€β”€ ARCHITECTURE.md
β”œβ”€β”€ PLAN.md
└── TRACKER.md
Enter fullscreen mode Exit fullscreen mode

Installation & Run

# Clone
git clone <your-repo-url>
cd language-tutor

# Install & build
npm install
npm run build

# Run
node dist/index.js
# or after npm publish:
npx language-tutor
Enter fullscreen mode Exit fullscreen mode

Tech Stack

Layer Technology
TUI Framework Ink 5.x (React for CLI)
CLI Parser Commander.js 12.x
Database better-sqlite3 11.x (WAL mode)
AI API NVIDIA (Nemotron, Llama 3.1, Mistral, Gemma, Phi)
Streaming Native fetch + SSE
Build tsup 8.x (ESM, Node 18+)
Language TypeScript 5.x (strict)

How I Built It

Open-Source AI Used

NVIDIA's Free API Tier β€” 8 open-weight models hosted free:

  • nvidia/nemotron-3.5-lightning-30b-a3b (default, fast)
  • meta/llama-3.1-8b-instruct / 70b / 405b-instruct
  • mistralai/mistral-large-2-instruct / mistral-nemo-12b-instruct
  • google/gemma-2-9b-it
  • microsoft/phi-3.5-mini-instruct

No local inference needed β€” runs on any machine with Node.js 18+ and internet for chat.

Architecture Highlights

  1. Local-First by Default β€” SQLite with WAL mode stores everything: conversations, messages, vocabulary, SRS state, daily progress, settings. Zero cloud sync.

  2. Streaming TUI β€” Ink (React for terminals) renders tokens in real-time via async generators consuming NVIDIA's SSE stream.

  3. SM-2 Spaced Repetition β€” Implemented from scratch in vocabulary.ts:

   // Ease factor update: EF' = EF + (0.1 - (5-q)*(0.08 + (5-q)*0.02))
   // Interval: 1, 6, then EF * previous_interval
Enter fullscreen mode Exit fullscreen mode
  1. Language-Specific Prompts β€” 15 .md templates in templates/prompts/ with:

    • Strict language enforcement ("IMPORTANT: Always respond in Spanish")
    • Common learner mistakes per language
    • Cultural context (formal/informal address, regional variations)
  2. Privacy-First Data Export β€” Full JSON round-trip for backup, machine transfer, or sharing with a friend.


Why Does Open Innovation Matter?

Open-weight models + free hosting = Democratized AI access.

Without NVIDIA's free tier (and similar offerings from Groq, OpenRouter, Together AI):

  • This project would need a $2,000+ GPU for local inference
  • Or $20+/month for commercial APIs (OpenAI, Anthropic)
  • My friend couldn't afford either

What open innovation made possible:

  • βœ… Zero cost to run β€” 14,400 free requests/day covers heavy daily use
  • βœ… Model choice β€” Switch between 8 models for speed vs quality
  • βœ… No vendor lock-in β€” Swap API endpoint in one file
  • βœ… Community-driven β€” Prompt templates are plain Markdown, anyone can contribute a language
  • βœ… Transparency β€” You know exactly what data leaves your machine (just the chat context)

Closed APIs would have meant: Usage limits, billing surprises, data retention policies, and no offline capability.


My Agent Session

This project was built with Claude Code (Anthropic's CLI agent). The development session included:

  • Project planning & architecture (PLAN.md, ARCHITECTURE.md)
  • Daily progress tracking (TRACKER.md)
  • Full implementation across 4 days
  • TypeScript strict-mode fixes
  • 15 language prompt templates
  • Build verification

Agent session available via DevRelay if needed for judging.


Submission Checklist

  • βœ… Working demo β€” node dist/index.js launches TUI immediately
  • βœ… Privacy-first β€” All data in local SQLite (%APPDATA%/language-tutor/)
  • βœ… Free to run β€” NVIDIA free tier, no subscriptions
  • βœ… Offline-capable β€” Vocab review, progress, export work without internet
  • βœ… 15 languages β€” ES, FR, DE, IT, PT, JA, KO, ZH, RU, AR, HI, TR, NL, PL, SV
  • βœ… 8 AI models β€” Llama, Mistral, Gemma, Phi, Nemotron via NVIDIA
  • βœ… SM-2 SRS β€” Proven spaced repetition algorithm
  • βœ… Export/Import β€” Full JSON portability
  • βœ… Keyboard-driven β€” Ctrl+1-5, Esc, Ctrl+Shift+H, no mouse needed
  • βœ… Simple Mode β€” Beginner-friendly (Chat + Vocab only)
  • βœ… Builds clean β€” npm run build β†’ single ESM file, no TypeScript errors
  • βœ… MIT License β€” In package.json
  • βœ… README + Docs β€” Complete usage guide

Built with ❀️ for language learners everywhere β€” especially the friend who inspired this.

Hacktoberfest 2026 β€’ Build for a Friend β€’ Local-First AI

Top comments (0)