Info:
This is documentation for Stream Chat React Native SDK v8, which is no longer actively maintained. For up-to-date documentation, see the latest version (v9).

Handle Commands UI

To show the command UI in the message input, set up the middlewares in MessageComposer using setupCommandUIMiddlewares:

Command UI

Best Practices

  • Register command middlewares once during client setup to avoid duplicates.
  • Keep custom command UI minimal so typing remains fast and predictable.
  • Use useStateStore selectors to avoid re-renders on unrelated composer state.
  • Always restore the composer state when closing the command UI.
  • Provide a clear escape path (e.g., close button or back gesture).
import { useEffect } from "react";
import { setupCommandUIMiddlewares } from "stream-chat-react-native";

const App = () => {
  useEffect(() => {
    if (!chatClient) {
      return;
    }
    chatClient.setMessageComposerSetupFunction(({ composer }) => {
      setupCommandUIMiddlewares(composer);
    });
  }, [chatClient]);
};

This adds four middlewares to MessageComposer:

  • createActiveCommandGuardMiddleware(stream-io/text-composer/active-command-guard) - Prevents new triggers when a command is active.
  • createCommandStringExtractionMiddleware(stream-io/text-composer/command-string-extraction) - Extracts the command string (for example, /ban user → user).
  • createCommandInjectionMiddleware(stream-io/message-composer-middleware/command-string-injection) - This injects the command string into the message composer state.
  • createDraftCommandInjectionMiddleware(stream-io/message-composer-middleware/draft-command-string-injection) - This injects the command string into the draft state.

All of the above middlewares are exported from stream-chat.

The command state in TextComposer is set via createCommandsMiddleware from stream-chat.

Customizing Command UI

To show a custom command UI, pass a custom component via the CommandInput prop on Channel.

import { Button, Text, View } from "react-native";
import {
  AutoCompleteInput,
  Channel,
  useMessageComposer,
  useStateStore,
  useMessageInputContext,
} from "stream-chat-react-native";

import { TextComposerState } from "stream-chat";

const textComposerStateSelector = (state: TextComposerState) => ({
  command: state.command,
});

const CustomInputCommand = () => {
  const messageComposer = useMessageComposer();
  const { textComposer } = messageComposer;
  const { command } = useStateStore(
    textComposer.state,
    textComposerStateSelector,
  );

  return (
    <View>
      <Text style={{ textAlign: "center" }}>{command?.name}</Text>
      <AutoCompleteInput />
      <Button
        onPress={() => {
          messageComposer.textComposer.setCommand(null);
          messageComposer?.restore();
        }}
        title="Close"
      />
    </View>
  );
};

<Channel channel={channel} CommandInput={CustomInputCommand}>
  {/* The underlying components */}
</Channel>;
Note:

The CommandInput component is only rendered when the command state is set in the message composer. Make sure you complete the above middlewares setup to make it work.

Add Chat to my app: getstream.io/SKILL.md

The fastest way to build with Stream. Start a new project or improve an existing one. Full CLI and documentation integration out of the box.


Ask your agent:

/stream Build me a Social App with Feeds and Moderation.
/stream Any livestream calls running?
/stream Chat React Native v8: <Your Question>