Dependency injection
without the magic.
Configuration, constructor injection, and events in a tiny jar.
No proxies. No field injection. No framework lock-in.
What makes Pixie different
No Proxies
Your objects are real objects. Clean stack traces, full JVM speed, and GraalVM native-image friendly.
Properties or Code
Configure from key-value properties — maps to AWS SSM, K8s ConfigMaps, Consul. Or wire in plain Java.
Built-in Events
Fire with @Event Consumer<T>, observe with @Observes. Polymorphic dispatch and exception isolation.
No Lock-in
Every class works with new. Remove Pixie and your code still compiles. Safe for any team size.
Four Producers
Constructors, @Factory methods, @Builder patterns, or pre-built instances. Use what fits.
Type-Safe Generics
Handler<String, Integer> only matches implementations with those exact type arguments. Wildcards included.
public class ShoppingCart {
public ShoppingCart(
@Param("taxRate") final double taxRate,
@Param("processor") @Component
final PaymentProcessor processor,
@Event
final Consumer<OrderPlaced> event) {
// Plain constructor. Works with new.
}
}Annotate a constructor.
Pixie does the rest.
@Param maps configuration values. @Component injects dependencies by type or name. @Event wires the event system. Your class stays plain Java.
cart = new://com.example.ShoppingCart
cart.taxRate = 0.08
cart.processor = @stripe
stripe = new://com.example.StripeProcessor
stripe.apiKey = sk_live_abc123
stripe.timeout = 30 secondsConfigure from properties
or in plain Java.
Key-value properties map directly to AWS Parameter Store, Kubernetes ConfigMaps, and every cloud platform. Component references use @name syntax. Or skip properties entirely and use System.builder().
// Factory — full control over construction
public class Connection {
@Factory
public static Connection create(
@Param("url") final String url,
@Param("timeout") @Default("30 seconds")
final Duration timeout) {
return new Connection(url, timeout);
}
}
// Builder — for complex construction
public class Pipeline {
@Builder
public static PipelineBuilder builder() {
return new PipelineBuilder();
}
}Four ways to
create components.
Constructors for simple cases. @Factory methods when you need validation or the constructor is private. @Builder for complex objects with many optional parameters. Or add pre-built instances with system.add().
// Fire events from any component
public class OrderService {
public OrderService(
@Event final Consumer<OrderPlaced> event) {
this.event = event;
}
public void place(String id) {
event.accept(new OrderPlaced(id));
}
}
// Observe events — no registration needed
public class EmailReceipt {
public void send(@Observes OrderPlaced e) {
mailer.send(e.getId());
}
}Decouple with events.
Inject a Consumer<T> to fire events. Add @Observes to receive them. Polymorphic dispatch, before/after hooks, and exception isolation included. In tests, just pass a lambda — no framework needed.
<dependency>
<groupId>org.tomitribe.pixie</groupId>
<artifactId>pixie</artifactId>
<version>2.0</version>
</dependency>Get started in seconds
One dependency. No transitive framework graph. No annotation processors. No code generation.
Installation guide →Explore the docs
Getting Started
Get up and running with Pixie in minutes
Annotations
Constructor annotations for configuration and dependency injection
References
How Pixie resolves @Component dependencies
Producers
Four ways to get objects into the Pixie System
Events
Fire and observe events across components
Testing
Test Pixie components with or without the framework
Configuration
Properties format, Builder API, and validation
Changelog
Version history and major features