diff --git a/packages/components/index.ts b/packages/components/index.ts
index a45a339327e..f0cb08f7e91 100644
--- a/packages/components/index.ts
+++ b/packages/components/index.ts
@@ -40,6 +40,7 @@ export * from '../core/usePointer/component'
export * from '../core/usePreferredColorScheme/component'
export * from '../core/usePreferredDark/component'
export * from '../core/usePreferredLanguages/component'
+export * from '../core/usePreferredReducedMotion/component'
export * from '../core/useScreenSafeArea/component'
export * from '../core/useScroll/directive'
export * from '../core/useScrollLock/directive'
diff --git a/packages/core/index.ts b/packages/core/index.ts
index a30573ee049..8da1ef601d9 100644
--- a/packages/core/index.ts
+++ b/packages/core/index.ts
@@ -83,6 +83,7 @@ export * from './usePointerSwipe'
export * from './usePreferredColorScheme'
export * from './usePreferredDark'
export * from './usePreferredLanguages'
+export * from './usePreferredReducedMotion'
export * from './useRafFn'
export * from './useRefHistory'
export * from './useResizeObserver'
diff --git a/packages/core/usePreferredReducedMotion/component.ts b/packages/core/usePreferredReducedMotion/component.ts
new file mode 100644
index 00000000000..7ca183cf686
--- /dev/null
+++ b/packages/core/usePreferredReducedMotion/component.ts
@@ -0,0 +1,16 @@
+import { defineComponent, reactive } from 'vue-demi'
+import { usePreferredReducedMotion } from '@vueuse/core'
+
+export const UsePreferredReducedMotion = defineComponent({
+ name: 'UsePreferredReducedMotion',
+ setup(props, { slots }) {
+ const data = reactive({
+ motion: usePreferredReducedMotion(),
+ })
+
+ return () => {
+ if (slots.default)
+ return slots.default(data)
+ }
+ },
+})
diff --git a/packages/core/usePreferredReducedMotion/demo.vue b/packages/core/usePreferredReducedMotion/demo.vue
new file mode 100644
index 00000000000..8b7a5006a32
--- /dev/null
+++ b/packages/core/usePreferredReducedMotion/demo.vue
@@ -0,0 +1,12 @@
+
+
+
+
+ Preferred Motion:
+
+ {{ motion }}
+
diff --git a/packages/core/usePreferredReducedMotion/index.md b/packages/core/usePreferredReducedMotion/index.md
new file mode 100644
index 00000000000..709ad9d6f96
--- /dev/null
+++ b/packages/core/usePreferredReducedMotion/index.md
@@ -0,0 +1,23 @@
+---
+category: Browser
+---
+
+# usePreferredReducedMotion
+
+Reactive [prefers-reduced-motion](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion) media query.
+
+## Usage
+
+```js
+import { usePreferredReducedMotion } from '@vueuse/core'
+
+const preferredMotion = usePreferredReducedMotion()
+```
+
+## Component Usage
+
+```html
+
+ Preferred Color Scheme: {{ motion }}
+
+```
diff --git a/packages/core/usePreferredReducedMotion/index.ts b/packages/core/usePreferredReducedMotion/index.ts
new file mode 100644
index 00000000000..4eb0b530702
--- /dev/null
+++ b/packages/core/usePreferredReducedMotion/index.ts
@@ -0,0 +1,21 @@
+import { computed } from 'vue-demi'
+import { useMediaQuery } from '../useMediaQuery'
+import type { ConfigurableWindow } from '../_configurable'
+
+export type ReducedMotionType = 'reduce' | 'no-preference'
+
+/**
+ * Reactive prefers-reduced-motion media query.
+ *
+ * @see https://vueuse.org/usePreferredReducedMotion
+ * @param [options]
+ */
+export function usePreferredReducedMotion(options?: ConfigurableWindow) {
+ const isReduced = useMediaQuery('(prefers-reduced-motion: reduce)', options)
+
+ return computed(() => {
+ if (isReduced.value)
+ return 'reduce'
+ return 'no-preference'
+ })
+}