j178/chatgpt: A Terminal Front End for the OpenAI Chat API
An elegant interactive CLI for ChatGPT
At a glance
- What is it?
- A Go CLI that wraps GPT-3.5 and GPT-4 in a Bubble Tea interface, keeps conversation history in a local JSON file, and works as a pipe filter. The configuration model is the interesting part, and so is the fact that the README never mentions a licence.
- Who is it for?
- Adopt j178/chatgpt if you already have an OpenAI API key and want a scriptable, keyboard-driven client that keeps its state in two plain JSON files you can edit by hand. Skip it if you need a licence you can point a legal team at, or if you want a provider other than OpenAI today: the README lists Claude, Gemini and Ollama support as under development, not shipped.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 18 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What j178/chatgpt actually is, and who ends up using it
This is a terminal client for the OpenAI Chat Completions API, written in Go. It is not a wrapper around the ChatGPT web product. There is no login flow, no browser session, and no subscription involved: you supply an API key and pay OpenAI per token through your own account. The README's usage section starts by pointing at the API key page and then at an environment variable, which sets the tone for the whole tool.
The audience is narrow and specific. People who live in a terminal and resent switching windows to ask a model a question. People who want to pipe a config file through a model and hand the result to the next command in a shell pipeline. People who want their conversation history in a file they own rather than in a vendor's account. The README's pipeline examples are the clearest statement of intent: a YAML file goes in, JSON comes out, and the output can be piped to `say` for speech.
If you want a graphical chat interface, or you want to use the consumer ChatGPT product without an API key, this is the wrong tool and the README does not pretend otherwise.
How the Go client, the config file and the conversation store fit together
The repository root holds `chatgpt.go`, `config.go`, `conversation.go` and `utils.go`, with the entry point under `cmd/` and the terminal interface under `ui/`. That layout suggests a split between configuration handling, conversation persistence and rendering, which matches what the README documents about the two JSON files.
Configuration is read from `~/.config/chatgpt/config.json`. Conversation history is saved to `~/.config/chatgpt/conversations.json`. The default config carries an `api_key`, an `endpoint` defaulting to `https://api.openai.com/v1`, a `prompts` map of named system prompts, and a `conversation` object with `prompt`, `context_length`, `model`, `temperature`, `stream` and `max_tokens`. The `context_length` key is the one worth pausing on: it controls how many previous exchanges are sent as context, defaulting to 6. The `tokenizer/` directory and the `tiktoken-go` dependency in `go.mod` indicate the project counts tokens locally rather than guessing, though the README does not spell out where that count is used.
The conversation store is more unusual than the config. Each entry in `conversations.json` carries its own `config` block, so a single conversation can use `gpt-4` while another uses `gpt-3.5-turbo`, and the file also holds a `last_idx` pointer to the active conversation. That means switching models is a file edit rather than a flag, which is either convenient or awkward depending on how you feel about hand-editing JSON. The README documents no command-line flag for changing the model per conversation.
Installing j178/chatgpt and running a first prompt
The README offers four install paths. Homebrew covers macOS and Linux, Scoop covers Windows, Nix users can add the package to `environment.systemPackages`, and anyone with a Go toolchain can install from source. If you already have Go, the source route is the least surprising.
go install github.com/j178/chatgpt/cmd/chatgpt@latestThat places a `chatgpt` binary in your Go bin directory. The Homebrew route is the one the README lists first for macOS and Linux:
brew install j178/tap/chatgptOn Windows, the Scoop commands are two steps because the bucket has to be added before the package resolves:
scoop bucket add j178 https://github.com/j178/scoop-bucket.git
scoop install j178/chatgptBefore the first run you need a key. The README uses an environment variable rather than requiring the key to be written into the config file:
export OPENAI_API_KEY=xxxWith that set, running `chatgpt` with no arguments starts the interactive interface. Running it with a named prompt starts in the same interface but with that system prompt selected, so `chatgpt -p translator` opens a session configured as a translator. The pipeline form is where the tool stops looking like a chat client:
cat config.yaml | chatgpt -p 'convert this yaml to json'What you should see is the model's answer on standard output, with no interactive interface, which is what makes the next pipe in the chain possible. The README pairs this with `echo "Hello, world" | chatgpt -p translator | say` as a demonstration. Note that the `-p` flag takes either a prompt name defined in your config or a literal prompt string, and the README uses both forms in its examples.
Keyboard-driven interaction and the key_map override
The interface is built on Bubble Tea and Bubbles, and the README documents an extensive key binding table. The bindings worth knowing before you start: `ctrl+j` toggles between single-line and multi-line input, `ctrl+t` starts a new conversation, `ctrl+x` forgets the current context without deleting the conversation, and `ctrl+r` removes the conversation entirely. The distinction between forgetting context and removing a conversation is a small design decision that matters in practice, since it lets you keep a thread's history on disk while starting the model fresh.
Every one of those bindings is overridable through a `key_map` dictionary in the config file. The README gives a full example mapping, and the keys are named rather than positional: `switch_multiline`, `submit`, `multiline_submit`, `insert_newline`, `multiline_insert_newline`, `help`, `quit`, `copy_last_answer`, `previous_question`, `next_question`, `new_conversation`, `previous_conversation`, `next_conversation`, `remove_conversation`, `forget_context`. Each takes an array of key strings.
This is more configurability than most CLI chat clients offer, and it is also a place where a typo fails quietly. The README does not state what happens when a `key_map` entry names an action that does not exist, or when two actions are bound to the same key. Treat the example mapping as the reference and change one entry at a time.
Where j178/chatgpt falls short
The most concrete limitation is the licence. The repository metadata gives no licence, and the README does not mention one either. For a personal tool that is an inconvenience. For anything inside a company with a dependency review process, it is a blocker, because there is no grant of rights to point at. That is a fact about the repository as it stands, not a prediction.
The second limitation is provider lock-in. The README opens with a note that support for other providers such as Claude, Gemini and Ollama is under development and will be available soon, linking to issue #88. Until that lands, the tool talks to an OpenAI-compatible endpoint and nothing else. The `endpoint` config key means you can point it at a compatible proxy or gateway, but that is not the same as native support for another vendor's API.
Third, the release cadence is uneven. The most recent release listed is v1.3.5 from 2024-06-09, following v1.3.4 in January 2024 and v1.3.3 a day before that. The repository itself has seen a push on 2026-08-29, so work is happening, but the tagged releases are not how that work reaches users. If you install from a release binary rather than from source, you may be running code well behind the default branch. The README does not document a rollback procedure or a version compatibility policy for the config file format, which matters if you hand-edit `conversations.json` and later upgrade.
Finally, the pipeline mode and the interactive mode are different products sharing a binary. Anything you learn about key bindings is irrelevant when you pipe input in, and the streaming behaviour that makes the interactive view pleasant is not something you can rely on in a script.
How it compares to a plain API client
The obvious alternative is not another chat CLI but the OpenAI SDK directly, or a thin wrapper script of your own. The difference in approach is where state lives. A script that calls the API keeps nothing: you construct the message array, send it, print the result, and context management is entirely your problem. j178/chatgpt takes the opposite position. It persists conversations to `~/.config/chatgpt/conversations.json`, tracks the active one with `last_idx`, and applies a `context_length` window automatically.
That trade is real in both directions. You get history you did not have to build, and a keyboard interface you did not have to write. You also get a file format you have to keep valid, a context window chosen by a config value rather than by your code, and a tool whose upgrade path can change the shape of that file. If your use case is a one-shot transformation inside a build script, the SDK is lighter and has no state to corrupt. If your use case is a long-running working session with a model, the persistence is the whole point.
The other comparison worth making is against the ChatGPT web product itself. The web product requires no API key and bills through a subscription; this tool requires a key and bills per token. The README's note about multi-provider support suggests the author sees the CLI as a general front end rather than an OpenAI-specific one, but that is a stated intention, not a shipped feature.
Maintenance, upgrades and what the missing licence means
The repository is not archived. The last push was on 2026-08-29, which is recent enough that the project is not abandoned. The dependency list is actively maintained: `bubbletea` at v1.3.6, `bubbles` at v0.21.0, `glamour` at v0.10.0, and `go-openai` at v1.38.1. The `go.mod` declares `go 1.23.0` with a `go1.24.4` toolchain, so building from source requires a reasonably current Go installation.
Upgrade cost is mostly about the config files. There is no documented migration step between versions, and no changelog beyond release tags. The `conversations.json` schema includes per-conversation config blocks, so a format change would touch saved history. Back that file up before upgrading if the history matters to you. Installing via Homebrew or Scoop moves the upgrade burden to the package manager, which is the lower-effort path; `go install ...@latest` will pick up the default branch, which is ahead of the last tagged release.
On licensing: with no licence file and no licence field, the default position under most copyright regimes is that no rights are granted beyond what the hosting platform's terms allow. That is a statement about the repository, not legal advice. If you need to redistribute the binary, embed it in a product, or pass an internal review, get an actual answer from someone qualified before you build on it.
Editorial conclusion
Adopt j178/chatgpt if you already have an OpenAI API key and want a scriptable, keyboard-driven client that keeps its state in two plain JSON files you can edit by hand. Skip it if you need a licence you can point a legal team at, or if you want a provider other than OpenAI today: the README lists Claude, Gemini and Ollama support as under development, not shipped. Before committing, read config.go and conversation.go in the repository root to confirm the on-disk schema matches the README examples, and verify the release page carries a build for your platform.
Frequently asked questions
How do I install j178/chatgpt on a Mac?
The README lists Homebrew as the macOS and Linux option, using the tap command `brew install j178/tap/chatgpt`. You can also install from source with `go install github.com/j178/chatgpt/cmd/chatgpt@latest`, or download a binary from the release page.
Can I use j178/chatgpt without an OpenAI API key?
No. The README's usage section begins by telling you to get or create an OpenAI API key and export it as `OPENAI_API_KEY`. There is no login flow or free tier described in the documentation.
Where does j178/chatgpt store my conversations?
The README states that configuration is read from `~/.config/chatgpt/config.json` and conversation history is saved to `~/.config/chatgpt/conversations.json`. The conversation file holds per-conversation config blocks plus a `last_idx` field pointing at the active conversation.
How do I use j178/chatgpt in a shell pipeline?
Pass input on standard input and use the `-p` flag to select a prompt, for example `cat config.yaml | chatgpt -p 'convert this yaml to json'`. The README also shows piping the output further, as in `echo "Hello, world" | chatgpt -p translator | say`.
Can I change the keyboard shortcuts in j178/chatgpt?
Yes. The README documents a `key_map` dictionary in the configuration file, where each named action such as `submit`, `quit` or `new_conversation` takes an array of key strings. The README provides a full example mapping that mirrors the defaults.
Does j178/chatgpt support models other than OpenAI's?
Not as shipped. The README carries a note that support for other providers such as Claude, Gemini and Ollama is under development and will be available soon, and points to issue #88. Until then the tool targets an OpenAI-compatible endpoint configured through the `endpoint` key.
Community notes