In this article, we'll explore how to customize the Interactive Elixir (IEx) shell to enhance your development workflow. We'll cover everything from basic configuration to advanced customization techniques that can make your IEx sessions more productive and enjoyable.
Note: The examples in this article use Elixir 1.17.3. While most features should work across different versions, some functionality might vary.
Table of Contents
- Understanding IEx Configuration
- Basic Shell Customization
- Configuring the IEx Prompt
- Creating Custom Helpers
- Setting Up .iex.exs
- Color Schemes and Styling
- Best Practices
- Conclusion
- Next Steps
Understanding IEx Configuration
IEx configuration can be set up in multiple ways:
- Through the
.iex.exs
file in your home directory (~/.iex.exs
) - Through a project-specific
.iex.exs
file - Via runtime configuration in your IEx session
The configuration files are loaded in the following order:
- User's home directory configuration (
~/.iex.exs
) - Current directory configuration (
./.iex.exs
) - Project-specific configuration (if present)
Basic Shell Customization
Let's start with basic shell configurations. Create a .iex.exs
file in your home directory:
# Configure IEx basic settings
IEx.configure(
history_size: 100,
inspect: [
limit: 5_000,
pretty: true,
width: 80
],
colors: [enabled: true]
)
# Common imports that you use frequently
import Enum, only: [map: 2, reduce: 3]
import String, only: [upcase: 1, downcase: 1]
# Default aliases
alias MyApp.Repo
alias MyApp.User
You can verify if these configurations are working correctly by running the following tests in your IEx session:
# Test history_size configuration
iex(1)> IEx.configuration()[:history_size]
100 # Should return 100
# Test inspect configurations
iex(2)> list = Enum.to_list(1..10_000)
iex(3)> IO.inspect(list, width: 30) # Compare with your width: 80 setting
# Test Enum imports
iex(4)> map([1, 2, 3], fn x -> x * 2 end) # Should work without Enum.
[2, 4, 6]
iex(5)> reduce([1, 2, 3], 0, fn x, acc -> x + acc end)
6
# Test String imports
iex(6)> upcase("hello") # Should work without String.
"HELLO"
iex(7)> downcase("WORLD")
"world"
# Test if colors are enabled
iex(8)> IO.ANSI.enabled?()
true
# Test aliases (will show error if modules don't exist, confirming alias setup)
iex(9)> Repo # Should show MyApp.Repo module or error if not exists
iex(10)> User # Should show MyApp.User module or error if not exists
# Show complete current configuration
iex(11)> IEx.configuration()
# Displays all current IEx configurations
Configuring the IEx Prompt
Customize your prompt to make it more informative and visually appealing:
# Custom prompt configuration
IEx.configure(
default_prompt:
"#{IO.ANSI.green}%prefix#{IO.ANSI.reset}" <>
"(#{IO.ANSI.cyan}%counter#{IO.ANSI.reset}) >",
alive_prompt:
"#{IO.ANSI.green}%prefix#{IO.ANSI.reset}" <>
"(#{IO.ANSI.cyan}%node#{IO.ANSI.reset}) " <>
"(#{IO.ANSI.cyan}%counter#{IO.ANSI.reset}) >"
)
# Available prompt variables:
# %counter - command counter
# %prefix - iex
# %node - node name (when running distributed)
Creating Custom Helpers
Custom helpers can significantly improve your workflow. Here are some useful examples:
# ~/.iex.exs
defmodule IExHelpers do
def reload! do
Mix.Task.reenable("compile.elixir")
Application.stop(Mix.Project.config()[:app])
Mix.Task.run("compile.elixir")
Application.start(Mix.Project.config()[:app])
end
def list_app_modules(app) do
case :application.get_key(app, :modules) do
{:ok, modules} ->
modules
|> Enum.sort()
|> IO.inspect(pretty: true)
:undefined ->
IO.puts "Application #{app} not found or has no modules"
end
end
end
import IExHelpers
You can use these functions in IEx like this:
iex> reload! # Recompiles and restarts your application for code changes
iex> list_app_modules(:phoenix) # Lists all available modules in the Phoenix application
Setting Up .iex.exs
Here's a complete example of a .iex.exs
configuration file:
# ~/.iex.exs
# Configure IEx basic settings
# Common imports that you use frequently
import Enum, only: [map: 2, reduce: 3]
import String, only: [upcase: 1, downcase: 1]
# Set up aliases
alias MyApp.Repo
alias MyApp.User
# Configure shell appearance
Application.put_env(:elixir, :ansi_enabled, true)
IEx.configure(
history_size: 100,
inspect: [
limit: 5_000,
pretty: true,
width: 80
],
colors: [
syntax_colors: [
number: :yellow,
atom: :cyan,
string: :green,
boolean: :red,
nil: :red
],
eval_result: [:green, :bright],
eval_error: [:red, :bright],
eval_info: [:blue, :bright]
],
default_prompt:
"#{IO.ANSI.green()}%prefix#{IO.ANSI.reset()}" <>
"(#{IO.ANSI.cyan()}%counter#{IO.ANSI.reset()}) >"
)
defmodule IExHelpers do
def reload! do
Mix.Task.reenable("compile.elixir")
Application.stop(Mix.Project.config()[:app])
Mix.Task.run("compile.elixir")
Application.start(Mix.Project.config()[:app])
end
def list_app_modules(app) do
case :application.get_key(app, :modules) do
{:ok, modules} ->
modules
|> Enum.sort()
|> IO.inspect(pretty: true)
:undefined ->
IO.puts("Application #{app} not found or has no modules")
end
end
end
# Import helper functions into IEx session scope
import IExHelpers
Color Schemes and Styling
IEx supports ANSI colors for various elements. Here's how to configure them:
# Color configuration
IEx.configure(
colors: [
enabled: true,
syntax_colors: [
number: :yellow,
atom: :cyan,
string: :green,
boolean: :red,
nil: :red,
],
ls_directory: :cyan,
ls_device: :yellow,
doc_code: :green,
doc_inline_code: :magenta,
doc_headings: [:cyan, :underline],
doc_title: [:cyan, :bright, :underline],
]
)
Best Practices
-
Organization
- Keep your
.iex.exs
file organized and well-commented - Group related configurations together
- Document custom helpers
- Keep your
-
Project-Specific Configuration
- Use project-level
.iex.exs
for project-specific settings - Keep general configurations in your home directory's
.iex.exs
- Use project-level
-
Performance
- Avoid loading unnecessary modules or making expensive computations
- Use lazy loading when possible
- Keep helper functions simple and focused
-
Maintenance
- Regularly review and update your configurations
- Remove unused helpers and aliases
- Keep configurations in version control
Conclusion
Customizing IEx can significantly improve your Elixir development experience. By properly configuring your shell environment, you can work more efficiently and effectively. Remember that the best configuration is one that suits your specific needs and workflow.
Next Steps
In the upcoming articles, we'll explore:
- Numbers in Elixir
- Integer, floats, and mathematical operations
Top comments (4)
Thanks! This was a great inspiration to tune my
iex.exs
further.Will my global ~/.iex.exs gets merged with project specific iex.exs?
Yes, they get merged in sequence: global config loads first, then project-specific one on top of it.
Thanks for sharing, very helpful!