Scaldi
Scaldi is a lightweight dependency injection (DI) library for Scala. It’s designed to be simpler and more “Scala-idiomatic” than heavier Java-style DI frameworks. Basically Scala already have everything you need for dependency injection. But still some things can be made easier. Goal of the project is to provide more standard and easy way to make dependency injection in Scala projects consuming power of the Scala language. With Scaldi you can define your application modules in pure Scala without any annotations or XML.
Why use Scaldi?
• Reduce tight coupling between components
• Make code easier to test (swap implementations easily)
• Avoid manual object wiring in large applications
• Keep DI simple and readable in Scala style
Basic idea
Instead of manually creating objects:
val service = new UserService(new UserRepository())
You define bindings and let Scaldi resolve dependencies automatically.
Example
Define components
trait UserRepository {
def getUser(id: Int): String
}
class UserRepositoryImpl extends UserRepository {
def getUser(id: Int) = s"User $id"
}
class UserService(repo: UserRepository) {
def printUser(id: Int) = println(repo.getUser(id))
}
Define module (bindings)
import scaldi.Module
class AppModule extends Module {
bind[UserRepository] to new UserRepositoryImpl
bind[UserService] to new UserService(inject[UserRepository])
}
Use it
import scaldi.Injectable
object Main extends App with Injectable {
implicit val injector = new AppModule
val service = inject[UserService]
service.printUser(1)
}
Key features of Scaldi
• Lightweight (no heavy container)
• No annotations required
• Uses Scala idioms (implicits, traits)
• Supports lazy injection
• Easy testability (override modules in tests)
• Minimal configuration
Key concepts of Scaldi
• Module → defines bindings
• Injector → resolves dependencies
• bind / inject → core API
• Injectable trait → enables injection
Advantages
• Very simple compared to frameworks like Spring
• Fits naturally with Scala language features
• Low overhead
• Good for small to medium projects
Disadvantages
• Less popular / smaller ecosystem
• Limited documentation compared to mainstream tools
• Not actively evolving much in recent years
• Lacks advanced features of larger DI frameworks
When should you use it?
Use Scaldi when:
• You want simple DI without complexity
• You’re building a pure Scala project
• You prefer code-based configuration
Avoid it when:
• You need enterprise-scale DI features
• You want long-term actively maintained tooling
• Your team already uses another DI standard
Alternatives
• Guice → annotation-based, Java-friendly
• MacWire → no runtime reflection, compile-time wiring
• Spring Framework → full ecosystem, heavy but powerful
• ZIO → modern, functional approach to DI
• Airframe → lightweight, similar philosophy
Important Traits
There are 3 most important traits that you need to know, in order to make dependency injection with Scaldi:
• Injector: it's a container for the bindings, that you have defined in the module.
• Module: gives you nice syntax to create bindings with bind and binding. Module also extends Injector trait and implicit Injector instance always available when you are defining your bindings
• Injectable: the only responsibility of this trait is to provide you with inject function (so it just provides nice syntax for injecting dependencies). It’s important to understand, that it’s the only purpose of it. So it is completely stateless and knows nothing about actual bindings you have defined in the module. In order to actually find and inject dependencies, inject function always takes an implicit parameter of type Injector.