{"id":50645357,"url":"https://github.com/tomas-samek/tiko-di","last_synced_at":"2026-06-07T12:01:16.296Z","repository":{"id":354010617,"uuid":"1219167738","full_name":"tomas-samek/tiko-di","owner":"tomas-samek","description":"Compile-time dependency injection framework for Java 21+. All wiring validated and generated by an annotation processor, so there's no reflection, no classpath scanning, and no runtime DI exceptions during normal operation. Ships with a built-in event bus that swaps transparently between local (in-memory) and distributed implementations.","archived":false,"fork":false,"pushed_at":"2026-06-05T05:11:41.000Z","size":4380,"stargazers_count":4,"open_issues_count":27,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T07:24:19.093Z","etag":null,"topics":["annotation-processor","compile-time","dependency-injection","event-driven","graalvm","ioc-container","java-21"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tomas-samek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-23T15:44:16.000Z","updated_at":"2026-06-05T05:11:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"f0c0ada8-42f8-4d55-9cd3-fe4dda40ac8e","html_url":"https://github.com/tomas-samek/tiko-di","commit_stats":null,"previous_names":["tomas-samek/tiko-di"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/tomas-samek/tiko-di","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomas-samek%2Ftiko-di","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomas-samek%2Ftiko-di/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomas-samek%2Ftiko-di/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomas-samek%2Ftiko-di/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tomas-samek","download_url":"https://codeload.github.com/tomas-samek/tiko-di/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tomas-samek%2Ftiko-di/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34020187,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-07T02:00:07.652Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["annotation-processor","compile-time","dependency-injection","event-driven","graalvm","ioc-container","java-21"],"created_at":"2026-06-07T12:00:43.932Z","updated_at":"2026-06-07T12:01:16.290Z","avatar_url":"https://github.com/tomas-samek.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Tiko DI\n\n\u003e A modern, compile-time dependency injection framework for Java 21+ with event-driven architecture\n\n[![Build](https://github.com/tomas-samek/tiko-di/actions/workflows/maven.yml/badge.svg?branch=main)](https://github.com/tomas-samek/tiko-di/actions/workflows/maven.yml)\n[![Java](https://img.shields.io/badge/Java-21%20%7C%2025%20%7C%2026-blue.svg)](https://www.oracle.com/java/)\n[![Maven](https://img.shields.io/badge/Maven-3.8+-red.svg)](https://maven.apache.org/)\n[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=tomas-samek_tiko-di\u0026metric=alert_status)](https://sonarcloud.io/summary/new_code?id=tomas-samek_tiko-di)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=tomas-samek_tiko-di\u0026metric=coverage)](https://sonarcloud.io/summary/new_code?id=tomas-samek_tiko-di)\n\n**Status: 0.1.0 on Maven Central.** Suitable for early-adopter experimentation. See [docs/roadmap.md](./docs/roadmap.md) for what ships today and what's next.\n\n## What Tiko is\n\nA **compile-time orchestrator** with an integrated event model and full compile-time validation.\n\n\u003e Tiko orchestrates, it doesn't bundle — direct access, compile-time safe, nothing wrapped.\n\nThe container, the scopes, the event bus, and the wiring graph ship as the framework. HTTP servers, databases, caches, template engines, security libraries, and any other library — you bring directly, and tiko orchestrates the seam via `@Produces`. Nothing is wrapped or rewritten on the library side; nothing is re-invented on the framework side.\n\nFor the longer pitch — design principles, three-layer architecture, event-pipeline trade-offs — see [docs/VISION.md](./docs/VISION.md).\n\n## The three buckets\n\nEvery concern in a tiko-built service lands in exactly one bucket. Classify, then write code.\n\n### Core — what tiko ships\n\nDI container, scopes (`SINGLETON` / `EVENT` / `PROTOTYPE`), event bus, `@EventHandler` + `@EventTrigger`, compile-time validation, lifecycle hooks (`@PostConstruct`, `@PreDestroy`, `ApplicationStartedEvent`, `ApplicationEndingEvent`), `@Configuration` typed records.\n\n### Plug in — you bring the library; tiko orchestrates the seam\n\nHTTP (Javalin, Jetty, Spark, Vert.x), DataSource (HikariCP, Agroal), schema migrations (Flyway, Liquibase), caching (Caffeine), templates (FreeMarker, Pebble), security (JWT / OAuth via the library of your choice), schedulers, retries, any SDK client. Pattern: declare a factory method annotated `@Produces`, return the library's value, consume as a constructor parameter. No wrapper, no adapter layer, no annotation-driven dispatch.\n\n### Open design questions\n\nAsync generalisation, scheduling-as-tick-event, retry-as-event-loop — the small set of unresolved questions about extending the event model itself. An honest scope note, not a deferral promise.\n\n## What you plug in\n\nLookup-table answer to \"does tiko support X?\":\n\n| Need | Pattern | Recipe in |\n|---|---|---|\n| HTTP layer | `@Produces Javalin` (or your choice) + plain route methods | `tiko-build` skill, example `15_quickstart` |\n| Postgres / MySQL | `@Produces DataSource` returning `HikariDataSource` | `tiko-build` skill, example `15_quickstart` |\n| Schema migrations | `@EventHandler(ApplicationStartedEvent)` calling `Flyway.migrate()` | `tiko-build` skill, example `15_quickstart` |\n| Kafka | `@KafkaSource` / `@KafkaSink` — tiko-native module with compile-time validation | `tiko-kafka`, example `08_kafka_order_warehouse` |\n| In-process cache | `@Produces Cache\u003cK,V\u003e` (Caffeine) | `tiko-build` skill |\n| Templates | `@Produces freemarker.template.Configuration` (or Pebble, Mustache) | `tiko-build` skill |\n| Security | Javalin `before` handler + `Context` attributes (open-design caveat in skill §6) | `tiko-build` skill §6 |\n| Scheduling | `@EventHandler` on a `Tick` event published by a small scheduler thread | `tiko-build` skill §4.2 |\n| Async work | `@EventHandler(async = true)` for event-shaped work; `CompletableFuture` / virtual threads for ad-hoc | `tiko-build` skill §4.3 |\n| Retry | Small utility wrapper — visible code, no AOP | `tiko-build` skill §4.4 |\n| Configuration | Typed `@Configuration` records | `tiko-config`, example `02_config` |\n| Metrics / tracing | Plug in your library; expose via routes on your HTTP layer | — |\n\n## Start building\n\n- **New service?** Read [`.ai-skills/tiko-build/SKILL.md`](./.ai-skills/tiko-build/SKILL.md) — decision tree, `@Produces` cookbook, anti-pattern redirect table so an agent reaches for the tiko-native primitive.\n- **Long-form prose?** [`docs/orchestrator-model.md`](./docs/orchestrator-model.md).\n- **Reference shape?** [`tiko-examples/15_quickstart`](./tiko-examples/15_quickstart) — the canonical small service the skill cites.\n- **Scaffold a fresh project?** Maven archetype — see [Scaffold a new project](#scaffold-a-new-project-archetype) below.\n- **Library not in the cookbook?** Read [`.ai-skills/tiko-cookbook-extension/SKILL.md`](./.ai-skills/tiko-cookbook-extension/SKILL.md) — the procedural skill for adding a new recipe. Load-bearing rule: **ask, don't fabricate.**\n\n## Quick example\n\n```java\n// 1. Define your components\n@Component(scope = Scope.SINGLETON)\npublic class UserRepository {\n    public User findById(String id) { /* ... */ return null; }\n}\n\n@Component(scope = Scope.SINGLETON)\npublic class UserService {\n    private final UserRepository repository;\n\n    @Inject\n    public UserService(UserRepository repository) {\n        this.repository = repository;\n    }\n\n    public User getUser(String id) {\n        return repository.findById(id);\n    }\n}\n\n// 2. Use the container\npublic class Main {\n    public static void main(String[] args) {\n        try (Container container = Tiko.create()) {\n            UserService service = container.get(UserService.class);\n            User user = service.getUser(\"123\");\n        }\n    }\n}\n```\n\nThe annotation processor validates all dependencies at compile-time and generates the wiring code. Nothing runs by reflection.\n\n## Installation\n\nTiko ships to Maven Central as of 0.1.0 — pull the artifacts directly:\n\n```xml\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eio.github.tomas-samek\u003c/groupId\u003e\n        \u003cartifactId\u003etiko-api\u003c/artifactId\u003e\n        \u003cversion\u003e0.1.0\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eio.github.tomas-samek\u003c/groupId\u003e\n        \u003cartifactId\u003etiko-runtime\u003c/artifactId\u003e\n        \u003cversion\u003e0.1.0\u003c/version\u003e\n    \u003c/dependency\u003e\n    \u003c!-- Optional, only if you use @Configuration --\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eio.github.tomas-samek\u003c/groupId\u003e\n        \u003cartifactId\u003etiko-config\u003c/artifactId\u003e\n        \u003cversion\u003e0.1.0\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n\n\u003cbuild\u003e\n    \u003cplugins\u003e\n        \u003cplugin\u003e\n            \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n            \u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n            \u003cversion\u003e3.13.0\u003c/version\u003e\n            \u003cconfiguration\u003e\n                \u003cannotationProcessorPaths\u003e\n                    \u003cpath\u003e\n                        \u003cgroupId\u003eio.github.tomas-samek\u003c/groupId\u003e\n                        \u003cartifactId\u003etiko-processor\u003c/artifactId\u003e\n                        \u003cversion\u003e0.1.0\u003c/version\u003e\n                    \u003c/path\u003e\n                \u003c/annotationProcessorPaths\u003e\n            \u003c/configuration\u003e\n        \u003c/plugin\u003e\n    \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\n\u003e **On JDK 23+?** `javac` no longer runs annotation processing implicitly — the snippet above is already correct (it requires `maven-compiler-plugin` ≥ 3.13.0). For Gradle, plain `javac`, and the legacy `\u003cproc\u003efull\u003c/proc\u003e` opt-in, see [docs/jdk-23-setup.md](./docs/jdk-23-setup.md).\n\n### Scaffold a new project (archetype)\n\nThe fastest way to start a fresh project — generates a runnable single-module Tiko DI project with a minimal `Main` + one `@Component`, plus AI-assistant context files:\n\n```bash\nmvn archetype:generate \\\n    -DarchetypeGroupId=io.github.tomas-samek \\\n    -DarchetypeArtifactId=tiko-archetype \\\n    -DarchetypeVersion=0.1.0 \\\n    -DgroupId=com.example \\\n    -DartifactId=my-app \\\n    -DinteractiveMode=false\n\ncd my-app\nmvn exec:java   # prints: Hello, world!\n```\n\nThe generated project ships with AI-context files for the major coding agents — `CLAUDE.md` (canonical), `AGENTS.md`, `.cursor/rules/tiko.md`, `.github/copilot-instructions.md`, `.junie/guidelines.md`, `.ai-skills/SKILL.md`, and `.ai-skills/tiko-build/SKILL.md` (the orchestrator-model skill — decision tree + `@Produces` cookbook + anti-pattern redirects). Each tool-specific file points at the canonical sources, so edit one file when conventions change.\n\n### AI-agent topology server (MCP)\n\nEvery Tiko build emits machine-readable topology + config schema to\n`META-INF/tiko/`. The `tiko-mcp` companion jar exposes them to any\nMCP-aware coding agent (Claude Code, Cursor, …):\n\n    java -jar tiko-mcp.jar /path/to/your/project\n\nThe metadata ships inside the jar so MCP can also introspect Tiko\ndependencies you didn't build yourself. To suppress emission for a\nmodule (closed-source service, sensitive jars), add\n`-Atiko.topology.bundle=false` to the annotation processor args.\n\nSee [`tiko-examples/13_mcp_introspection`](./tiko-examples/13_mcp_introspection)\nfor a runnable demo. Projects scaffolded from `tiko-archetype` ship a\nready-to-use `.mcp.json` (jbang-resolved) — MCP-aware agents auto-connect\non open with no setup beyond installing jbang.\n\n## Annotations at a glance\n\n| Annotation                          | Purpose                                                                  | Deep dive                              |\n|-------------------------------------|--------------------------------------------------------------------------|----------------------------------------|\n| `@Component(scope, name, profiles)` | Marks a class for DI                                                     | [di-and-scopes.md](./docs/di-and-scopes.md) |\n| `@Inject`                           | Marks the constructor to wire (constructor-only — no field injection)    | [di-and-scopes.md](./docs/di-and-scopes.md) |\n| `@Named(\"...\")` / `@Pick(Class)`    | Disambiguate when multiple impls exist (string vs class-literal)         | [di-and-scopes.md](./docs/di-and-scopes.md#qualifiers--named-pick-pickert-pick) |\n| `@Produces(scope, name, profiles)`  | Factory method — instance or static                                      | [di-and-scopes.md](./docs/di-and-scopes.md#produces-factory-methods) |\n| `@PostConstruct` / `@PreDestroy`    | Lifecycle hooks (`AutoCloseable` is the recommended cleanup form)        | [di-and-scopes.md](./docs/di-and-scopes.md#lifecycle-hooks) |\n| `@Configuration(prefix)`            | Marks a record as a YAML-backed config root                              | [configuration.md](./docs/configuration.md) |\n| `@EventHandler(async, eventType)`   | Subscribe to events (sync by default, opt-in async)                      | [events.md](./docs/events.md) |\n| `@EventTrigger(eventName, ...)`     | Declarative event chains — return-as-payload, guards, spread, async      | [events.md](./docs/events.md#event-chains-with-eventtrigger) |\n\nScopes: `SINGLETON` \u003e `EVENT` \u003e `PROTOTYPE` (longest to shortest lifetime). Shorter-lived beans injected into longer-lived scopes are automatically proxied — see [docs/di-and-scopes.md](./docs/di-and-scopes.md#cross-scope-injection).\n\n## Runnable examples\n\nFifteen worked examples ship under [`tiko-examples/`](./tiko-examples/README.md), each a self-contained Maven project:\n\n| #  | Module                                                              | Demonstrates                                                                                            |\n|----|---------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|\n| 01 | [`01_basic_di`](./tiko-examples/01_basic_di)                        | `@Component`, scopes, cross-scope proxies, `@Produces`, `@Named`, `@Pick`, `Provider\u003cT\u003e`, `Picker\u003cT\u003e`, `pick()` |\n| 02 | [`02_config`](./tiko-examples/02_config)                            | `@Configuration` records, layered `ConfigSources`, `${VAR}` interpolation                               |\n| 03 | [`03_events`](./tiko-examples/03_events)                            | Lifecycle events, `@EventTrigger` chains with guards/spread/async, `Event\u003c?\u003e` origin tracking           |\n| 04 | [`04_api_impl`](./tiko-examples/04_api_impl)                        | API/impl split — app compiles against an interface jar, impl supplied at runtime                        |\n| 05 | [`05_multi_module`](./tiko-examples/05_multi_module)                | Multi-module aggregation via `AggregatingContainer`                                                     |\n| 06 | [`06_config_multi_module`](./tiko-examples/06_config_multi_module)  | Module-baked `META-INF/tiko/defaults.yaml` discovery + user override                                    |\n| 07 | [`07_async_start`](./tiko-examples/07_async_start)                  | `@EventHandler(async = true)` on `ApplicationStartedEvent` — keep slow warmup off the critical path     |\n| 08 | [`08_kafka_order_warehouse`](./tiko-examples/08_kafka_order_warehouse) | Cross-JVM Kafka demo — `@KafkaSource` / `@KafkaSink`, shared event class, Testcontainers e2e         |\n| 09 | [`09_http_javalin`](./tiko-examples/09_http_javalin)                | `TikoJavalin.scoped` middleware opens an EVENT scope per route; sync request→response independent of the bus |\n| 10 | [`10_persistence_jdbc`](./tiko-examples/10_persistence_jdbc)        | Persistence cookbook — EVENT-scoped JDBC transactions across HTTP and batch flows ([docs](./docs/cookbooks/persistence.md)) |\n| 11 | [`11_custom_logger`](./tiko-examples/11_custom_logger)              | Routing framework logs through slf4j + logback via `System.LoggerFinder`                                |\n| 12 | [`12_testing`](./tiko-examples/12_testing)                          | `@TikoTest` JUnit 5 extension — parameter resolution, `RecordingEventBus` assertions, scope helpers, `awaitAsyncDispatch` |\n| 13 | [`13_mcp_introspection`](./tiko-examples/13_mcp_introspection)      | Runnable demo of the `tiko-mcp` topology server reading a built project's `META-INF/tiko/` artifacts |\n| 14 | [`14_profiles`](./tiko-examples/14_profiles)                        | `@Component(profiles = \"...\")` — dev/prod implementation switching with default-profile resolution |\n| 15 | [`15_quickstart`](./tiko-examples/15_quickstart)                    | **Orchestrator-model reference app** — HikariCP + Javalin + event-driven handler the `tiko-build` skill cites |\n\n## Measured cold-start\n\nThe `comparisons/` directory holds eight self-contained, side-by-side implementations of the same four-singleton, two-module workload — plain Java (no DI), Tiko, Dagger 2, Avaje Inject, HK2, Guice, Spring, and Micronaut (`micronaut-inject` only). Median of 10 cold JVM invocations, default JVM, default GC, Java 21, on a development laptop. **These numbers move on different hardware** — re-run locally before drawing conclusions.\n\n| Framework                        | Wall-clock (ms) | `total_ns` (ms) | Style                      |\n|----------------------------------|----------------:|----------------:|----------------------------|\n| _jvm baseline (`java -version`)_ |             104 |               — | —                          |\n| plain (no DI)                    |             172 |              36 | floor reference            |\n| **dagger**                       |         **186** |          **44** | compile-time, lazy         |\n| **tiko**                         |         **202** |          **61** | compile-time, lazy         |\n| avaje                            |             228 |             105 | compile-time, eager        |\n| hk2                              |             307 |             159 | runtime, reflection, lazy  |\n| guice                            |             373 |             230 | runtime, reflection, lazy  |\n| micronaut (inject-only)          |             459 |             308 | compile-time, eager + AOP  |\n| spring                           |             529 |             368 | runtime, reflection, eager |\n\nThe `total_ns` column sums the four phases the bench measures (`create + first_get_a + first_get_b + close`) and is the apples-to-apples comparison: it accounts for both eager (Avaje, Spring, Micronaut) and lazy (Tiko, Dagger, Guice, HK2) initialisation strategies. See [`comparisons/README.md`](./comparisons/README.md) for full per-phase tables, methodology, caveats, and reproduction.\n\nThe honest reading: the dominant axis is **lazy vs eager init**, not \"compile-time vs runtime.\" Four clusters emerge — lean compile-time-lazy (plain, Dagger, Tiko at 36–61 ms `total_ns`), compile-time-eager (Avaje at 105 ms), runtime-reflection-lazy (HK2, Guice at 159–230 ms), and eager-with-overhead (Micronaut, Spring at 308–368 ms). Within each laziness class the compile-time framework is cheaper (Tiko \u003c Guice; Avaje \u003c Spring), but Avaje (compile-time + eager) is slower than HK2 and Guice (runtime + lazy) — eagerness costs more than reflection saves at this scale.\n\n## Modules\n\n| Module                  | Purpose                                                                                                                                            |\n|-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|\n| `tiko-api`              | Core annotations and interfaces. The only compile-time dependency your code needs.                                                                 |\n| `tiko-processor`        | Annotation processor — runs at compile-time to validate dependencies and generate wiring code.                                                     |\n| `tiko-runtime`          | Minimal runtime container. Zero dependencies beyond `tiko-api`. Ships the in-memory `LocalEventBus`.                                               |\n| `tiko-config`           | YAML-backed configuration injection. The only module that depends on SnakeYAML. Required when your project uses `@Configuration`; not pulled otherwise. |\n| `tiko-test`             | JUnit 5 extension + compile-time `@TestComponent` overrides + runtime `TikoOptions.override(...)` + `RecordingEventBus` spy. Test-scope dependency only. |\n| `tiko-kafka` + `tiko-kafka-processor` | Kafka transport via the universal `TransportBootstrap` SPI — `@KafkaSource` / `@KafkaSink`, JSON serializer, per-record commit + seek-back. Opt-in. |\n| `tiko-archetype`        | Maven archetype that scaffolds a runnable single-module Tiko project in seconds.                                                                   |\n| `tiko-bom`              | Bill-of-materials for version-aligned dependency management.                                                                                       |\n\nEvent abstractions (`EventBus`, `EventCallback`, `Subscription`, `@EventHandler`, `@EventTrigger`, `Event\u003cT\u003e`) live in `tiko-api`; the in-memory implementation lives in `tiko-runtime`. Kafka ships as a separate, opt-in module pair (`tiko-kafka` + `tiko-kafka-processor`); further transports (RabbitMQ, JMS) are planned under Phase 8.\n\n## Logging\n\nTiko logs through `java.lang.System.Logger` — the JDK-standard SPI introduced in\nJava 9. There is no tiko-side configuration knob, no SPI to implement, no\nadapter module.\n\n**Default:** routes through `java.util.logging`. Nothing to configure for \"just works.\"\n\n**Routing to slf4j:** add `slf4j-jdk-platform-logging` + your slf4j backend\n(logback, log4j-slf4j2-impl, slf4j-simple, etc.). See\n[`tiko-examples/11_custom_logger`](./tiko-examples/11_custom_logger) for a\nrunnable example.\n\n**Routing to log4j2:** add `log4j-jpl` + the log4j2 core. Same mechanism, different bridge.\n\n**Routing to JBoss Logging:** JBoss Logging uses `JulLogManager` rather than a\n`LoggerFinder` — set `-Djava.util.logging.manager=org.jboss.logmanager.LogManager`.\n\nThe single tiko-side knob remains `TikoOptions.errorHandler(...)` for handler-exception\npolicy — a different layer than framework logging.\n\n## Documentation\n\n| Document                                              | What's in it                                                                                |\n|-------------------------------------------------------|---------------------------------------------------------------------------------------------|\n| [docs/VISION.md](./docs/VISION.md)                    | Long-form pitch, design principles, three-layer architecture, event-pipeline trade-offs.    |\n| [docs/di-and-scopes.md](./docs/di-and-scopes.md)      | Full DI reference — scopes, cross-scope proxies, lifecycle hooks, qualifiers, `@Produces`.  |\n| [docs/configuration.md](./docs/configuration.md)      | `@Configuration` deep-dive — nested records, layered sources, module-baked defaults.        |\n| [docs/events.md](./docs/events.md)                    | Event bus, error handling, async executor, lifecycle events, `@EventTrigger` chains.        |\n| [docs/testing.md](./docs/testing.md)                  | `tiko-test` JUnit 5 extension — `@TikoTest`, parameter resolution, `RecordingEventBus`, scope helpers, known limitations. |\n| [docs/jdk-23-setup.md](./docs/jdk-23-setup.md)        | Annotation processing on JDK 23+ — Maven / Gradle / plain `javac`.                          |\n| [docs/roadmap.md](./docs/roadmap.md)                  | What ships today, what's planned per phase, known limitations.                              |\n| [docs/release-process.md](./docs/release-process.md)  | Release engineering notes (maintainers).                                                    |\n| [docs/qa-playbook.md](./docs/qa-playbook.md)          | Structured QA passes over the framework + examples; issue body template; rules for what to file and what not to. |\n| [docs/issue-fix-playbook.md](./docs/issue-fix-playbook.md) | Counterpart to the QA playbook — how to work a filed issue without anchoring on its framing. Four-phase fix workflow + common traps. |\n| [comparisons/README.md](./comparisons/README.md)      | Side-by-side cold-start benchmarks across 8 DI frameworks.                                  |\n| [docs/superpowers/specs/2026-05-12-kafka-event-bus-design.md](./docs/superpowers/specs/2026-05-12-kafka-event-bus-design.md) | Kafka event bus design — universal transport adapter pattern. |\n\n## Roadmap (summary)\n\n- **Phase 1 — Alpha completion.** ✅ Closed. Core DI, scopes, lifecycle events, `@EventTrigger` chains, multi-module aggregation.\n- **Phase 2 — Configuration \u0026 distributed events.** ✅ Closed. `@Configuration` v1 + nested records + `Set\u003cX\u003e` + YAML source anchors, Kafka transport, `ErrorContext` hook, async event executor + shutdown timeout, `System.Logger` migration.\n- **Phase 3 — Onboarding \u0026 tooling.** ✅ Closed (30/30 issues, a week ahead of due date). AI-assistant-aware archetype, `tiko-test` JUnit 5 module, machine-readable topology + nine-tool MCP server, plus the QA pass #1 follow-ups: examples README cleanup, slf4j routing fix, `@PreDestroy` LIFO contract honoured across `@Component` and `@Produces`, project-wide `maven-failsafe-plugin` wiring, dotted-prefix `@Configuration` now binds naturally-nested YAML. QA discipline codified in [qa-playbook.md](./docs/qa-playbook.md) + [issue-fix-playbook.md](./docs/issue-fix-playbook.md).\n- **Phase 4 — Runtime hardening (in progress).** Structured `RuntimeException` subtypes, checked-exception propagation through `@Produces` / `@PostConstruct` (✅), framework-managed JVM shutdown hook, JaCoCo coverage + SonarCloud static analysis. AOP / metrics / GraalVM dropped from scope until a concrete driver appears.\n- **Phase 5 — Publish to Maven Central.** POM metadata, GPG signing, sources/javadoc jars, `central-publishing-maven-plugin` + CI deploy, and the `@Named` vs `@Pick` API decision. Pulled early so a lean, validated core ships before the heavier feature work.\n- **Phase 6 — MCP enrichment.** `get_generated_artifact`, a lifecycle-hook query tool, and richer proxy topology — deeper introspection of the compile-time graph.\n- **Phase 7 — Resiliency layer.** Timeouts, retries, bounded-queue backpressure, executor pool knobs, DLQ for failed/timed-out events.\n- **Phase 8 — Distributed transports.** RabbitMQ + JMS adapters, `TransportBootstrap` SPI audit, pluggable serializer SPI.\n- **Phase 9 — Examples \u0026 docs polish.** Advanced-feature example gaps (`@EventTriggers`, scoped suppliers, origin chain, `TikoOptions`) plus public-docs tightening.\n\nFull detail in [docs/roadmap.md](./docs/roadmap.md).\n\n## Building from source\n\n```bash\ngit clone https://github.com/tomas-samek/tiko-di.git\ncd tiko-di\nmvn clean install              # build all modules\nmvn test                       # run tests\nmvn clean install -DskipTests  # build without tests\nmvn clean install -pl tiko-api # build specific module\n```\n\nRequires Java 21+ and Maven 3.8+.\n\n## Philosophy\n\n1. **Compile-time safety.** Catch all errors the compiler can see. The only runtime exceptions Tiko throws fire at container startup — never during `container.get(...)` in a running application.\n2. **Simplicity.** Minimal concepts, intuitive API.\n3. **Explicitness.** No magic, generated code is readable.\n4. **Performance.** Zero reflection, fast startup, low memory.\n5. **Modularity.** Use only what you need.\n6. **Event-driven.** First-class support for decoupled communication.\n\n## Contributing\n\nContributions are welcome. Open issues or pull requests on GitHub.\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes\n4. Push to the branch\n5. Open a Pull Request\n\nBug reports should include Java version, Maven version, and a minimal reproducer. State symptoms and observable facts only — no \"probable cause\" or \"suggested fix\" sections, those bias whoever picks the issue up. The full format and rationale are in [docs/qa-playbook.md](./docs/qa-playbook.md); the counterpart workflow for working a filed issue is [docs/issue-fix-playbook.md](./docs/issue-fix-playbook.md).\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n## Acknowledgments\n\nBuilt on lessons learned from existing DI frameworks:\n\n- **Dagger 2** — compile-time validation approach\n- **Guice** — clean, type-safe API design\n- **Spring** — comprehensive feature set and ecosystem thinking\n- **Micronaut** — cloud-native optimization strategies\n\n## Contact\n\nTomas Samek — [GitHub](https://github.com/tomas-samek)\n\nProject: \u003chttps://github.com/tomas-samek/tiko-di\u003e\n\n---\n\n**Tiko** — Compile-time dependency injection for Java 21+, with first-class event handling.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomas-samek%2Ftiko-di","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomas-samek%2Ftiko-di","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomas-samek%2Ftiko-di/lists"}