IPython is an enhanced Python REPL, and it’s actually the core for Jupyter notebook. In short, Jupyter is an open-source web application that allows you to create and share documents containing live code, equations, visualizations, and narrative text. If you use the interactive shell a lot and you don’t know IPython, you should really check this one out!
IPython vs the standard Python REPL
The standard Python REPL has improved a lot. Since Python 3.13, it has colored prompts and error messages, lets you edit a whole block of code (like a function or a loop) at once, recalls that block from history as one piece, and has a paste mode (press F3) for pasting larger chunks of code. Python 3.14 added syntax highlighting while you type. So for quick experiments, the built-in REPL is now quite pleasant.
IPython still goes further. It has magic commands, numbered input and output you can refer back to, better object inspection with ? and ??, and a history that survives restarts. If you spend a lot of time in an interactive shell, IPython is worth it.
IPython features
Some of the features the IPython shell offers are:
- Comprehensive object introspection.
- Input history, persistent across sessions.
- Caching of output results during a session with automatically generated references.
- Tab completion, with support for completion of python variables and keywords, filenames, and Python functions.
- Magic commands for controlling the environment and performing many tasks.
- Session logging and reloading.
- Integrated access to the pdb debugger and the Python profiler.
- A less known feature of IPython: its architecture also allows for parallel and distributed computing.
Magic commands
These are just a selection of the magic commands that are built into IPython that I think you’ll like:
%cd— change the current working directory%edit— open an editor and execute the code you typed in after closing the editor%env— show the current environment variables%pip install [pkgs]— install packages without leaving the interactive shell%timeand%timeit— time the execution of Python code
Read the full list in the documentation here.
Referencing previous input and output
Another useful feature is referencing the input and output of a previous command. In and Out are actual objects. You can use the output of the 2nd command by using Out[2]. In[2] gives you the code you typed as a string, and the magic command %rerun 2 runs it again. Here’s a short session:
In [1]: numbers = [3, 1, 2] In [2]: sorted(numbers) Out[2]: [1, 2, 3] In [3]: Out[2] Out[3]: [1, 2, 3] In [4]: In[2] Out[4]: 'sorted(numbers)' In [5]: %rerun 2 === Executing: === sorted(numbers) === Output: === Out[5]: [1, 2, 3] In [6]: len? Signature: len(obj, /) Docstring: Return the number of items in a container. Type: builtin_function_or_method
The last command shows object introspection: put a question mark after any object, function, or module to see its documentation. Two question marks also show the source code, if it’s available.
Install IPython
If you want to use IPython inside a project, install it in the project’s virtual environment with pip install. That way, IPython can import all the packages of your project:
$ pip install ipython
If you’d rather have IPython available everywhere, install it as a tool. With uv, you can install it once, or start it without installing anything:
$ uv tool install ipython $ uvx ipython
With pipx, that’s pipx install ipython. Don’t use pip install --user for this: on many Linux distributions and on Homebrew’s Python, pip refuses to install outside a virtual environment. Keep in mind that a globally installed IPython runs in its own environment, so it can’t import the packages from your project’s virtual environment.