python-inquirer: an Inquirer.js clone for Python prompts
A collection of common interactive command line user interfaces, based on Inquirer.js (https://github.com/SBoudrias/Inquirer.js/)
At a glance
- What is it?
- python-inquirer is a collection of common interactive command line user interfaces for Python, born as a clone of Inquirer.js and covering text, editor, list, checkbox and path questions with validation, hierarchical prompts and error feedback. It is MIT licensed, the current release is 3.4.1, and it has three runtime dependencies: blessed, readchar and editor.
- Who is it for?
- python-inquirer fits a Python developer who wants a script to ask a person questions rather than take command line arguments, and it fits a project moving that script to something closer to a wizard. It does not fit a script that has to run unattended, since the whole point is a human at the terminal, and the documentation says nothing about a non-interactive mode.
- Can I use it commercially?
- Yes. MIT 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 48 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 October 21, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Four runtime dependencies, and a deliberate design lineage
python-inquirer is a collection of common interactive command line user interfaces, based on Inquirer.js, and the project's own framing of its purpose is unusually clear.
It was born as an Inquirer.js clone and shares part of the goals and philosophy. Inquirer should ease the process of asking end user questions, parsing and validating answers, managing hierarchical prompts and providing error feedback. That is four distinct jobs, and it is worth noticing that the library is not only about rendering a nice prompt on screen. Parsing is the conversion of what the user typed into a typed value, validation is the rejection of a bad answer before the next question is asked, hierarchical prompts are the ability to ask a follow-up question only if an earlier answer needs it, and error feedback is the re-ask loop that makes the whole thing usable.
The dependency list in `pyproject.toml` shows how small the implementation is. There are three runtime dependencies: `blessed` at >=1.19.0 for terminal control, `readchar` at >=4.2.0 for reading individual keystrokes, and `editor` at >=1.6.0 for the external editor question. Everything else is the standard library, and the build backend is `poetry-core`.
Two of those choices are what make the library work the way it does. `readchar` gives you single-key input, which is what makes arrow-key navigation in a list possible without waiting for a newline, and `blessed` gives you the terminal capability detection, the cursor control and the colour handling, and it degrades when the terminal is dumb. Neither of them is a large dependency, and together they are the reason the library works on a plain terminal with no extra tooling.
The package is called `inquirer` on PyPI even though the repository and the project are called python-inquirer, which is a small trap when you are searching for it.
The classifiers are worth one line too. The status is Development Status:: 5 - Production/Stable, the supported Python versions are 3.9 through 3.13, and the requires-python is >=3.9.2.
Asking questions is a list of question objects and one call
The API shape is the whole of it, and it takes two lines to see.
import inquirer
questions = [
inquirer.Text('name', message="What's your name"),
inquirer.Text('surname', message="What's your surname"),
inquirer.Text('phone', message="What's your phone number",
validate=lambda _, x: re.match('\+?\d[\d ]+\d', x),
)
]
answers = inquirer.prompt(questions)Each question is an object with a name, which is the key it will appear under in the returned dictionary, and a message. The `validate` argument takes a callable, and the phone example shows the shape: it receives two arguments, the question and the current answer, and returns something truthy when the answer is acceptable. The phone pattern is a regular expression, `re.match('\+?\d[\d ]+\d', x)`, so an optional leading plus, then a digit, then digits or spaces, then a digit.
That is a small but real design decision. Validation is per question and per call, not a schema applied to the whole answer set. The consequence is that there is no built-in way to say this field is required and that one is optional, or that the two must agree, other than by writing the callable yourself. For a two-field form that is fine. For a fifteen-field form with cross-field rules, the logic ends up outside the library, which is worth knowing before you build a large wizard on it.
The return value is a plain dictionary keyed by the question names, so `answers['phone']` is what the user typed, and `inquirer.prompt(questions)` is the single call that runs the sequence.
The `examples/` directory shows the full surface, with scripts covering the question types and the options: checkbox, checkbox carousel, hints, locked, long, other and tagged variants, confirm, editor, ignore, list and its variants, located, mixed, password, password echo, path, pre-answers, questions from JSON, replacements and shortcuts.
List and Checkbox differ in one detail that matters
List and Checkbox look like the same widget with a different number of answers, and the documentation spells out how they differ.
A List shows a list of choices and allows the selection of one of them. A Checkbox shows a list of choices with multiple selection. Both take the extra argument `carousel=False`, and when it is set to true the answers rotate, back to the first when pressing down on the last choice, and down to the last when pressing up on the first.
Navigation beyond the arrow keys is the other shared feature. Page Up and Page Down move the selection a full page at a time, which is handy for long lists, and when carousel is enabled they wrap around just like the arrow keys.
Checkbox has one more argument, `locked=<List>`, and the given choices in it cannot be removed. The documentation gives the reason: it is useful if you want to make clear that a specific option out of the choices must be chosen. So a locked choice is a pre-selected, non-deselectable entry, which is how you express a mandatory option without validating it afterwards.
inquirer.Checkbox('interests',
message="What are you interested in?",
choices=['Computers', 'Books', 'Science', 'Nature', 'Fantasy', 'History'],
)The `examples/` directory also shows that the choice list is not restricted to plain strings. There are `list_hints.py`, `checkbox_hints.py`, `checkbox_tagged.py`, `list_tagged.py` and `list_other.py`, which are the variants where a choice carries a hint, a tag or some other object, and `list_long.py` and `checkbox_long.py` for lists too long to fit on screen.
The `examples/pre_answers.py` and `examples/questions_from_json.py` files point at something the README does not explain in prose. Questions can be supplied from JSON, and answers can be pre-supplied, which is how you build a wizard that can be resumed or driven from a configuration file rather than typed.
Text, Editor and Path, and how the external editor is chosen
The other three question types are more specialised, and two of them handle real-world friction.
Editor is like a Text question but for larger answers, and it opens an external text editor to collect the answer. The environment variables `$VISUAL` and `$EDITOR` specify which editor is used, and if neither is present inquirer falls back to `vim`, then `emacs`, then `nano`, in that order, based on what is available on the system. The external editor handling is done with the `python-editor` library.
That fallback chain is the kind of detail that matters more than it looks. A prompt that assumes `$EDITOR` is set will fail silently in a container, in a CI job, or on a system where the user has a different set-up, and a prompt that assumes vim exists will fail on a minimal image. Asking, then falling back through three known editors, is the difference between a prompt that works everywhere and one that works on the developer's machine.
inquirer.Editor('long_text', message="Provide long text")Path is like Text but with builtin validations for working with paths. The `path_type` argument is what does the work:
inquirer.Path('log_file',
message="Where logs should be located?",
path_type=inquirer.Path.DIRECTORY,
)`inquirer.Path.DIRECTORY` tells the question that the answer must be a directory, so a file path is rejected at the prompt rather than discovered later when the code tries to write into it.
The other examples in the directory cover the rest of the surface: `confirm.py` for yes and no, `password.py` and `password_echo.py` for the two password entry styles, `ignore.py` and `shortcuts.py` for the key handling options, `mixed.py` for a form with different question types together, `replacements.py` for the rendering options, and `located.py` for a question about the terminal's own capabilities.
The project tooling is stricter than the library
The pyproject.toml and the surrounding files describe a project with unusually high internal standards for a library of this size, and that tells you something about how it is maintained.
The coverage configuration is the standout. Branch coverage is on, the source is both the `inquirer` package and the tests, the report shows missing lines, and `fail_under = 97`. A library that requires 97 percent branch coverage to merge is one where the maintainer has decided that untested branches are bugs, and given that the code is mostly terminal interaction where a missed branch is a hung prompt, that is a defensible position.
The tooling list is broad. `flake8` with `flake8-docstrings` means the docstrings are checked, `isort` and `pyupgrade` handle import ordering and syntax modernisation, `black` formats the code, `pre-commit` with `pre-commit-hooks` runs the checks before a commit, `bandit` and `safety` are there for security checks, `sphinx` and `sphinx-autobuild` build the documentation with the `furo` theme, and `pexpect` is present for driving the prompts in tests. The `noxfile.py` at the top level runs the test matrix, with `nox` and `nox-poetry` in the dev dependencies.
The CI setup matches: a Tests workflow badge, a Codecov badge, a pre-commit badge, and a `codecov.yml` configuration at the root. The `bandit.yml` file at the root is a bandit configuration, and `.flake8` and `.editorconfig` handle linting and formatting conventions.
One thing the pyproject does not show is a test framework dependency in the runtime group, which is where `pexpect` earns its place: driving a terminal prompt in a test means spawning a pseudo-terminal and expecting the interaction, which is exactly what pexpect is for, and it is why this library can claim a 97 percent branch coverage without a mocked-out terminal.
The documentation is on Read the Docs at python-inquirer.readthedocs.io, and the README says the documentation has been moved there, keeping only the usage examples.
Where python-inquirer is the wrong choice
The first case is a script that has to run without a person. Everything in this library is built around the assumption that someone is at the terminal to answer, and the documentation says nothing about a non-interactive mode where answers come from a file, from standard input or from a default. If your tool has to work in a pipeline, in a cron job or in a container with no tty, you need to design around that, and this library will not do it for you.
The second case is a project that has already chosen a prompt library. There is a long tail of similar libraries, and the choice is usually made once. The interesting thing about python-inquirer is not that it is better than the alternatives, it is that it is a faithful port of Inquirer.js, so a team coming from the JavaScript ecosystem gets the same interaction model and roughly the same mental model.
The third case is a form with heavy cross-field validation. As noted, validation is a callable per question, so a required-field rule, a dependent field and a confirm-and-correct loop all have to be written by hand, and the hierarchical prompting is not a schema-driven mechanism. If your input is a complicated document rather than a short set of answers, a form library with a schema, or a TUI framework, is a better fit.
The fourth is Windows, and the project is honest about it. Python-inquirer supports mainly UNIX-based platforms, and Windows has experimental support with an invitation to report problems. The use of `readchar` for single-key input and of `blessed` for terminal control is where the platform assumption lives, and while modern Windows terminals have improved a great deal, a library that says experimental should be treated as such on a platform where the team cannot test every configuration.
On maintenance, the version is 3.4.1, released 2025-08-02, with 3.4.0 from 2024-08-12 and 3.3.0 from 2024-06-25, and the last push to the repository was on 2026-09-04, so the project is not abandoned. The copyright line in the README runs 2014-2023, and the licence is MIT, with the attribution to both the Python author and Simon Boudrias for Inquirer.js.
Editorial conclusion
python-inquirer fits a Python developer who wants a script to ask a person questions rather than take command line arguments, and it fits a project moving that script to something closer to a wizard. It does not fit a script that has to run unattended, since the whole point is a human at the terminal, and the documentation says nothing about a non-interactive mode. Before you adopt it, check the platform support, because the project states it mainly supports UNIX-like systems with Windows support marked experimental, and note that the validation is regex-based per question rather than a schema.
Frequently asked questions
How do I install python-inquirer?
Run `pip install inquirer`, which is the PyPI package name, even though the project and repository are called python-inquirer. The runtime dependencies are blessed, readchar and editor, and Python 3.9.2 or newer is required.
Which question types does python-inquirer provide?
Text, Editor, List, Checkbox and Path, plus the Confirm and Password types that appear in the examples directory. The examples folder contains scripts covering the variants of each, including carousel, hints, tagged, locked, long and other options.
How does python-inquirer validate an answer?
Each question takes a `validate` callable that receives the question and the current answer and returns something truthy when the answer is acceptable, as in the phone number example that uses a regular expression match. There is no separate schema layer for the whole answer set.
Does python-inquirer work on Windows?
The project states that it supports mainly UNIX-based platforms such as macOS and Linux, and that Windows has experimental support with an invitation to report problems.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/magmax-python-inquirer)Was this useful?