๐Ÿ“ฆ Boxwerk

Boxwerk is a tool for creating modular Ruby and Rails applications. It enables you to organize code into packages of Ruby files with clear boundaries and explicit dependencies. Boxwerk is heavily inspired by Packwerk but provides more robust enforcement at runtime using Ruby::Box, ensuring that only public constants from direct dependencies are accessible. Violations raise NameError, turning architectural rules into runtime guarantees.

As your application grows, Boxwerk helps prevent accidental coupling, enforces modularity, and makes it easier to understand and modify code without breaking other parts of the system.

{Usage Guide}[USAGE.md] ยท {API Documentation}[https://dtcristo.github.io/boxwerk/] ยท {Changelog}[CHANGELOG.md]

Features

Goals

Ruby::Box

Ruby::Box (Ruby 4.0+) provides in-process isolation of classes, modules, and constants. Each box has its own top-level Object, isolated $LOAD_PATH and $LOADED_FEATURES, and independent monkey patches. Boxwerk creates one box per package and wires cross-package constant resolution through const_missing.

Set RUBY_BOX=1 before starting Ruby. See the official documentation for details. See ARCHITECTURE.md for how Boxwerk uses Ruby::Box internally.

Quick Start

Create packages with package.yml files:

my_app/
โ”œโ”€โ”€ package.yml
โ”œโ”€โ”€ main.rb
โ””โ”€โ”€ packs/
    โ”œโ”€โ”€ foo/
    โ”‚   โ”œโ”€โ”€ package.yml
    โ”‚   โ””โ”€โ”€ lib/foo.rb
    โ””โ”€โ”€ bar/
        โ”œโ”€โ”€ package.yml
        โ””โ”€โ”€ lib/bar.rb
# package.yml (root)
enforce_dependencies: true
dependencies:
  - packs/foo
  - packs/bar

Install and run:

gem install boxwerk
RUBY_BOX=1 boxwerk run main.rb

No Bundler or Gemfile required for basic usage. To use global or per-package gems, see USAGE.md.

CLI

boxwerk run <script.rb>             Run a Ruby script in a package box
boxwerk exec <command> [args...]    Execute a command in the boxed environment
boxwerk console                     Interactive console in a package box
boxwerk info                        Show package structure and dependencies
boxwerk install                     Install gems for all packages

Options: --package <package>, --all, --global. See USAGE.md for details.

Limitations

See TODO.md for plans to address these and other planned features.

Examples

Development

bundle install                        # Install dependencies
RUBY_BOX=1 bundle exec rake           # Run all tests (unit, e2e, examples)
bundle exec rake format               # Format code

License

Available as open source under the MIT License.