Why did Shopify choose to use engines and packwerk instead of just packwerk?

This message was imported from the Ruby/Rails Modularity Slack server. Find more info in the import thread.

Message originally sent by slack user U783MOJYF8Z

Does someone know why Shopify went with engines + packwerk instead of only packwerk?
Shopify started out with just a few large packages - the components. The idea is that a component roughly corresponds to a busienss domain; we have a smell test that says you should be able to create a successful startup with just that part. So they’re not super small.

For these components it makes sense to have the standard rails folder structure; engines give us the autoloading setup to do that. They also provide custom initializers, routing, translations etc. Note however that we don’t currently load or test components / engines in isolation.

Also, by now we have quite a few nested packages within those components. Those are usually not engines, as the tradeoff looks different; they are usually much smaller and may only cover parts of the stack.

Hey Phillip, thanks for the insight. I have a couple of questions:

  1. For the nested packages you still needed to solve the autoloading setup right? Did you build something custom to have the nested packages load their code, initializers, etc?
  2. Is the idea of those nested packages to only be used by the parent component and sibling packages? Or what is the reason to have them nested within a component?

Message originally sent by slack user U783MOJYF8Z

Did you build something custom to have the nested packages load their code, initializers, etc?

I just checked and nested packages seem to be engines now too. Sorry, I haven’t been involved with this stuff for a while

Message originally sent by slack user U783MOJYF8Z

what is the reason to have them nested within a component?

The idea is to have a manageable number of “top level packages” - our core monolith is quite big, and a flat list of hundreds of packages would be hard to understand. Components are, as I said, modeled after business domains (inspired by domain driven design); all packages that implement parts of that domain are nested within that component.