Skip to content

Lumberj3ck/LazyLang

Repository files navigation

LazyLang

A terminal-based language learning app that lets you have conversations with an AI while translating unfamiliar words on the fly — all without leaving the terminal.

screenshot-2026-02-07_16-56-41

Why

When practicing a foreign language through conversation, you constantly run into words you don't know. The usual workflow is: stop what you're doing, open a dictionary in a browser, look up the word, switch back. This context switching breaks your focus and slows you down.

LazyLang solves this by putting the conversation and the dictionary in the same place. You speak, the AI responds in language you speak, and you navigate the response with vim keybindings to translate any word instantly. No tab switching, no copy-pasting — just stay in the flow.

Controls

Key Action
Ctrl+B Start/stop recording
j / k Move focus down/up one line
w / b Move focus to next/previous word
Enter Translate focused word
Esc Stop speech playback
q / Ctrl+C Quit

Requirements

  • OpenAI-compatible API key such as Groq (powers speech recognition, chat, and inline translations)
  • Piper TTS for text-to-speech (included in Docker image)

Configuration

All runtime settings live in config.json inside the project directory. The completion_provider section lets you point LazyLang at any OpenAI-style endpoint and store the auth token alongside it:

{
  "completion_provider": {
    "base_url": "https://api.groq.com/openai/v1",
    "token": "sk-...",
    "model": "openai/gpt-oss-120b"
  }
}

The base_url and model values are mandatory; LazyLang refuses to start until they are provided. If completion_provider.token is omitted, LazyLang falls back to the LLM_API_KEY environment variable (useful when generating the initial config automatically inside Docker). Both conversations and inline translations share this provider configuration, so the model endpoint only needs to be defined once. When base_url points to a localhost or private-network address (perfect for Ollama), tokens are optional; any public endpoint still requires a token.

Set stt_backend.type to local to run Whisper.cpp on-device. In that mode LazyLang ignores API tokens and uses the bundled downloader to fetch the requested .bin model from Hugging Face automatically. When type is hosted, LazyLang defaults to the same completion_provider.base_url/token; you can override the endpoint with stt_backend.url and a matching stt_backend.token when the STT service lives elsewhere.

Running with Docker

Create a .env file with your LLM_API_KEY, then:

docker compose up --build

This starts the app with all dependencies bundled.

To run the app container directly:

docker build -t lazylang .
docker run --env-file .env --name lazylang --rm -it \
  -e PULSE_SERVER=/run/user/1000/pulse/native \
  -v /run/user/1000/pulse:/run/user/1000/pulse \
  -v ~/.config/pulse/cookie:/root/.config/pulse/cookie \
  --group-add $(getent group audio | cut -d: -f3) \
  lazylang

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Open a pull request

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors