diff --git a/app/assets/javascripts/merge_request_dashboard/components/merge_request.stories.js b/app/assets/javascripts/merge_request_dashboard/components/merge_request.stories.js
new file mode 100644
index 0000000000000000000000000000000000000000..978b9169f64c439539515b435dbea721cb2a0a64
--- /dev/null
+++ b/app/assets/javascripts/merge_request_dashboard/components/merge_request.stories.js
@@ -0,0 +1,110 @@
+import MergeRequest from './merge_request.vue';
+
+const Template = (_, { argTypes }) => {
+  return {
+    components: { MergeRequest },
+    props: Object.keys(argTypes),
+    template: '<merge-request v-bind="$props" />',
+  };
+};
+
+export default {
+  component: MergeRequest,
+  title: 'merge_requests_dashboard/merge_request',
+};
+
+export const Default = Template.bind({});
+Default.args = {
+  mergeRequest: {
+    reference: '!123456',
+    titleHtml: 'Merge request title',
+    author: {
+      name: 'John Smith',
+      webUrl: 'https://gitlab.com/root',
+    },
+    milestone: {
+      title: '17.0',
+    },
+    labels: {
+      nodes: [
+        {
+          id: 'gid://gitlab/GroupLabel/992791',
+          color: '#428BCA',
+          title: 'Deliverable',
+          description: 'Label description',
+        },
+        {
+          id: 'gid://gitlab/GroupLabel/3103452',
+          color: '#E44D2A',
+          title: 'devops::create',
+          description: 'Label description',
+        },
+        {
+          id: 'gid://gitlab/GroupLabel/2975007',
+          color: '#F0AD4E',
+          title: 'feature::enhancement',
+          description: 'Label description',
+        },
+        {
+          id: 'gid://gitlab/GroupLabel/3412464',
+          color: '#3cb371',
+          title: 'frontend',
+          description: 'Label description',
+        },
+        {
+          id: 'gid://gitlab/GroupLabel/16934793',
+          color: '#A8D695',
+          title: 'group::code review',
+          description: 'Label description',
+        },
+        {
+          id: 'gid://gitlab/GroupLabel/14918378',
+          color: '#F0AD4E',
+          title: 'section::dev',
+          description: 'Label description',
+        },
+        {
+          id: 'gid://gitlab/GroupLabel/10230929',
+          color: '#009966',
+          title: 'type::feature',
+          description: 'Label description',
+        },
+      ],
+    },
+    assignees: {
+      nodes: [
+        {
+          id: 'gid://gitlab/User/1',
+          avatarUrl: '',
+          name: 'John Smith',
+          username: 'jsmith',
+          webUrl: 'https://gitlab.com/root',
+          webPath: '/root',
+        },
+      ],
+    },
+    reviewers: {
+      nodes: [
+        {
+          id: 'gid://gitlab/User/1',
+          avatarUrl: '',
+          name: 'John Smith',
+          username: 'jsmith',
+          webUrl: 'https://gitlab.com/root',
+          webPath: '/root',
+        },
+        {
+          id: 'gid://gitlab/User/2',
+          avatarUrl: '',
+          name: 'John Smith',
+          username: 'jsmith',
+          webUrl: 'https://gitlab.com/root',
+          webPath: '/root',
+        },
+      ],
+    },
+    userDiscussionsCount: 5,
+    createdAt: '2024-04-22T10:13:09Z',
+    updatedAt: '2024-04-19T14:34:42Z',
+  },
+};
diff --git a/app/assets/javascripts/merge_request_dashboard/components/merge_request.vue b/app/assets/javascripts/merge_request_dashboard/components/merge_request.vue
new file mode 100644
index 0000000000000000000000000000000000000000..362f608bed2a262792c4874a72dd7e13b91ce6ad
--- /dev/null
+++ b/app/assets/javascripts/merge_request_dashboard/components/merge_request.vue
@@ -0,0 +1,125 @@
+<script>
+import { GlLink, GlSprintf, GlIcon, GlLabel, GlTooltipDirective } from '@gitlab/ui';
+import { __, sprintf } from '~/locale';
+import SafeHtml from '~/vue_shared/directives/safe_html';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
+import { isScopedLabel } from '~/lib/utils/common_utils';
+
+export default {
+  components: {
+    GlLink,
+    GlSprintf,
+    GlIcon,
+    GlLabel,
+    TimeAgoTooltip,
+    UserAvatarLink,
+  },
+  directives: {
+    SafeHtml,
+    GlTooltip: GlTooltipDirective,
+  },
+  props: {
+    mergeRequest: {
+      type: Object,
+      required: true,
+    },
+  },
+  methods: {
+    showScopedLabel(label) {
+      return isScopedLabel(label);
+    },
+    assigneeTitle(assignee) {
+      return sprintf(__('Assigned to %{assignee}'), { assignee: assignee.name });
+    },
+    reviewerTitle(reviewer) {
+      return sprintf(__('Review requested %{reviewer}'), { reviewer: reviewer.name });
+    },
+  },
+};
+</script>
+
+<template>
+  <div class="gl-bg-white gl-p-5 gl-rounded-base">
+    <div class="gl-display-flex gl-mb-2">
+      <div class="gl-display-flex gl-flex-direction-column">
+        <h4 class="gl-mb-0 gl-mt-0 gl-font-base">
+          <gl-link
+            v-safe-html="mergeRequest.titleHtml"
+            href="#"
+            class="gl-text-body gl-hover-text-gray-900"
+          />
+        </h4>
+        <div class="gl-font-sm gl-mt-2 gl-text-secondary">
+          <gl-sprintf
+            :message="__('%{reference} %{divider} created %{createdAt} by %{author} %{milestone}')"
+          >
+            <template #reference>{{ mergeRequest.reference }}</template>
+            <template #divider>&middot;</template>
+            <template #createdAt><time-ago-tooltip :time="mergeRequest.createdAt" /></template>
+            <template #author>
+              <gl-link :href="mergeRequest.author.webUrl" class="gl-text-secondary">
+                {{ mergeRequest.author.name }}
+              </gl-link>
+            </template>
+            <template #milestone>
+              <gl-icon :size="16" class="gl-ml-2" name="milestone" />
+              {{ mergeRequest.milestone.title }}
+            </template>
+          </gl-sprintf>
+        </div>
+      </div>
+      <div class="gl-ml-auto gl-display-flex gl-flex-direction-column">
+        <ul class="gl-display-flex gl-justify-content-end gl-m-0 gl-p-0 gl-list-style-none">
+          <li v-if="mergeRequest.assignees.nodes.length">
+            <user-avatar-link
+              v-for="(assignee, index) in mergeRequest.assignees.nodes"
+              :key="`assignee_${assignee.id}`"
+              :link-href="assignee.webUrl"
+              :img-src="assignee.avatarUrl"
+              :img-size="24"
+              :tooltip-text="assigneeTitle(assignee)"
+              :class="{ 'gl-mr-2': index !== mergeRequest.assignees.nodes.length - 1 }"
+            />
+          </li>
+          <li v-if="mergeRequest.reviewers.nodes.length" class="gl-ml-4">
+            <user-avatar-link
+              v-for="(reviewer, index) in mergeRequest.reviewers.nodes"
+              :key="`reviewer_${reviewer.id}`"
+              :link-href="reviewer.webUrl"
+              :img-src="reviewer.avatarUrl"
+              :img-size="24"
+              :tooltip-text="reviewerTitle(reviewer)"
+              :class="{ 'gl-mr-2': index !== mergeRequest.reviewers.nodes.length - 1 }"
+            />
+          </li>
+          <li
+            v-if="mergeRequest.userDiscussionsCount"
+            v-gl-tooltip="__('Comments')"
+            class="gl-align-self-center gl-ml-4"
+          >
+            <gl-icon name="comments" class="gl-vertical-align-middle!" />
+            {{ mergeRequest.userDiscussionsCount }}
+          </li>
+        </ul>
+        <div v-if="mergeRequest.updatedAt" class="gl-font-sm gl-mt-2 gl-text-secondary">
+          <gl-sprintf :message="__('Updated at %{updatedAt}')">
+            <template #updatedAt><time-ago-tooltip :time="mergeRequest.updatedAt" /></template>
+          </gl-sprintf>
+        </div>
+      </div>
+    </div>
+    <div>
+      <gl-label
+        v-for="label in mergeRequest.labels.nodes"
+        :key="label.id"
+        :background-color="label.color"
+        :title="label.title"
+        :description="label.description"
+        size="sm"
+        :scoped="showScopedLabel(label)"
+        class="gl-mr-2"
+      />
+    </div>
+  </div>
+</template>
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index d1f4bf53cdd5086b96151911d01eab3cd1ad6eb9..804a447ed31b13e1c1edc65c30ae00d5d44ff1aa 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1104,6 +1104,9 @@ msgstr ""
 msgid "%{project_path} is a project that you can use to add a README to your GitLab profile. Create a public project and initialize the repository with a README to get started. %{help_link_start}Learn more%{help_link_end}."
 msgstr ""
 
+msgid "%{reference} %{divider} created %{createdAt} by %{author} %{milestone}"
+msgstr ""
+
 msgid "%{ref} cannot be added: %{error}"
 msgstr ""
 
@@ -7111,6 +7114,9 @@ msgstr ""
 msgid "Assigned to %{assignee_name}"
 msgstr ""
 
+msgid "Assigned to %{assignee}"
+msgstr ""
+
 msgid "Assigned to me"
 msgstr ""
 
@@ -43577,6 +43583,9 @@ msgstr ""
 msgid "Review changes"
 msgstr ""
 
+msgid "Review requested %{reviewer}"
+msgstr ""
+
 msgid "Review requests"
 msgstr ""
 
@@ -55153,6 +55162,9 @@ msgstr ""
 msgid "Updated %{updated_at} by %{updated_by}"
 msgstr ""
 
+msgid "Updated at %{updatedAt}"
+msgstr ""
+
 msgid "Updated date"
 msgstr ""
 
diff --git a/spec/frontend/merge_request_dashboard/components/__snapshots__/merge_request_spec.js.snap b/spec/frontend/merge_request_dashboard/components/__snapshots__/merge_request_spec.js.snap
new file mode 100644
index 0000000000000000000000000000000000000000..c3e4d58f0e76f1fdaefb542527654a642d0065e8
--- /dev/null
+++ b/spec/frontend/merge_request_dashboard/components/__snapshots__/merge_request_spec.js.snap
@@ -0,0 +1,115 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Merge request dashboard merge request component renders template 1`] = `
+<div
+  class="gl-bg-white gl-p-5 gl-rounded-base"
+>
+  <div
+    class="gl-display-flex gl-mb-2"
+  >
+    <div
+      class="gl-display-flex gl-flex-direction-column"
+    >
+      <h4
+        class="gl-font-base gl-mb-0 gl-mt-0"
+      >
+        <gl-link-stub
+          class="gl-hover-text-gray-900 gl-text-body"
+          href="#"
+        >
+          Merge request title
+        </gl-link-stub>
+      </h4>
+      <div
+        class="gl-font-sm gl-mt-2 gl-text-secondary"
+      >
+        <gl-sprintf-stub
+          message="%{reference} %{divider} created %{createdAt} by %{author} %{milestone}"
+        />
+      </div>
+    </div>
+    <div
+      class="gl-display-flex gl-flex-direction-column gl-ml-auto"
+    >
+      <ul
+        class="gl-display-flex gl-justify-content-end gl-list-style-none gl-m-0 gl-p-0"
+      >
+        <li>
+          <user-avatar-link-stub
+            imgalt=""
+            imgcssclasses=""
+            imgcsswrapperclasses=""
+            imgsize="24"
+            imgsrc=""
+            linkhref="https://gitlab.com/root"
+            popoveruserid=""
+            popoverusername=""
+            tooltipplacement="top"
+            tooltiptext="Assigned to John Smith"
+            username=""
+          />
+        </li>
+        <li
+          class="gl-ml-4"
+        >
+          <user-avatar-link-stub
+            class="gl-mr-2"
+            imgalt=""
+            imgcssclasses=""
+            imgcsswrapperclasses=""
+            imgsize="24"
+            imgsrc=""
+            linkhref="https://gitlab.com/root"
+            popoveruserid=""
+            popoverusername=""
+            tooltipplacement="top"
+            tooltiptext="Review requested John Smith"
+            username=""
+          />
+          <user-avatar-link-stub
+            imgalt=""
+            imgcssclasses=""
+            imgcsswrapperclasses=""
+            imgsize="24"
+            imgsrc=""
+            linkhref="https://gitlab.com/root"
+            popoveruserid=""
+            popoverusername=""
+            tooltipplacement="top"
+            tooltiptext="Review requested John Smith"
+            username=""
+          />
+        </li>
+        <li
+          class="gl-align-self-center gl-ml-4"
+        >
+          <gl-icon-stub
+            class="gl-vertical-align-middle!"
+            name="comments"
+            size="16"
+          />
+          5
+        </li>
+      </ul>
+      <div
+        class="gl-font-sm gl-mt-2 gl-text-secondary"
+      >
+        <gl-sprintf-stub
+          message="Updated at %{updatedAt}"
+        />
+      </div>
+    </div>
+  </div>
+  <div>
+    <gl-label-stub
+      backgroundcolor="#428BCA"
+      class="gl-mr-2"
+      description="Label description"
+      size="sm"
+      target=""
+      title="Deliverable"
+      tooltipplacement="top"
+    />
+  </div>
+</div>
+`;
diff --git a/spec/frontend/merge_request_dashboard/components/merge_request_spec.js b/spec/frontend/merge_request_dashboard/components/merge_request_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..709bbc46ae55ee983fb0a497898825eb243506bd
--- /dev/null
+++ b/spec/frontend/merge_request_dashboard/components/merge_request_spec.js
@@ -0,0 +1,75 @@
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import MergeRequest from '~/merge_request_dashboard/components/merge_request.vue';
+
+describe('Merge request dashboard merge request component', () => {
+  let wrapper;
+
+  function createComponent() {
+    wrapper = shallowMountExtended(MergeRequest, {
+      propsData: {
+        mergeRequest: {
+          reference: '!123456',
+          titleHtml: 'Merge request title',
+          author: {
+            name: 'John Smith',
+            webUrl: 'https://gitlab.com/root',
+          },
+          milestone: {
+            title: '17.0',
+          },
+          labels: {
+            nodes: [
+              {
+                id: 'gid://gitlab/GroupLabel/992791',
+                color: '#428BCA',
+                title: 'Deliverable',
+                description: 'Label description',
+              },
+            ],
+          },
+          assignees: {
+            nodes: [
+              {
+                id: 'gid://gitlab/User/1',
+                avatarUrl: '',
+                name: 'John Smith',
+                username: 'jsmith',
+                webUrl: 'https://gitlab.com/root',
+                webPath: '/root',
+              },
+            ],
+          },
+          reviewers: {
+            nodes: [
+              {
+                id: 'gid://gitlab/User/1',
+                avatarUrl: '',
+                name: 'John Smith',
+                username: 'jsmith',
+                webUrl: 'https://gitlab.com/root',
+                webPath: '/root',
+              },
+              {
+                id: 'gid://gitlab/User/2',
+                avatarUrl: '',
+                name: 'John Smith',
+                username: 'jsmith',
+                webUrl: 'https://gitlab.com/root',
+                webPath: '/root',
+              },
+            ],
+          },
+          userDiscussionsCount: 5,
+          createdAt: '2024-04-22T10:13:09Z',
+          updatedAt: '2024-04-19T14:34:42Z',
+        },
+      },
+    });
+  }
+
+  it('renders template', () => {
+    createComponent();
+
+    expect(wrapper.element).toMatchSnapshot();
+  });
+});