expand_ex: Transform Your Elixir Code Organization with Automated Alias Expansion
Refactoring Elixir code at scale is hard. You have multi-module aliases scattered throughout your codebase, each one hiding dependencies that are impossible to track with simple find-and-replace operations. When you need to rename a module or split your Phoenix app into separate Contexts, these compact alias statements become your worst enemy.
What if you could expand every multi-module alias automatically, turning a manual refactoring nightmare into a one-command solution?
That's what expand_ex does. It's a lightweight Mix task that expands Elixir's multi-module import, require, and alias statements into clean, single-line declarations. In seconds, it transforms your entire codebase from alias MyApp.{User, Post, Comment} into individual, IDE-friendly lines that work perfectly with your development tools.
What is expand_ex?
expand_ex is an Elixir code formatting tool that automatically expands multi-module alias, import, and require statements into separate single-line declarations. Instead of maintaining compact syntax like this:
alias MyApp.{User, Post, Comment}
alias MyApp.Accounts.{Profile, Settings}
import MyApp.{Helpers, Utils}
expand_ex transforms it into:
alias MyApp.User
alias MyApp.Post
alias MyApp.Comment
alias MyApp.Accounts.Profile
alias MyApp.Accounts.Settings
import MyApp.Helpers
import MyApp.Utils
The tool is available on Hex.pm (version 0.1.0) and open source on GitHub. It's built as a Mix task that runs across your entire project, finding and expanding every multi-module statement in seconds using parallel processing.
Why You Need expand_ex: 10 Real Problems It Solves
1. Refactoring & Module Renaming Made Easy
When you rename a module from User to Accounts.User, your IDE's find-and-replace feature needs to be careful. If you have alias MyApp.{User, UserToken, UserSession}, searching for "User" will match all three, making safe refactoring nearly impossible.
With expand_ex, each module stands alone:
# Before: Fragile for refactoring
alias MyApp.{User, UserToken, UserSession}
# After: Safe, IDE-friendly
alias MyApp.User
alias MyApp.UserToken
alias MyApp.UserSession
Now your IDE can reliably rename User to Accounts.User without accidentally touching UserToken. Language servers love explicit aliases, making your development tools work faster and smarter.
2. Context Splitting & Code Reorganization
Migrating a monolithic Elixir application into separate Phoenix Contexts (Accounts, Content, Social, etc.) requires understanding exactly which modules depend on what. Compact aliases hide these dependencies.
expand_ex makes the dependency graph transparent. When you expand your aliases, you immediately see which modules belong together and which need to move into separate Contexts. It's the first step in any major refactoring project.
3. Superior Git Workflow
Compact aliases create messy diffs. When you modify alias MyApp.{User, Post, Comment} by removing one module, the entire line changes. This creates unnecessary noise in your git history and makes blame tracking harder.
Expanded aliases produce clean, line-based diffs:
- alias MyApp.User
alias MyApp.Post
- alias MyApp.Comment
Reviewers understand exactly what changed. Your git history stays clean. Merge conflicts become less frequent because each alias is independent.
4. Enhanced Code Review
During code reviews, sneaky additions hide in compact aliases. A PR might add a new module dependency inside an existing multi-module alias, and reviewers miss it:
- alias MyApp.{User, Post}
+ alias MyApp.{User, Post, Secret}
With expanded aliases, this addition is obvious and reviewers catch it every time:
alias MyApp.User
alias MyApp.Post
+ alias MyApp.Secret
5. Better Search & Replace
Need to find everywhere MyApp.User is imported? With compact aliases, you can't rely on simple text search. Expanded aliases make searching trivial. You grep for alias MyApp.User and find every location instantly. No regex needed. Your tools work faster.
6. Identify Unused Aliases
The Elixir compiler warns about unused aliases, but multi-module statements hide the actual culprit. With expand_ex, the compiler points directly at the line, making it easy to remove exactly what's unused without touching the rest.
7. Dependency Auditing & Security
When auditing which modules your code depends on, compact aliases make the task tedious. Expanded aliases let you quickly scan dependencies and spot suspicious modules. You also catch name collisions faster. If two namespaces export modules with the same name, expanded aliases surface the conflict immediately.
8. Onboarding & Code Comprehension
New developers learning your codebase need to understand what modules are used where. Compact aliases force them to mentally expand the statement. Expanded aliases make dependencies explicit and obvious. Your team onboards faster. Code comprehension improves. Knowledge transfer becomes easier.
9. Tooling Compatibility
Modern Elixir tooling (Language Server, Dialyzer, linters, static analysis tools) works best with explicit, single-line imports. Compact aliases sometimes confuse analysis tools or require special handling. expand_ex ensures your code works optimally with every development tool in your ecosystem.
10. Real-World Refactoring: Phoenix Context Migration
Splitting a monolithic Phoenix app into proper Contexts requires understanding and reorganizing hundreds of module dependencies. expand_ex is the foundational tool for making this refactoring safe and manageable.
Real-World Use Case: Migrating to Phoenix Contexts
Let's walk through a concrete example: migrating a monolithic MyApp into separate Phoenix Contexts.
The Problem
Your Phoenix app started simple, but it's grown. You have users, posts, comments, and more all tangled together. The dependencies are opaque. You can't tell what truly belongs in Accounts vs Content vs Social. Refactoring is risky.
Step 1: Expand All Aliases
Run expand_ex:
mix expand
Now every file shows explicit dependencies, making the structure transparent.
Step 2: Analyze Dependencies
With expanded aliases, you see the problem clearly. Relationships that were implicit in compact syntax are now explicit and visible, allowing you to make informed decisions about Context boundaries.
Step 3: Reorganize into Contexts
Create proper Context structure, move files, and update the aliases. With expand_ex, this process is manageable because you can see exactly what depends on what.
Step 4: Run expand Again
After refactoring and reorganizing, run expand_ex one more time to ensure consistency. Your code is now organized into clean Contexts, dependencies are explicit, and your team understands the domain boundaries.
How expand_ex Works Under the Hood
expand_ex is implemented as a Mix task that processes your Elixir codebase efficiently:
- File Discovery - Finds all .ex and .exs files in your project (excluding dependencies)
- Pattern Matching - Identifies multi-module import, require, and alias statements using regex matching
- Expansion - Transforms each compact statement into individual single-line declarations
- Parallel Processing - Uses Task.async_stream/2 to process multiple files concurrently
- Recursive Processing - Runs until no more compact statements remain
- File Writing - Updates files in-place with expanded aliases
Installation & Usage
Getting started with expand_ex takes just a few minutes.
Add to Your Dependencies
In mix.exs, add expand_ex to your dependencies:
defp deps do
[
{:expand_ex, "~> 0.1"}
]
end
Then fetch the dependency:
mix deps.get
Run the Expansion
Expand all aliases in your project:
mix expand
The task will process all .ex and .exs files, expand every multi-module statement, and update files in-place.
Verify the Results
Check your git diff to see the changes:
git diff
Review the changes, make sure they look good, then commit:
git add .
git commit -m "Expand multi-module aliases with expand_ex"
Requirements
- Elixir ~> 1.12 or later
- Mix (comes with Elixir)
expand_ex is production-ready and thoroughly tested. It's safe to run on active codebases and integrates seamlessly into your development workflow.
Why This Matters: The Bigger Picture
expand_ex is a small tool, but it solves a real problem in Elixir development. As your application grows, code organization becomes crucial. Explicit dependencies make refactoring safer, code reviews more effective, and onboarding faster.
The Elixir community has always valued readability and maintainability. expand_ex extends that philosophy by making dependencies explicit and your codebase easier to navigate.
Whether you're splitting a monolithic app into Phoenix Contexts, renaming modules safely, improving code review quality, onboarding new developers, or auditing dependencies and security, expand_ex gives you a foundation for better code organization.
Key Takeaways
- expand_ex automatically expands multi-module aliases into clean, single-line declarations
- Safer refactoring through explicit dependencies and IDE compatibility
- Better code reviews with obvious dependency additions in diffs
- Cleaner git history with line-based changes instead of full-line modifications
- Phoenix Context migration becomes manageable at scale
- Improved tooling compatibility with language servers, linters, and static analysis
- Better team onboarding with explicit, readable dependencies
Make your Elixir code more maintainable today. Get expand_ex on Hex.pm or view the source on GitHub.