A beautiful, interactive web app that helps you discover the origins and roots of words. Perfect for vocabulary enthusiasts who want to understand words deeply through their etymological roots.
Try it out at etymology.thepushkarp.com
- Etymology Lookup: Search any word to discover its linguistic origins, root morphemes, and historical evolution
- Memorable Lore: Each word comes with a 2-3 sentence narrative that makes the etymology stick
- Related Words: Discover words that share the same roots
- Multiple LLM Providers: Choose between Anthropic (Claude) or OpenRouter for flexibility
- Dynamic Model Selection: Automatically fetches available models from Anthropic API
- Search History: Track your vocabulary exploration with a persistent sidebar
- Surprise Me: Discover random words to expand your vocabulary
- Structured Outputs: Guaranteed valid JSON responses using constrained decoding
- Node.js 18+
- An API key from either:
- Anthropic (recommended)
- OpenRouter
# Clone the repository
git clone https://github.com/thepushkarp/etymology-explorer.git
cd etymology-explorer
# Install dependencies
yarn install
# Start the development server
yarn devOpen http://localhost:3000 in your browser.
- Click the Settings button (bottom-right corner)
- Choose your LLM provider:
- Paste your Anthropic API key
- Select a model from the dropdown (auto-populated from API)
- Default: Claude Haiku 4.5 (fast and cost-effective)
- Toggle to "OpenRouter"
- Enter a model ID (e.g.,
anthropic/claude-3.5-sonnet,openai/gpt-4o) - Paste your OpenRouter API key
Your settings are stored locally in your browser and never sent to any server.
- Framework: Next.js 16 with App Router
- UI: React 19 + Tailwind CSS v4
- LLM: Anthropic SDK with structured outputs
- Data Sources: Etymonline + Wiktionary
- Typography: Libre Baskerville (serif)
etymology-explorer/
├── app/
│ ├── api/
│ │ ├── etymology/ # Main etymology synthesis endpoint
│ │ ├── models/ # Fetch available Anthropic models
│ │ ├── random-word/ # Random word selection
│ │ └── suggestions/ # Typo correction suggestions
│ ├── layout.tsx # Root layout with fonts
│ └── page.tsx # Main page with search UI
├── components/
│ ├── EtymologyCard.tsx # Main result display
│ ├── HistorySidebar.tsx # Search history panel
│ ├── RootChip.tsx # Expandable root morpheme
│ ├── SearchBar.tsx # Word input
│ ├── SettingsModal.tsx # LLM configuration
│ └── SurpriseButton.tsx # Random word button
├── lib/
│ ├── claude.ts # LLM synthesis with structured outputs
│ ├── etymonline.ts # Etymonline scraper
│ ├── wiktionary.ts # Wiktionary API client
│ ├── prompts.ts # System prompts and schemas
│ ├── types.ts # TypeScript interfaces
│ └── hooks/ # React hooks (localStorage, history)
└── data/
└── gre-words.json # Vocabulary word list
| Endpoint | Method | Description |
|---|---|---|
/api/etymology |
POST | Synthesize etymology for a word |
/api/models |
POST | Fetch available Anthropic models |
/api/suggestions |
GET | Get typo correction suggestions |
/api/random-word |
GET | Get a random word |
- Data Fetching: When you search a word, the app fetches data from Etymonline (web scraping) and Wiktionary (MediaWiki API) in parallel
- LLM Synthesis: The raw data is sent to your chosen LLM with a structured output schema
- Guaranteed JSON: Using constrained decoding, the LLM produces valid JSON matching the exact schema
- Rich Display: The etymology is rendered with expandable roots, related words, and source attribution
# Run development server
yarn dev
# Lint code
yarn lint
# Format code
yarn format
# Build for production
yarn buildDeploy easily on Vercel:
MIT
- Etymology data from Etymonline and Wiktionary
- Powered by Claude from Anthropic