A Ruby code minifier that uses TypeProf for type-aware analysis and AST-based transformations to achieve high compression rates while preserving functional equivalence.
This project takes an aggressive optimization approach. In Ruby, even comment removal requires context awareness — for example, foo\n# comment\n.to_s works because the comment connects the method chain, but removing it causes a syntax error. Whether a given comment is safe to remove depends entirely on context, making the boundary between safe and unsafe transformations inherently blurry. Since conservative minification is already difficult in Ruby, we choose to optimize as aggressively as possible. TypeProf's type analysis helps make these transformations more informed, but the goal is always maximum compression.
- Multi-file support: Follows
require_relativeandautoloadto collect and concatenate dependencies into a single output - Whitespace & comment removal: Strips all unnecessary whitespace and comments
- AST transformations: Boolean/char shortening, constant folding, control flow simplification, endless methods, parenthesis optimization
- Constant aliasing: Renames user-defined constants and shortens repeated external constant paths
- Variable renaming: Shortens local variables, keyword arguments, instance/class/global variables
- Method renaming: Shortens method names with
send(:sym)coordination and attr-backed ivar optimization - Method alias shortening: Replaces long stdlib method names with shorter aliases (e.g.,
collect→map) - Dead code elimination: Removes unreachable code after
return,break,next,raise - RuboCop preprocessing: Applies safe autocorrections before minification
- Dynamic code detection: Disables renaming in scopes containing
eval,binding,send, etc.
gem 'ruby-minify'# Minify a file (follows require_relative automatically)
bin/minify path/to/entry.rb
# Specify compression level (0-5 or alias: min, stable, unstable, max)
bin/minify path/to/entry.rb -c 5
bin/minify path/to/entry.rb -c max
# Write to output file
bin/minify path/to/entry.rb -o minified.rb
# Write constant aliases to a separate file (only generated at L2+)
bin/minify path/to/entry.rb -o minified.rb -a aliases.rb
# Multiple entry points
bin/minify file1.rb file2.rb
# Show version / help
bin/minify -v
bin/minify -hrequire 'ruby_minify'
minifier = RubyMinify::Minifier.new
result = minifier.call('path/to/entry.rb')
puts result.content # minified code
puts result.preamble # external prefix declarations (e.g., "A=TypeProf::Core::AST")
puts result.aliases # backward-compat alias declarations (e.g., "MyClass=A")
puts result.stats.file_count # number of files processed
puts result.stats.compression_ratio # e.g., 0.44 (56% reduction)
# Specify optimization level (0-5, default: 3)
result = minifier.call('path/to/entry.rb', level: 5)The default level is 3 (stable). Levels 0-3 are safe transformations that preserve all public interfaces. Levels 4-5 are aggressive and may break code that relies on reflection or name inspection.
| Level | Alias | Transformations | Safety |
|---|---|---|---|
| 0 | min |
Whitespace/comment removal (AST rebuild) | Safe |
| 1 | + AST transformations (boolean/char/constant folding, control flow, endless methods, paren removal) | Safe | |
| 2 | + Constant aliasing, external prefix aliasing | Safe | |
| 3 | stable |
+ Local variable & keyword argument renaming | Safe |
| 4 | unstable |
+ Class/module renaming, instance/class/global variable renaming | Aggressive |
| 5 | max |
+ Method renaming, attr-backed ivar coordination | Aggressive |
See tests/ruby_minify/pipeline/ for per-stage transformation examples, and tests/ruby_minify/levels/ for end-to-end compression examples at each level.
bundle install
# Run tests (fast, excludes self-hosting)
rake test
# Run all tests including self-hosting
rake test:all
# Run self-hosting test only
rake test:integration
# Run gem integration tests (minifies real gems and runs their test suites)
rake test:gems
# Show compression ratio on self-hosting
rake benchmarkThe minification pipeline:
FileCollector → Concatenator → Preprocessor → Compactor → STAGES[level] → Output
- FileCollector — Resolves
require_relative/autoloadand collects all source files into a dependency graph - Concatenator — Topologically sorts files and concatenates them into a single source
- Preprocessor — Applies RuboCop safe autocorrections (redundant return/self, symbol proc, etc.)
- Compactor — Rebuilds the AST into minimal whitespace form (L0 baseline)
- STAGES — Table-driven stage pipeline, configured per level:
- Optimize stages (Hash
{Class => weight}):ControlFlowSimplify,EndlessMethod,ConstantFold,BooleanShorten,CharShorten,ParenOptimizer— executed by weight (high-weight before renames, zero-weight after), each transformsString → String - Rename stages (Array
[Class, kwargs]):ConstantAliaser,VariableRenamer,MethodRenamer— run viaUnifiedRenamerwith a single TypeProf analysis pass
- Optimize stages (Hash
- TypeProf - Type-aware AST analysis
- Prism - Syntax validation
- RuboCop - Preprocessing autocorrections
The gem is available as open source under the terms of the MIT License.