# Customizing Components

The SwiftUI SDK components are fully customizable and interchangeable through the `ViewFactory` protocol that holds all the reusable views of the SDK. You can find the full reference of the `ViewFactory` protocol [here](https://github.com/GetStream/stream-chat-swiftui/blob/v5/Sources/StreamChatSwiftUI/ViewFactory/ViewFactory.swift).

## View Factory

The `ViewFactory` protocol defines the swappable views of the chat experience. There are default implementations for all the views used in the SDK. If you want to customize a view, you will need to implement the `ViewFactory` protocol, but only implement the view you want to swap.

In most cases, your custom view only needs to conform to the standard SwiftUI `View` protocol and provide a `body` property, there's no need to implement additional lifecycle methods or protocols. The only exception is when customizing the navigation bar, where your custom view must conform to SwiftUI's `ToolbarContent` protocol.

### Options-Based API

All `ViewFactory` methods accept a single **Options** struct instead of individual parameters. Each Options struct groups together all the data and callbacks needed to create that view. This design makes it easy to add new parameters in future releases without breaking your existing implementations.

For example, if you want to change the default user avatar view that is used in multiple views, you implement the `makeUserAvatarView(options:)` slot in the `ViewFactory` protocol:

```swift
class CustomFactory: ViewFactory {

    @Injected(\.chatClient) public var chatClient

    public var styles = RegularStyles()

    private init() {}

    public static let shared = CustomFactory()

    func makeUserAvatarView(options: UserAvatarViewOptions) -> some View {
        CustomUserAvatarView(
            user: options.user,
            size: options.size
        )
    }
}
```

Afterwards, you need to inject the `CustomFactory` in your view. To do this, you pass the newly created factory to the `ChatChannelListView`. If you are only using the `ChatChannelView`, you can pass the factory to it instead.

```swift
var body: some Scene {
    WindowGroup {
        ChatChannelListView(viewFactory: CustomFactory.shared)
    }
}
```

And that's everything needed to provide custom views for the SwiftUI SDK.

<admonition type="tip">

The `ViewFactory` protocol is generic over the views that it can replace, and there is no usage of `AnyView`. This allows SwiftUI to compute the diffing of the views faster and more accurately without any performance overhead.

</admonition>

## Styles

In addition to `ViewFactory`, the SDK provides a `Styles` protocol that controls the overall look and layout of key UI surfaces. Every `ViewFactory` has a `styles` property that you can set to control styling independently from view swapping.

The two built-in implementations are:

| Style               | Composer placement      | Look                |
| ------------------- | ----------------------- | ------------------- |
| `RegularStyles`     | Docked at the bottom    | Classic chat UI     |
| `LiquidGlassStyles` | Floating above keyboard | iOS 26 Liquid Glass |

To use a particular style, set the `styles` property on your factory:

```swift
class CustomFactory: ViewFactory {

    @Injected(\.chatClient) public var chatClient

    public var styles = LiquidGlassStyles()

    private init() {}

    public static let shared = CustomFactory()
}
```

You can also create your own custom `Styles` implementation to override specific parts:

```swift
class CustomStyles: Styles {
    var composerPlacement: ComposerPlacement = .docked

    func makeComposerInputViewModifier(options: ComposerInputModifierOptions) -> some ViewModifier {
        MyInputModifier()
    }

    func makeComposerButtonViewModifier(options: ComposerButtonModifierOptions) -> some ViewModifier {
        MyButtonModifier()
    }

    func makeScrollToBottomButtonModifier(options: ScrollToBottomButtonModifierOptions) -> some ViewModifier {
        MyScrollToBottomModifier()
    }

    func makeComposerViewModifier(options: ComposerViewModifierOptions) -> some ViewModifier {
        MyComposerBackgroundModifier()
    }

    func makeSuggestionsContainerModifier(options: SuggestionsContainerModifierOptions) -> some ViewModifier {
        MySuggestionsModifier()
    }

    func makeSearchableModifier(options: SearchableModifierOptions) -> some ViewModifier {
        DefaultSearchableModifier(
            searchText: options.searchText,
            prompt: "Search"
        )
    }
}
```

The full list of `Styles` hooks includes:

- `makeComposerInputViewModifier` – modifier applied to the composer text input area.
- `makeComposerButtonViewModifier` – modifier applied to composer action buttons.
- `makeScrollToBottomButtonModifier` – modifier applied to the scroll-to-bottom button.
- `makeComposerViewModifier` – modifier applied to the whole composer container.
- `makeSuggestionsContainerModifier` – modifier applied to the suggestions overlay.
- `makeChannelListContentModifier` – modifier for the full channel list content area.
- `makeChannelListModifier` – modifier applied to the channel list itself.
- `makeSearchableModifier` – modifier applied to built-in search UI such as the channel list search.
- `makeMessageListModifier` – modifier applied to the message list.
- `makeMessageListContainerModifier` – modifier applied to the message list container.
- `makeMessageViewModifier` – modifier applied to each individual message bubble.
- `makeMessageAttachmentsViewModifier` – modifier applied to the outer view that wraps a message's attachment stack.
- `makeMessageAttachmentItemViewModifier` – modifier applied to file, voice, link, image, video, and quoted-message reference bubbles. For quoted-message references, `MessageAttachmentItemViewModifierOptions.attachmentType` is `nil`.
- `makeBouncedMessageActionsModifier` – modifier for bounced-message action UI.

## Complete ViewFactory reference

Below is the full list of `ViewFactory` hooks, grouped by area. Expand a section to see all available slots. You can also browse the full source [here](https://github.com/GetStream/stream-chat-swiftui/blob/v5/Sources/StreamChatSwiftUI/ViewFactory/ViewFactory.swift).

<details>
<summary>Avatars</summary>

| Method                                                                                   | Description                                                  |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `func makeChannelAvatarView(options: ChannelAvatarViewOptions) -> ChannelAvatarViewType` | Avatar shown in the channel list, header, and search results |
| `func makeUserAvatarView(options: UserAvatarViewOptions) -> UserAvatarViewType`          | User avatar used throughout the SDK                          |

</details>

<details>
<summary>Channel List</summary>

| Method                                                                                                                                 | Description                                          |
| -------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| `func makeChannelListHeaderViewModifier(options: ChannelListHeaderViewModifierOptions) -> HeaderViewModifier`                          | Navigation header view modifier for the channel list |
| `func makeEmptyChannelsView(options: EmptyChannelsViewOptions) -> EmptyChannels`                                                       | Empty state view when there are no channels          |
| `func makeLoadingView(options: LoadingViewOptions) -> LoadingContent`                                                                  | Loading state view for the channel list              |
| `func makeChannelListItem(options: ChannelListItemOptions<ChannelDestination>) -> ChannelListItemType`                                 | View for each channel row in the list                |
| `func makeChannelListBackground(options: ChannelListBackgroundOptions) -> ChannelListBackground`                                       | Background view for the channel list                 |
| `func makeChannelListItemBackground(options: ChannelListItemBackgroundOptions) -> ChannelListItemBackground`                           | Background view for each channel list item           |
| `func makeChannelListDividerItem(options: ChannelListDividerItemOptions) -> ChannelListDividerItem`                                    | Divider between channel list items                   |
| `func makeMoreChannelActionsView(options: MoreChannelActionsViewOptions) -> MoreActionsView`                                           | Additional channel actions popup                     |
| `func makeTrailingSwipeActionsView(options: TrailingSwipeActionsViewOptions) -> TrailingSwipeActionsViewType`                          | Trailing swipe actions for a channel row             |
| `func makeLeadingSwipeActionsView(options: LeadingSwipeActionsViewOptions) -> LeadingSwipeActionsViewType`                             | Leading swipe actions for a channel row              |
| `func makeChannelListTopView(options: ChannelListTopViewOptions) -> ChannelListTopViewType`                                            | View shown above the channel list                    |
| `func makeChannelListFooterView(options: ChannelListFooterViewOptions) -> ChannelListFooterViewType`                                   | Footer view for the channel list                     |
| `func makeChannelListStickyFooterView(options: ChannelListStickyFooterViewOptions) -> ChannelListStickyFooterViewType`                 | Sticky footer view for the channel list              |
| `func makeSearchResultsView(options: SearchResultsViewOptions) -> ChannelListSearchResultsViewType`                                    | Container view for channel/message search results    |
| `func makeChannelListSearchResultItem(options: ChannelListSearchResultItemOptions<ChannelDestination>) -> ChannelListSearchResultItem` | View for each search result item                     |

</details>

<details>
<summary>Channel And Message List</summary>

| Method                                                                                                                                             | Description                                          |
| -------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| `func makeChannelDestination(options: ChannelDestinationOptions) -> @MainActor (ChannelSelectionInfo) -> ChannelDestination`                       | Destination view when navigating to a channel        |
| `func makeMessageThreadDestination(options: MessageThreadDestinationOptions) -> @MainActor (ChatChannel, ChatMessage) -> MessageThreadDestination` | Destination view when navigating to a message thread |
| `func makeEmptyMessagesView(options: EmptyMessagesViewOptions) -> EmptyMessagesViewType`                                                           | Empty state view when there are no messages          |
| `func makeChannelHeaderViewModifier(options: ChannelHeaderViewModifierOptions) -> ChatHeaderViewModifier`                                          | Navigation header modifier for the channel view      |
| `func makeChannelBarsVisibilityViewModifier(options: ChannelBarsVisibilityViewModifierOptions) -> ChangeBarsVisibilityModifier`                    | Controls top/bottom bars visibility                  |
| `func makeChannelLoadingView(options: ChannelLoadingViewOptions) -> ChannelLoadingViewType`                                                        | Loading state for `ChatChannelView`                  |
| `func makeMessageThreadHeaderViewModifier(options: MessageThreadHeaderViewModifierOptions) -> ThreadHeaderViewModifier`                            | Navigation header modifier for the thread view       |
| `func makeMessageListBackground(options: MessageListBackgroundOptions) -> MessageListBackground`                                                   | Background view for the message list                 |
| `func makeMessageItemView(options: MessageItemViewOptions) -> MessageItemViewType`                                                                 | Container view for each message in the list          |
| `func makeMessageTextView(options: MessageTextViewOptions) -> MessageTextViewType`                                                                 | Text content view for a message                      |
| `func makeMessageDateView(options: MessageDateViewOptions) -> MessageDateViewType`                                                                 | Date label shown below/inside a message              |
| `func makeMessageAuthorAndDateView(options: MessageAuthorAndDateViewOptions) -> MessageAuthorAndDateViewType`                                      | Author name and date header layout                   |
| `func makeMessageTopView(options: MessageTopViewOptions) -> MessageTopViewType`                                                                    | View shown above the message bubble                  |
| `func makeLastInGroupHeaderView(options: LastInGroupHeaderViewOptions) -> LastInGroupHeaderView`                                                   | Header view for the last message in a group          |
| `func makeMessageAttachmentsView(options: MessageAttachmentsViewOptions) -> MessageAttachmentsViewType`                                            | Container view for message attachments               |
| `func makeImageAttachmentView(options: ImageAttachmentViewOptions) -> ImageAttachmentViewType`                                                     | Image attachment view                                |
| `func makeGiphyAttachmentView(options: GiphyAttachmentViewOptions) -> GiphyAttachmentViewType`                                                     | Giphy attachment view                                |
| `func makeLinkAttachmentView(options: LinkAttachmentViewOptions) -> LinkAttachmentViewType`                                                        | Link preview attachment view                         |
| `func makeFileAttachmentView(options: FileAttachmentViewOptions) -> FileAttachmentViewType`                                                        | File attachment view                                 |
| `func makeVideoAttachmentView(options: VideoAttachmentViewOptions) -> VideoAttachmentViewType`                                                     | Video attachment view                                |
| `func makeMediaViewer(options: MediaViewerOptions) -> MediaViewerType`                                                                             | Full-screen media gallery viewer                     |
| `func makeMediaViewerToolbarModifier(options: MediaViewerToolbarModifierOptions) -> MediaViewerToolbarModifierType`                                | Toolbar modifier for the media gallery viewer        |
| `func makeMediaViewerFooterView(options: MediaViewerFooterViewOptions) -> MediaViewerFooterViewType`                                               | Footer for the media gallery viewer                  |
| `func makeDeletedMessageView(options: DeletedMessageViewOptions) -> DeletedMessageViewType`                                                        | View for deleted messages                            |
| `func makeSystemMessageView(options: SystemMessageViewOptions) -> SystemMessageViewType`                                                           | View for system messages                             |
| `func makeEmojiTextView(options: EmojiTextViewOptions) -> EmojiTextViewType`                                                                       | Text view that renders emoji                         |
| `func makeVoiceRecordingView(options: VoiceRecordingViewOptions) -> VoiceRecordingViewType`                                                        | Voice recording attachment view                      |
| `func makeCustomAttachmentViewType(options: CustomAttachmentViewTypeOptions) -> CustomAttachmentViewType`                                          | View for custom attachment types                     |
| `func makeScrollToBottomButton(options: ScrollToBottomButtonOptions) -> ScrollToBottomButtonType`                                                  | Button to scroll to the latest message               |
| `func makeDateIndicatorView(options: DateIndicatorViewOptions) -> DateIndicatorViewType`                                                           | Date overlay/separator indicator                     |
| `func makeMessageListDateIndicator(options: MessageListDateIndicatorViewOptions) -> MessageListDateIndicatorViewType`                              | Date indicator shown while scrolling                 |
| `func makeInlineTypingIndicatorView(options: TypingIndicatorViewOptions) -> InlineTypingIndicatorViewType`                                         | Inline typing indicator shown in the message list    |
| `func makeSubtitleTypingIndicatorView(options: SubtitleTypingIndicatorViewOptions) -> SubtitleTypingIndicatorViewType`                             | Subtitle typing indicator in the navigation bar      |
| `func makeGiphyBadgeViewType(options: GiphyBadgeViewTypeOptions) -> GiphyBadgeViewType`                                                            | Badge overlay for Giphy messages                     |
| `func makeMessageRepliesView(options: MessageRepliesViewOptions) -> MessageRepliesViewType`                                                        | Thread replies count button below a message          |

</details>

<details>
<summary>Composer And Suggestions</summary>

| Method                                                                                                                                | Description                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| `func makeMessageComposerViewType(options: MessageComposerViewTypeOptions) -> MessageComposerViewType`                                | The full message composer component                         |
| `func makeLeadingComposerView(options: LeadingComposerViewOptions) -> LeadingComposerViewType`                                        | Leading view of the composer (e.g. add attachment button)   |
| `func makeComposerInputView(options: ComposerInputViewOptions) -> ComposerInputViewType`                                              | Input area of the composer                                  |
| `func makeComposerTextInputView(options: ComposerTextInputViewOptions) -> ComposerTextInputViewType`                                  | Text input field inside the composer                        |
| `func makeComposerInputTrailingView(options: ComposerInputTrailingViewOptions) -> ComposerInputTrailingViewType`                      | Trailing view inside the composer input (e.g. emoji button) |
| `func makeTrailingComposerView(options: TrailingComposerViewOptions) -> TrailingComposerViewType`                                     | Trailing view of the composer (e.g. send button)            |
| `func makeSendMessageButton(options: SendMessageButtonOptions) -> SendMessageButtonType`                                              | Send message button                                         |
| `func makeConfirmEditButton(options: ConfirmEditButtonOptions) -> ConfirmEditButtonType`                                              | Confirm button when editing a message                       |
| `func makeComposerVoiceRecordingInputView(options: ComposerVoiceRecordingInputViewOptions) -> ComposerVoiceRecordingInputViewType`    | Voice recording UI inside the composer                      |
| `func makeAttachmentPickerView(options: AttachmentPickerViewOptions) -> AttachmentPickerViewType`                                     | Attachment picker container                                 |
| `func makeAttachmentCommandsPickerView(options: AttachmentCommandsPickerViewOptions) -> AttachmentCommandsPickerViewType`             | Commands picker in the attachment area                      |
| `func makeAttachmentTypePickerView(options: AttachmentTypePickerViewOptions) -> AttachmentTypePickerViewType`                         | Attachment type selector (photo, file, poll, etc.)          |
| `func makeAttachmentMediaPickerView(options: AttachmentMediaPickerViewOptions) -> AttachmentMediaPickerViewType`                      | Photo/video picker                                          |
| `func makeAttachmentFilePickerView(options: AttachmentFilePickerViewOptions) -> AttachmentFilePickerViewType`                         | File picker                                                 |
| `func makeAttachmentCameraPickerView(options: AttachmentCameraPickerViewOptions) -> AttachmentCameraPickerViewType`                   | Camera picker                                               |
| `func makeCustomAttachmentPickerView(options: CustomAttachmentPickerViewOptions) -> CustomAttachmentPickerViewType`                   | Custom attachment picker                                    |
| `func makeCustomAttachmentPreviewView(options: CustomAttachmentPreviewViewOptions) -> CustomAttachmentPreviewViewType`                | Preview for custom attachments in the composer              |
| `func makeAttachmentPollPickerView(options: AttachmentPollPickerViewOptions) -> AttachmentPollPickerViewType`                         | Poll creation picker in the composer                        |
| `func makeSendInChannelView(options: SendInChannelViewOptions) -> SendInChannelViewType`                                              | "Send also in channel" toggle for thread replies            |
| `func makeSuggestionsContainerView(options: SuggestionsContainerViewOptions) -> SuggestionsContainerViewType`                         | Container for command/mention suggestions                   |
| `func makeComposerQuotedMessageView(options: ComposerQuotedMessageViewOptions) -> ComposerQuotedMessageViewType`                      | Quoted message shown inside the composer                    |
| `func makeQuotedMessageView(options: QuotedMessageViewOptions) -> QuotedMessageViewType`                                              | Base quoted message view                                    |
| `func makeChatQuotedMessageView(options: ChatQuotedMessageViewOptions) -> ChatQuotedMessageViewType`                                  | Quoted message shown in the message list                    |
| `func makeComposerEditedMessageView(options: ComposerEditedMessageViewOptions) -> ComposerEditedMessageViewType`                      | Edited message shown inside the composer                    |
| `func makeMessageAttachmentPreviewThumbnailView(options: MessageAttachmentPreviewViewOptions) -> MessageAttachmentPreviewViewType`    | Thumbnail preview for attachments in the composer           |
| `func makeMessageAttachmentPreviewIconView(options: MessageAttachmentPreviewIconViewOptions) -> MessageAttachmentPreviewIconViewType` | Icon preview for attachments in the composer                |

</details>

<details>
<summary>Reactions, Actions, And Read State</summary>

| Method                                                                                                        | Description                                       |
| ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| `func makeMessageActionsView(options: MessageActionsViewOptions) -> MessageActionsViewType`                   | Message actions popup (copy, delete, edit, etc.)  |
| `func makeReactionsDetailView(options: ReactionsDetailViewOptions) -> ReactionsDetailViewType`                | Detail view showing who reacted                   |
| `func makeBottomReactionsView(options: ReactionsBottomViewOptions) -> ReactionsBottomViewType`                | Reactions shown below a message                   |
| `func makeMessageReactionView(options: MessageReactionViewOptions) -> MessageReactionViewType`                | Single reaction view                              |
| `func makeReactionsOverlayView(options: ReactionsOverlayViewOptions) -> ReactionsOverlayViewType`             | Overlay shown when adding a reaction              |
| `func makeReactionsContentView(options: ReactionsContentViewOptions) -> ReactionsContentView`                 | Content view for the reactions picker             |
| `func makeMoreReactionsView(options: MoreReactionsViewOptions) -> MoreReactionsViewType`                      | "More reactions" button/view                      |
| `func makeMessageReadIndicatorView(options: MessageReadIndicatorViewOptions) -> MessageReadIndicatorViewType` | Read indicator shown next to messages             |
| `func makeNewMessagesDividerView(options: NewMessagesDividerViewOptions) -> NewMessagesDividerType`           | Divider indicating unread messages                |
| `func makeJumpToUnreadButtonOverlay(options: JumpToUnreadButtonOptions) -> JumpToUnreadButtonOverlayType`     | Overlay modifier for the jump-to-unread button    |
| `func makeThreadRepliesDividerView(options: ThreadRepliesDividerViewOptions) -> ThreadRepliesDividerType`     | Divider between parent message and thread replies |

</details>

<details>
<summary>Polls</summary>

| Method                                                                                                        | Description                              |
| ------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| `func makePollView(options: PollViewOptions) -> PollViewType`                                                 | Poll attachment view in the message list |
| `func makeAttachmentPollPickerView(options: AttachmentPollPickerViewOptions) -> AttachmentPollPickerViewType` | Poll creation view in the composer       |

</details>

<details>
<summary>Thread List</summary>

| Method                                                                                                                 | Description                                     |
| ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `func makeThreadDestination(options: ThreadDestinationOptions) -> @MainActor (ChatThread) -> ThreadDestination`        | Destination view when navigating to a thread    |
| `func makeThreadListItem(options: ThreadListItemOptions<ThreadDestination>) -> ThreadListItemType`                     | View for each thread row in the thread list     |
| `func makeEmptyThreadsView(options: EmptyThreadsViewOptions) -> EmptyThreads`                                          | Empty state view when there are no threads      |
| `func makeThreadListLoadingView(options: ThreadListLoadingViewOptions) -> ThreadListLoadingView`                       | Loading state view for the thread list          |
| `func makeThreadListContainerViewModifier(options: ThreadListContainerModifierOptions) -> ThreadListContainerModifier` | Modifier applied to the thread list container   |
| `func makeThreadListHeaderViewModifier(options: ThreadListHeaderViewModifierOptions) -> ThreadListHeaderViewModifier`  | Navigation header modifier for the thread list  |
| `func makeThreadListHeaderView(options: ThreadListHeaderViewOptions) -> ThreadListHeaderView`                          | Header view shown at the top of the thread list |
| `func makeThreadListFooterView(options: ThreadListFooterViewOptions) -> ThreadListFooterView`                          | Footer shown when loading more threads          |
| `func makeThreadListBackground(options: ThreadListBackgroundOptions) -> ThreadListBackground`                          | Background view for the thread list             |
| `func makeThreadListItemBackground(options: ThreadListItemBackgroundOptions) -> ThreadListItemBackground`              | Background view for each thread list item       |
| `func makeThreadListDividerItem(options: ThreadListDividerItemOptions) -> ThreadListDividerItem`                       | Divider between thread list items               |

</details>

<details>
<summary>Member Add And Text Rendering</summary>

| Method                                                                                      | Description                            |
| ------------------------------------------------------------------------------------------- | -------------------------------------- |
| `func makeMemberAddView(options: MemberAddViewOptions) -> MemberAddViewType`                | Add members view for a channel         |
| `func makeAttachmentTextView(options: AttachmentTextViewOptions) -> AttachmentTextViewType` | Text preview for attachments           |
| `func makeStreamTextView(options: StreamTextViewOptions) -> StreamTextViewType`             | Custom text view for message rendering |

</details>

## Accessing Dependencies

When building your own view components and you want to use the dependencies of the SwiftUI SDK, you can access them by using the `@Injected(\.keyPath)` property wrapper:

```swift
@Injected(\.chatClient) var chatClient
@Injected(\.colors) var colors
@Injected(\.fonts) var fonts
@Injected(\.images) var images
@Injected(\.utils) var utils
```

<admonition type="note">

The `@Injected` property wrapper works similarly to the `@Environment` in SwiftUI, but it also allows access to the dependencies in non-view related code. This approach is inspired by the following [Dependency Injection](https://www.avanderlee.com/swift/dependency-injection/) article by [Antoine van der Lee](https://www.avanderlee.com/).

</admonition>

### Extending with Custom Types

In some cases, you might also need to extend the `@Injected` property wrapper with your own types. For example, you may want to be able to access your custom types like this:

```swift
@Injected(\.customType) var customType
```

In order to achieve this, you first need to define your own `InjectionKey`, and define it's `currentValue`, which basically creates the new instance of your type.

```swift
class CustomType {
	// your custom logic here
}

struct CustomInjectionKey: InjectionKey {
    static var currentValue: CustomType = CustomType()
}
```

Next, you need to extend our `InjectedValues` with your own custom type, by defining its getter and setter.

```swift
extension InjectedValues {
    /// Provides access to the `CustomType` instance in the views and view models.
    var customType: CustomType {
        get {
            Self[CustomInjectionKey.self]
        }
        set {
            Self[CustomInjectionKey.self] = newValue
        }
    }
}
```

With these few simple steps, you can now access your custom type in both your app code and in your custom implementations of the views used throughout the SDK.

## Build Time Improvements

If you are customizing many view slots (over 15) from the SDK, and you have many generics in your codebase, it's a good idea to explicitly specify the types of your custom views with `typealias`. This will improve the build time of your project.

For example, in our `ViewFactory`, the `associatedType` for creating the empty channels view is `EmptyChannels`:

```swift
associatedtype EmptyChannels: View
func makeEmptyChannelsView(options: EmptyChannelsViewOptions) -> EmptyChannels
```

In order to improve the build time, you would need to specify the associated type with a `typealias`, like this:

```swift
typealias EmptyChannels = CustomEmptyChannelsView
```

Then, your custom implementation of the factory method `makeEmptyChannelsView` will look like the following:

```swift
public func makeEmptyChannelsView(options: EmptyChannelsViewOptions) -> CustomEmptyChannelsView {
    CustomEmptyChannelsView()
}
```

You can find all the associated types we use in the `ViewFactory` [here](https://github.com/GetStream/stream-chat-swiftui/blob/v5/Sources/StreamChatSwiftUI/ViewFactory/ViewFactory.swift).


---

This page was last updated at 2026-07-13T13:42:56.838Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/ios/swiftui/view-customizations/](https://getstream.io/chat/docs/sdk/ios/swiftui/view-customizations/).