# ComponentContextFactory in Decompose: How It Creates Isolated Child Component Contexts

> Learn how ComponentContextFactory in Decompose creates isolated child component contexts using Lifecycle StateKeeper InstanceKeeper and BackHandler services. Understand its role in component management.

- Repository: [Arkadii Ivanov/decompose](https://github.com/arkivanov/decompose)
- Tags: internals
- Published: 2026-02-25

---

**ComponentContextFactory is a functional interface in the Decompose library that constructs isolated component contexts for child components by combining Lifecycle, StateKeeper, InstanceKeeper, and BackHandler services.**

When building navigation flows in Decompose (arkivanov/decompose), parent components must spawn child components with their own isolated lifecycles and state management. The ComponentContextFactory centralizes this creation logic, ensuring every child receives properly configured Essenty services without tight coupling to specific context implementations.

## What Is ComponentContextFactory?

Located in [`decompose/src/commonMain/kotlin/com/arkivanov/decompose/ComponentContextFactory.kt`](https://github.com/arkivanov/decompose/blob/main/decompose/src/commonMain/kotlin/com/arkivanov/decompose/ComponentContextFactory.kt), ComponentContextFactory is a functional interface that knows how to build a new component context from the four Essenty services required by every Decompose component.

| Parameter | Purpose |
|-----------|---------|
| `Lifecycle` | Controls the start/stop lifecycle of the component. |
| `StateKeeper` | Persists state across process recreation. |
| `InstanceKeeper` | Holds singleton‑like objects for the component’s whole lifetime. |
| `BackHandler` | Handles back‑button events (Android) or other “back” actions. |

```kotlin
fun interface ComponentContextFactory<out T : Any> {
    operator fun invoke(
        lifecycle: Lifecycle,
        stateKeeper: StateKeeper,
        instanceKeeper: InstanceKeeper,
        backHandler: BackHandler,
    ): T
}

```

## Why ComponentContextFactory Is Required for Child Components

When a navigation model (e.g., a `Router`, a `StackNavigator`, or a `ChildSlotNavigator`) creates a child component, it must provide that child with an isolated context containing its own lifecycle, state‑keeping, instance‑keeping, and back‑handling. The factory encapsulates the creation logic so the navigation model does not need to know the concrete type of the context (plain `ComponentContext`, `JetpackComponentContext`, or any custom implementation).

- **Decoupling:** The navigation infrastructure works with the abstract `ComponentContextFactory<T>` rather than a concrete context class.
- **Customization:** Apps can supply their own factory (e.g., to create a `JetpackComponentContext` that also exposes a `SavedStateHandle`).
- **Testability:** Tests can inject a simple factory returning `DefaultComponentContext` to verify navigation behavior.

## How ComponentContextFactory Works in Practice

### Default Factory Usage in Parent Components

The default implementation of `ComponentContext` provides its own factory via `ComponentContextFactoryOwner`. In [`DefaultComponentContext.kt`](https://github.com/arkivanov/decompose/blob/main/DefaultComponentContext.kt), the factory is exposed so parent components can create isolated child contexts.

```kotlin
class RootComponent(
    componentContext: ComponentContext
) : ComponentContextOwner by componentContext {

    // Router that will create child components
    private val router = router<Config, Child>(initialStack = listOf(Config.First))

    // The factory comes from the parent context (DefaultComponentContext)
    private val childFactory = componentContext.componentContextFactory

    private fun createChild(config: Config): Child {
        // Build a fresh child context using the factory
        val childContext = childFactory(
            lifecycle = LifecycleRegistry(),
            stateKeeper = StateKeeper(),
            instanceKeeper = InstanceKeeper(),
            backHandler = BackHandler()
        )
        return Child(childContext, config)
    }
}

```

### Custom Factory for Jetpack Integration

For Android Jetpack integration, [`DefaultJetpackComponentContext.kt`](https://github.com/arkivanov/decompose/blob/main/DefaultJetpackComponentContext.kt) supplies a factory that creates `JetpackComponentContext` objects. This allows child components to access Jetpack‑specific APIs like `SavedStateHandle` while maintaining the same creation pattern.

```kotlin
class JetpackRootComponent(
    componentContext: JetpackComponentContext
) : ComponentContextOwner by componentContext {

    // Use the Jetpack‑specific factory
    private val childFactory: ComponentContextFactory<JetpackComponentContext> =
        componentContext.componentContextFactory

    private fun createJetpackChild(): JetpackChild {
        val childContext = childFactory(
            lifecycle = componentContext.lifecycle,
            stateKeeper = componentContext.stateKeeper,
            instanceKeeper = componentContext.instanceKeeper,
            backHandler = componentContext.backHandler
        )
        return JetpackChild(childContext)
    }
}

```

### Testing with Factory Injection

In unit tests, you can inject a simple factory that returns `DefaultComponentContext` instances. This is demonstrated in the test utilities where `ComponentContextFactory` enables verification of router behavior without requiring full Android infrastructure.

```kotlin
class RouterTest {

    // Simple factory that creates a DefaultComponentContext
    private val testFactory = ComponentContextFactory(::DefaultComponentContext)

    @Test
    fun `router creates child with proper context`() {
        val router = TestRouter(
            factory = testFactory,
            childFactory = { ctx, config -> TestChild(ctx, config) }
        )
        // ...assertions about lifecycle, stateKeeper etc.
    }
}

```

## Key Implementation Files

| File | Role |
|------|------|
| [[`ComponentContextFactory.kt`](https://github.com/arkivanov/decompose/blob/main/ComponentContextFactory.kt)](https://github.com/arkivanov/decompose/blob/master/decompose/src/commonMain/kotlin/com/arkivanov/decompose/ComponentContextFactory.kt) | Defines the functional interface that creates component contexts. |
| [[`ComponentContextFactoryOwner.kt`](https://github.com/arkivanov/decompose/blob/main/ComponentContextFactoryOwner.kt)](https://github.com/arkivanov/decompose/blob/master/decompose/src/commonMain/kotlin/com/arkivanov/decompose/ComponentContextFactoryOwner.kt) | Interface for objects that expose a `ComponentContextFactory`. |
| [[`DefaultComponentContext.kt`](https://github.com/arkivanov/decompose/blob/main/DefaultComponentContext.kt)](https://github.com/arkivanov/decompose/blob/master/decompose/src/commonMain/kotlin/com/arkivanov/decompose/DefaultComponentContext.kt) | Standard implementation of a component context and its factory. |
| [[`DefaultChildItemFactory.kt`](https://github.com/arkivanov/decompose/blob/main/DefaultChildItemFactory.kt)](https://github.com/arkivanov/decompose/blob/master/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/children/DefaultChildItemFactory.kt) | Uses a `ComponentContextFactory` to create child contexts for navigation models. |
| [[`DefaultJetpackComponentContext.kt`](https://github.com/arkivanov/decompose/blob/main/DefaultJetpackComponentContext.kt)](https://github.com/arkivanov/decompose/blob/master/jetpack-component-context/src/commonMain/kotlin/com/arkivanov/decompose/jetpackcomponentcontext/DefaultJetpackComponentContext.kt) | Example of a custom context type with its own factory. |
| [[`TestComponentContext.kt`](https://github.com/arkivanov/decompose/blob/main/TestComponentContext.kt)](https://github.com/arkivanov/decompose/blob/master/decompose-test-utils/src/commonMain/kotlin/com/arkivanov/decompose/testutils/TestComponentContext.kt) | Shows how the factory is used in test utilities. |

## Summary

- **ComponentContextFactory** is a functional interface in [`ComponentContextFactory.kt`](https://github.com/arkivanov/decompose/blob/main/ComponentContextFactory.kt) that constructs component contexts from four Essenty services: `Lifecycle`, `StateKeeper`, `InstanceKeeper`, and `BackHandler`.
- It enables **decoupled child creation** by allowing navigation models to instantiate child components without knowing the concrete context type.
- The factory pattern supports **customization** for platform-specific implementations like `JetpackComponentContext` and improves **testability** through dependency injection.
- Routers use `ComponentContextFactory` via [`DefaultChildItemFactory.kt`](https://github.com/arkivanov/decompose/blob/main/DefaultChildItemFactory.kt) to ensure each child receives an isolated context with properly wired lifecycle and state management.

## Frequently Asked Questions

### What parameters does ComponentContextFactory require?

`ComponentContextFactory` accepts four parameters: a `Lifecycle` for controlling component start/stop states, a `StateKeeper` for persisting state across process recreation, an `InstanceKeeper` for holding singleton-like objects during the component's lifetime, and a `BackHandler` for managing back-button events. These parameters are defined in the `invoke` operator function in [`ComponentContextFactory.kt`](https://github.com/arkivanov/decompose/blob/main/ComponentContextFactory.kt).

### How does ComponentContextFactory differ from ComponentContext itself?

While `ComponentContext` is the interface that components implement to access lifecycle and state services, `ComponentContextFactory` is the functional interface responsible for creating those context instances. Think of `ComponentContext` as the container of services, and `ComponentContextFactory` as the builder that assembles new containers for each child component.

### Can I create a custom ComponentContextFactory for my own context type?

Yes, you can implement a custom `ComponentContextFactory` to create specialized context types like `JetpackComponentContext`. By implementing the functional interface and providing your own logic in the `invoke` operator, you can expose additional platform-specific APIs (such as Android's `SavedStateHandle`) while maintaining compatibility with Decompose's navigation infrastructure.

### Where is ComponentContextFactory used in the Decompose router?

The router uses `ComponentContextFactory` through [`DefaultChildItemFactory.kt`](https://github.com/arkivanov/decompose/blob/main/DefaultChildItemFactory.kt) to instantiate fresh contexts for each child in a navigation stack. When the router pushes a new configuration, it invokes the factory to create a child-specific `Lifecycle`, `StateKeeper`, `InstanceKeeper`, and `BackHandler`, ensuring proper isolation and lifecycle propagation between parent and child components.