diff --git a/Examples/xx-messenger/Sources/ContactsFeature/ContactsComponent.swift b/Examples/xx-messenger/Sources/ContactsFeature/ContactsComponent.swift
new file mode 100644
index 0000000000000000000000000000000000000000..a0ce4ed860b1dd45596fd70039aa1344b8deed76
--- /dev/null
+++ b/Examples/xx-messenger/Sources/ContactsFeature/ContactsComponent.swift
@@ -0,0 +1,105 @@
+import AppCore
+import ComposableArchitecture
+import ComposablePresentation
+import ContactFeature
+import Foundation
+import MyContactFeature
+import XCTestDynamicOverlay
+import XXClient
+import XXMessengerClient
+import XXModels
+
+public struct ContactsComponent: ReducerProtocol {
+  public struct State: Equatable {
+    public init(
+      myId: Data? = nil,
+      contacts: IdentifiedArrayOf<XXModels.Contact> = [],
+      contact: ContactComponent.State? = nil,
+      myContact: MyContactComponent.State? = nil
+    ) {
+      self.myId = myId
+      self.contacts = contacts
+      self.contact = contact
+      self.myContact = myContact
+    }
+
+    public var myId: Data?
+    public var contacts: IdentifiedArrayOf<XXModels.Contact>
+    public var contact: ContactComponent.State?
+    public var myContact: MyContactComponent.State?
+  }
+
+  public enum Action: Equatable {
+    case start
+    case didFetchContacts([XXModels.Contact])
+    case contactSelected(XXModels.Contact)
+    case contactDismissed
+    case contact(ContactComponent.Action)
+    case myContactSelected
+    case myContactDismissed
+    case myContact(MyContactComponent.Action)
+  }
+
+  public init() {}
+
+  @Dependency(\.app.messenger) var messenger: Messenger
+  @Dependency(\.app.dbManager.getDB) var db: DBManagerGetDB
+  @Dependency(\.app.mainQueue) var mainQueue: AnySchedulerOf<DispatchQueue>
+  @Dependency(\.app.bgQueue) var bgQueue: AnySchedulerOf<DispatchQueue>
+
+  public var body: some ReducerProtocol<State, Action> {
+    Reduce { state, action in
+      switch action {
+      case .start:
+        state.myId = try? messenger.e2e.tryGet().getContact().getId()
+        return Effect
+          .catching { try db() }
+          .flatMap { $0.fetchContactsPublisher(.init()) }
+          .assertNoFailure()
+          .map(Action.didFetchContacts)
+          .subscribe(on: bgQueue)
+          .receive(on: mainQueue)
+          .eraseToEffect()
+
+      case .didFetchContacts(var contacts):
+        if let myId = state.myId,
+           let myIndex = contacts.firstIndex(where: { $0.id == myId }) {
+          contacts.move(fromOffsets: [myIndex], toOffset: contacts.startIndex)
+        }
+        state.contacts = IdentifiedArray(uniqueElements: contacts)
+        return .none
+
+      case .contactSelected(let contact):
+        state.contact = ContactComponent.State(id: contact.id, dbContact: contact)
+        return .none
+
+      case .contactDismissed:
+        state.contact = nil
+        return .none
+
+      case .myContactSelected:
+        state.myContact = MyContactComponent.State()
+        return .none
+
+      case .myContactDismissed:
+        state.myContact = nil
+        return .none
+
+      case .contact(_), .myContact(_):
+        return .none
+      }
+    }
+    .presenting(
+      state: .keyPath(\.contact),
+      id: .keyPath(\.?.id),
+      action: /Action.contact,
+      presented: { ContactComponent() }
+    )
+    .presenting(
+      state: .keyPath(\.myContact),
+      id: .notNil(),
+      action: /Action.myContact,
+      presented: { MyContactComponent() }
+    )
+  }
+}
diff --git a/Examples/xx-messenger/Sources/ContactsFeature/ContactsFeature.swift b/Examples/xx-messenger/Sources/ContactsFeature/ContactsFeature.swift
deleted file mode 100644
index 680a231ec8cc9e6e13487a849a65941bda7a7428..0000000000000000000000000000000000000000
--- a/Examples/xx-messenger/Sources/ContactsFeature/ContactsFeature.swift
+++ /dev/null
@@ -1,135 +0,0 @@
-import AppCore
-import ComposableArchitecture
-import ComposablePresentation
-import ContactFeature
-import Foundation
-import MyContactFeature
-import XCTestDynamicOverlay
-import XXClient
-import XXMessengerClient
-import XXModels
-
-public struct ContactsState: Equatable {
-  public init(
-    myId: Data? = nil,
-    contacts: IdentifiedArrayOf<XXModels.Contact> = [],
-    contact: ContactState? = nil,
-    myContact: MyContactState? = nil
-  ) {
-    self.myId = myId
-    self.contacts = contacts
-    self.contact = contact
-    self.myContact = myContact
-  }
-
-  public var myId: Data?
-  public var contacts: IdentifiedArrayOf<XXModels.Contact>
-  public var contact: ContactState?
-  public var myContact: MyContactState?
-}
-
-public enum ContactsAction: Equatable {
-  case start
-  case didFetchContacts([XXModels.Contact])
-  case contactSelected(XXModels.Contact)
-  case contactDismissed
-  case contact(ContactAction)
-  case myContactSelected
-  case myContactDismissed
-  case myContact(MyContactAction)
-}
-
-public struct ContactsEnvironment {
-  public init(
-    messenger: Messenger,
-    db: DBManagerGetDB,
-    mainQueue: AnySchedulerOf<DispatchQueue>,
-    bgQueue: AnySchedulerOf<DispatchQueue>,
-    contact: @escaping () -> ContactEnvironment,
-    myContact: @escaping () -> MyContactEnvironment
-  ) {
-    self.messenger = messenger
-    self.db = db
-    self.mainQueue = mainQueue
-    self.bgQueue = bgQueue
-    self.contact = contact
-    self.myContact = myContact
-  }
-
-  public var messenger: Messenger
-  public var db: DBManagerGetDB
-  public var mainQueue: AnySchedulerOf<DispatchQueue>
-  public var bgQueue: AnySchedulerOf<DispatchQueue>
-  public var contact: () -> ContactEnvironment
-  public var myContact: () -> MyContactEnvironment
-}
-
-#if DEBUG
-extension ContactsEnvironment {
-  public static let unimplemented = ContactsEnvironment(
-    messenger: .unimplemented,
-    db: .unimplemented,
-    mainQueue: .unimplemented,
-    bgQueue: .unimplemented,
-    contact: { .unimplemented },
-    myContact: { .unimplemented }
-  )
-}
-#endif
-
-public let contactsReducer = Reducer<ContactsState, ContactsAction, ContactsEnvironment>
-{ state, action, env in
-  switch action {
-  case .start:
-    state.myId = try? env.messenger.e2e.tryGet().getContact().getId()
-    return Effect
-      .catching { try env.db() }
-      .flatMap { $0.fetchContactsPublisher(.init()) }
-      .assertNoFailure()
-      .map(ContactsAction.didFetchContacts)
-      .subscribe(on: env.bgQueue)
-      .receive(on: env.mainQueue)
-      .eraseToEffect()
-
-  case .didFetchContacts(var contacts):
-    if let myId = state.myId,
-       let myIndex = contacts.firstIndex(where: { $0.id == myId }) {
-      contacts.move(fromOffsets: [myIndex], toOffset: contacts.startIndex)
-    }
-    state.contacts = IdentifiedArray(uniqueElements: contacts)
-    return .none
-
-  case .contactSelected(let contact):
-    state.contact = ContactState(id: contact.id, dbContact: contact)
-    return .none
-
-  case .contactDismissed:
-    state.contact = nil
-    return .none
-
-  case .myContactSelected:
-    state.myContact = MyContactState()
-    return .none
-
-  case .myContactDismissed:
-    state.myContact = nil
-    return .none
-
-  case .contact(_), .myContact(_):
-    return .none
-  }
-}
-.presenting(
-  contactReducer,
-  state: .keyPath(\.contact),
-  id: .keyPath(\.?.id),
-  action: /ContactsAction.contact,
-  environment: { $0.contact() }
-)
-.presenting(
-  myContactReducer,
-  state: .keyPath(\.myContact),
-  id: .notNil(),
-  action: /ContactsAction.myContact,
-  environment: { $0.myContact() }
-)
diff --git a/Examples/xx-messenger/Sources/ContactsFeature/ContactsView.swift b/Examples/xx-messenger/Sources/ContactsFeature/ContactsView.swift
index e09725d92c84feeb7f8cb7da5dbc38cf9d998087..9813bc54bc84cf3191925e3b6db60e7ebefd9629 100644
--- a/Examples/xx-messenger/Sources/ContactsFeature/ContactsView.swift
+++ b/Examples/xx-messenger/Sources/ContactsFeature/ContactsView.swift
@@ -7,17 +7,17 @@ import SwiftUI
 import XXModels
 
 public struct ContactsView: View {
-  public init(store: Store<ContactsState, ContactsAction>) {
+  public init(store: StoreOf<ContactsComponent>) {
     self.store = store
   }
 
-  let store: Store<ContactsState, ContactsAction>
+  let store: StoreOf<ContactsComponent>
 
   struct ViewState: Equatable {
     var myId: Data?
     var contacts: IdentifiedArrayOf<XXModels.Contact>
 
-    init(state: ContactsState) {
+    init(state: ContactsComponent.State) {
       myId = state.myId
       contacts = state.contacts
     }
@@ -74,7 +74,7 @@ public struct ContactsView: View {
       .background(NavigationLinkWithStore(
         store.scope(
           state: \.contact,
-          action: ContactsAction.contact
+          action: ContactsComponent.Action.contact
         ),
         onDeactivate: { viewStore.send(.contactDismissed) },
         destination: ContactView.init(store:)
@@ -82,7 +82,7 @@ public struct ContactsView: View {
       .background(NavigationLinkWithStore(
         store.scope(
           state: \.myContact,
-          action: ContactsAction.myContact
+          action: ContactsComponent.Action.myContact
         ),
         onDeactivate: { viewStore.send(.myContactDismissed) },
         destination: MyContactView.init(store:)
@@ -96,7 +96,7 @@ public struct ContactsView_Previews: PreviewProvider {
   public static var previews: some View {
     NavigationView {
       ContactsView(store: Store(
-        initialState: ContactsState(
+        initialState: ContactsComponent.State(
           contacts: [
             .init(
               id: "1".data(using: .utf8)!,
@@ -115,8 +115,7 @@ public struct ContactsView_Previews: PreviewProvider {
             ),
           ]
         ),
-        reducer: .empty,
-        environment: ()
+        reducer: EmptyReducer()
       ))
     }
   }
diff --git a/Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsFeatureTests.swift b/Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsComponentTests.swift
similarity index 70%
rename from Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsFeatureTests.swift
rename to Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsComponentTests.swift
index 9b3ac0d080ad8e23b8359ab8b3cf073433bed7d8..e0732e698e2756cf77de98ec25d47eea9f375757 100644
--- a/Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsFeatureTests.swift
+++ b/Examples/xx-messenger/Tests/ContactsFeatureTests/ContactsComponentTests.swift
@@ -9,21 +9,20 @@ import XXMessengerClient
 import XXModels
 @testable import ContactsFeature
 
-final class ContactsFeatureTests: XCTestCase {
+final class ContactsComponentTests: XCTestCase {
   func testStart() {
     let store = TestStore(
-      initialState: ContactsState(),
-      reducer: contactsReducer,
-      environment: .unimplemented
+      initialState: ContactsComponent.State(),
+      reducer: ContactsComponent()
     )
 
     let myId = "2".data(using: .utf8)!
     var didFetchContacts: [XXModels.Contact.Query] = []
     let contactsPublisher = PassthroughSubject<[XXModels.Contact], Error>()
 
-    store.environment.mainQueue = .immediate
-    store.environment.bgQueue = .immediate
-    store.environment.messenger.e2e.get = {
+    store.dependencies.app.mainQueue = .immediate
+    store.dependencies.app.bgQueue = .immediate
+    store.dependencies.app.messenger.e2e.get = {
       var e2e: E2E = .unimplemented
       e2e.getContact.run = {
         var contact: XXClient.Contact = .unimplemented(Data())
@@ -32,7 +31,7 @@ final class ContactsFeatureTests: XCTestCase {
       }
       return e2e
     }
-    store.environment.db.run = {
+    store.dependencies.app.dbManager.getDB.run = {
       var db: Database = .unimplemented
       db.fetchContactsPublisher.run = { query in
         didFetchContacts.append(query)
@@ -67,28 +66,26 @@ final class ContactsFeatureTests: XCTestCase {
 
   func testSelectContact() {
     let store = TestStore(
-      initialState: ContactsState(),
-      reducer: contactsReducer,
-      environment: .unimplemented
+      initialState: ContactsComponent.State(),
+      reducer: ContactsComponent()
     )
 
     let contact = XXModels.Contact(id: "id".data(using: .utf8)!)
 
     store.send(.contactSelected(contact)) {
-      $0.contact = ContactState(id: contact.id, dbContact: contact)
+      $0.contact = ContactComponent.State(id: contact.id, dbContact: contact)
     }
   }
 
   func testDismissContact() {
     let store = TestStore(
-      initialState: ContactsState(
-        contact: ContactState(
+      initialState: ContactsComponent.State(
+        contact: ContactComponent.State(
           id: "id".data(using: .utf8)!,
           dbContact: Contact(id: "id".data(using: .utf8)!)
         )
       ),
-      reducer: contactsReducer,
-      environment: .unimplemented
+      reducer: ContactsComponent()
     )
 
     store.send(.contactDismissed) {
@@ -98,23 +95,21 @@ final class ContactsFeatureTests: XCTestCase {
 
   func testSelectMyContact() {
     let store = TestStore(
-      initialState: ContactsState(),
-      reducer: contactsReducer,
-      environment: .unimplemented
+      initialState: ContactsComponent.State(),
+      reducer: ContactsComponent()
     )
 
     store.send(.myContactSelected) {
-      $0.myContact = MyContactState()
+      $0.myContact = MyContactComponent.State()
     }
   }
 
   func testDismissMyContact() {
     let store = TestStore(
-      initialState: ContactsState(
-        myContact: MyContactState()
+      initialState: ContactsComponent.State(
+        myContact: MyContactComponent.State()
       ),
-      reducer: contactsReducer,
-      environment: .unimplemented
+      reducer: ContactsComponent()
     )
 
     store.send(.myContactDismissed) {