A minimal terminal chat client for OpenAI-compatible APIs, written in Go.
Opening a browser, navigating to ChatGPT or Claude, waiting for the page to load—it all takes time. When you just need a quick answer or want to iterate on an idea, that friction adds up.
Chatty eliminates that friction. It's a terminal-based AI chat client that launches instantly and gets you chatting with AI in milliseconds, not seconds. No Electron, no bloat—just a simple binary that starts instantly and streams responses in real-time. The name emphasizes the TTY (teletypewriter) interface—your terminal.
- Starts instantly - Compiled Go binary with minimal dependencies
- Streams responses - See the text as it arrives, not after the full response
- Renders markdown - Code blocks with syntax highlighting, formatted text
- Supports reasoning models - Detects and dims thinking tags (
<think>,<thinking>) - Works anywhere - Any OpenAI-compatible API endpoint
- Simple config - YAML file with environment variable overrides
- Persists sessions - Save and reopen chats with
/listand/load - Shell-like editing - Arrow keys and history recall when running in an interactive terminal
- Small codebase - ~1,650 lines of Go, easy to read and modify
- Go 1.23 or later
- Access to an OpenAI-compatible API endpoint
go install github.com/ZaguanLabs/chatty/cmd/chatty@latestAlternatively, clone the repository and build locally:
git clone https://github.com/ZaguanLabs/chatty.git
cd chatty
go build ./cmd/chattyOr use the provided Makefile for convenience:
git clone https://github.com/ZaguanLabs/chatty.git
cd chatty
make buildChatty works with any OpenAI-compatible API provider. Create config.yaml in the project root or pass --config to specify a path.
Zaguán provides access to multiple AI models through a unified API:
api:
url: "https://api.zaguanai.com/v1"
key: "${CHATTY_API_KEY}"
model:
name: "openai/gpt-4o-mini"
temperature: 0.7
stream: trueapi:
url: "https://api.openai.com/v1"
key: "${OPENAI_API_KEY}"
model:
name: "gpt-4o-mini"
temperature: 0.7
stream: trueChatty works with any OpenAI-compatible API. Examples:
xAI (Grok):
api:
url: "https://api.x.ai/v1"
key: "${XAI_API_KEY}"
model:
name: "grok-beta"
temperature: 0.7
stream: trueAnthropic (Direct API):
api:
url: "https://api.anthropic.com/v1"
key: "${ANTHROPIC_API_KEY}"
model:
name: "claude-3-5-sonnet-20241022"
temperature: 0.7
stream: trueLocal models (Ollama, LM Studio, etc.):
api:
url: "http://localhost:11434/v1"
key: "not-needed"
model:
name: "llama3.2"
temperature: 0.7
stream: trueEnvironment variables override config file values:
CHATTY_API_URL- Override the API endpointCHATTY_API_KEYor provider-specific keys (e.g.,OPENAI_API_KEY,ANTHROPIC_API_KEY) - Override the API key
# Build with version info
make build
# Run
./chatty
# Or build and run directly
make runChatty supports both interactive TUI mode and direct CLI mode:
Once running in interactive mode, you can use these commands:
/help- Show available commands/exitor/quit- Exit the chat/resetor/clear- Clear conversation history/history- Show conversation history/markdown- Toggle markdown rendering on/off/listor/sessions- List saved conversations/load <id>- Load a saved conversation by its numeric id
You can also use commands directly from the command line:
./chatty /help- Show CLI help./chatty /list- List saved conversations./chatty /load <id>- Load and display a saved conversation./chatty "Your question here"- Ask a question directly and get the response
CLI mode is useful for scripting or when you need a quick answer without entering the interactive session.
Chatty follows a lean, modular layout:
chatty/
├── cmd/chatty/
│ └── main.go # CLI entrypoint & bootstrap (~70 lines)
├── internal/
│ ├── chat.go # Chat loop, commands, streaming (~670 lines)
│ ├── client.go # OpenAI-compatible HTTP client (~230 lines)
│ ├── storage/
│ │ └── storage.go # SQLite persistence layer (~320 lines)
│ └── config/
│ └── config.go # Config loading & validation (~140 lines)
├── config.yaml # Sample configuration
└── go.mod # Module definition
Total: ~1,650 lines of Go code (tests included)
- Run tests:
make test - Build:
make build - Install:
make install - Format:
go fmt ./...
Build for all supported platforms:
make build-allOr build for specific platforms:
make build-linux # Linux amd64 and arm64
make build-macos # macOS arm64
make build-windows # Windows amd64 and arm64Binaries are created in the dist/ directory with platform-specific names:
chatty-linux-amd64chatty-linux-arm64chatty-macos-arm64chatty-windows-amd64.exechatty-windows-arm64.exe
For production releases with optimized, stripped binaries (~28% smaller):
make build-releaseThis creates stripped binaries (using -ldflags="-s -w") that are smaller and suitable for distribution.
Use the interactive release command:
make releaseThis will:
- Run all tests
- Prompt for documentation updates
- Validate version format
- Create an annotated git tag
- Show instructions for pushing
Then push the tag to trigger the automated release:
git push origin v0.x.xAlternatively, use make tag to skip the test/checklist steps.
The GitHub Actions workflow will automatically:
- Build stripped binaries for all platforms
- Create release archives (
.tar.gzfor Unix,.zipfor Windows) - Include
LICENSE,README.md, andconfig.example.yamlin each archive - Generate SHA256 checksums
- Create a GitHub release with all artifacts
Released under the MIT License, which allows you to use, modify, and distribute the code in commercial or personal projects as long as you include the original copyright notice and license text.