Model or dataset
simonw/llm avatar
simonw/llm

simonw/llm: A CLI and Python Library That Puts Model Choice Behind One Interface

Access large language models from the command-line

12,510 stars988 forksPythonApache-2.0

At a glance

What is it?
LLM is a Python command-line tool and library that talks to OpenAI, Claude, Gemini, Qwen, Gemma, Kimi, DeepSeek, Mistral and local models through plugins, logging every prompt and response to SQLite. It is a good fit for scripted, single-shot model calls; it is not a chat product or a hosted gateway.
Who is it for?
Adopt LLM if you want prompts, embeddings and structured extraction reachable from a shell script or a Python function, with responses logged to SQLite by default. Do not adopt it if you need a multi-user service, a web UI, or a provider abstraction that hides each vendor's native API surface, because the plugin model exposes those differences rather than smoothing them.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Python, 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

The problem LLM targets: one prompt, many providers, no application code

Most teams that try a language model end up writing the same throwaway script repeatedly: read an API key from somewhere, build a request body, handle the response, print the text. LLM replaces that script with a command. The README's quick start shows the shape of it. `llm "Ten fun names for a pet pelican"` runs a prompt against the default model, and `cat myfile.py | llm -s "Explain this code"` pipes a file in with a system prompt. The intended user is someone at a terminal, not someone building a product. That distinction matters, because it explains nearly every design decision in the project. There is no server component, no request queue, no dashboard. There is a binary that takes text in and gives text out, plus a Python library for when a shell pipeline is the wrong container. The audience is engineers doing data extraction, batch summarisation, ad hoc exploration, or wiring a model call into an existing shell-based workflow. If your requirement is a chat interface with user accounts, this is not that thing, and the README does not pretend otherwise.

How the plugin model splits core from providers

The core package ships a small set of capabilities and delegates the rest. The README lists the providers reachable through separate installs: `llm install llm-gemini` for Google, `llm install llm-anthropic` for Claude, `llm install llm-ollama` for models running locally through Ollama. Each plugin registers models with the core, which is why the same `-m` flag works across all of them. That is the real mechanism: a registry of model identifiers, populated at install time, resolved at call time. It has a consequence worth stating plainly. The list of models you can address depends on which plugins are installed and which versions of them, so the set of valid `-m` values is a property of your environment, not of the tool. The README also shows a path that skips plugins entirely: `uvx llm openai endpoint http://localhost:1234/v1 -m google/gemma-4-12b "What is the capital of France?"` points LLM at any OpenAI-compatible Chat Completions endpoint, with `--key your-api-key` when the endpoint requires authentication. That covers LM Studio and similar local servers without a dedicated plugin. The trade-off is visible here. Plugins give you provider-specific features. The generic endpoint path gives you portability at the cost of whatever the vendor does beyond the Chat Completions shape.

SQLite logging, embeddings, schemas and tools in one binary

Beyond single prompts, the README lists four capabilities that separate LLM from a thin curl wrapper. Prompts and responses are stored in SQLite, which the README calls out under logging. Embeddings can be generated and stored. Structured content can be extracted from text and images using schemas. Models can be granted the ability to execute tools. Each of these is a subcommand or flag rather than a separate tool, and they share the same database. That coupling is the interesting part. Because responses land in SQLite, a prompt you ran interactively yesterday is queryable today without any export step. The cost is that the database grows with use and lives somewhere on your filesystem that you should know about before you fill a disk. The README does not spell out retention or cleanup policy in the material available, so treat log growth as something to check rather than something the tool manages for you. The tools feature deserves the same caution. Granting a model the ability to execute tools means the model's output influences what runs on your machine. The README presents it as a capability; it does not present a sandbox. That is a design boundary, and it is one you should be deliberate about before enabling it in an unattended script.

Getting it running: install paths and the first two commands

Installation is offered four ways, and the README flags one of them. `pip install llm` is the default. `pipx install llm` and `uv tool install llm` isolate the tool from your project environment, which is the usual reason to prefer them. `brew install llm` exists but the README links to a warning note about the Homebrew route, so read that page before choosing it. Once installed, the first real step is credentials: `llm keys set openai` for OpenAI, `llm keys set gemini` after installing the Gemini plugin, `llm keys set anthropic` after installing the Anthropic plugin. Keys are stored by the tool rather than read from an environment variable in the documented flow, which is convenient for interactive use and a consideration for shared machines. After that, `llm -m gemini-3.5-flash 'Tell me fun facts about Mountain View'` and `llm -m claude-sonnet-5 'Impress me with wild facts about turnips'` show the pattern: install the plugin, set the key, name the model. For local models the sequence is three commands: `llm install llm-ollama`, `ollama pull llama3.2:latest`, then `llm -m llama3.2:latest 'What is the capital of France?'`. Note that the model name passed to `-m` is the Ollama tag, not a plugin-specific alias, so the naming convention follows the local runtime rather than LLM itself.

Interactive chat and its command vocabulary

`llm chat -m gpt-4.1` opens a REPL, and the README prints the full list of in-chat commands: `exit` or `quit` to leave, `!multi` to enter multiple lines then `!end` to finish, `!edit` to open your default editor and modify the prompt, and `!fragment <my_fragment> [<another_fragment> ...]` to insert one or more fragments. Fragments connect to the long-context work mentioned in the project news, where reusable text blocks are composed into a prompt rather than retyped. This is the part of LLM that looks most like a chat product, and it is worth being clear that it is not one. There is no conversation history UI, no branching, no sharing. The chat mode is a convenience wrapper around the same call path as the one-shot form. If your team's need is a shared chat surface, LLM's chat is a local convenience, not a collaboration tool, and the README's framing supports that reading. The fragment syntax is the piece most likely to be useful in practice, because it turns a long system prompt into something you name instead of paste.

Where LLM is the wrong tool

Three cases stand out. First, multi-user or hosted access. LLM is a local binary with local credentials and a local SQLite file. Nothing in the README describes authentication for other users, request isolation, or a network interface. Wrapping it in a service is possible because it is also a Python library, but that is your engineering, not the project's. Second, workflows that depend on a single vendor's newest API surface. The plugin model means the features you get track the plugin's release cadence, not the provider's. If a capability ships at a provider on Tuesday, the question of when it reaches LLM depends on the plugin maintainer. The generic OpenAI-compatible endpoint path is worse for this, since it targets the Chat Completions shape specifically. Third, anything where the SQLite log is a problem rather than a feature. Prompts and responses are stored, which is excellent for auditability and awkward if the content is sensitive and the machine is shared. The README presents logging as a capability; it does not present a documented off switch in the material available, so verify that before you run regulated content through it. None of these are defects. They are the edges of a deliberately local, single-operator tool.

The alternative worth comparing: provider SDKs called from your own code

The honest comparison is not another CLI. It is the official Python SDK for whichever provider you use, called directly. The difference in approach is where the abstraction sits. LLM gives you a model registry and a uniform `-m` flag, so switching from `claude-sonnet-5` to `gemini-3.5-flash` is a flag change and a plugin install. A provider SDK gives you that provider's full surface on day one, including parameters and endpoints that a uniform interface has no place to put. If you are building an application, the SDK is usually the better foundation, because you will want the vendor's types and error handling rather than a string in and string out contract. LLM earns its place in the gap between the two: scripts, pipelines, one-off extraction, and Python code where the point is the prompt rather than the integration. The library form means you are not locked into the CLI, and the SQLite log means you get a record of what ran without writing one. That combination is narrower than a framework and wider than a shell alias, which is exactly the niche it occupies.

Maintenance, versioning and licence

The release cadence is fast. The supplied release list shows 0.35 on 7 September 2026, 0.34 on 2 September, and 0.33 on 22 August, three releases inside roughly two weeks. The project news entry from 29 April 2026 describes LLM 0.32a0 as a major backwards-compatible refactor, which is a phrase worth reading carefully: a refactor of that size, even one described as backwards-compatible, is the kind of change that can surface in plugin behaviour rather than in the core CLI. The practical implication is that pinning matters. If you install plugins alongside the core, an upgrade to one can move ahead of the other, and the model identifiers your scripts depend on come from the plugin. Treat the core version and each plugin version as a set you test together. On licensing, the repository is Apache-2.0, which permits commercial use and modification and includes a patent grant, with the usual requirements around preserving notices and stating changes. Plugins are separate packages with their own licences, and the README does not enumerate them, so check each one you install. This is a description of the licence, not legal advice; get counsel for anything that depends on the outcome.

Editorial conclusion

Adopt LLM if you want prompts, embeddings and structured extraction reachable from a shell script or a Python function, with responses logged to SQLite by default. Do not adopt it if you need a multi-user service, a web UI, or a provider abstraction that hides each vendor's native API surface, because the plugin model exposes those differences rather than smoothing them. Before committing, run `llm logs path` to see where the database will live, check the licence file at the repository root, and confirm that a plugin exists for the model you actually intend to call, since core installs only cover the OpenAI-compatible path.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. simonw/llm on GitHub
Community notes

Community notes