Skip to content

Integrations

React hooks

Import from os-detect/react. Requires React 17+.

tsx
import { useOS, useIsWindows11 } from 'os-detect/react'

useOS()

Returns the current OS string synchronously. The value is computed once and stable across re-renders.

tsx
function Banner() {
  const os = useOS() // 'windows' | 'macos' | 'ios' | ...

  return <p>Running on {os}</p>
}

useIsWindows11()

Starts the async detection inside useEffect and updates state when it resolves. Returns null while the detection is in progress.

tsx
function WindowsBadge() {
  const isWin11 = useIsWindows11() // null → true | false

  if (isWin11 === null) return <Spinner />
  return <p>{isWin11 ? 'Windows 11' : 'Windows 10 or older'}</p>
}
HookReturnsNotes
useOS()OSSynchronous, cached, stable
useIsWindows11()boolean | nullnull while detecting

Vue composables

Import from os-detect/vue. Requires Vue 3+.

ts
import { useOS, useIsWindows11 } from 'os-detect/vue'

useOS()

Returns a readonly Ref with the current OS string. Detection is synchronous and cached.

vue
<script setup lang="ts">
import { useOS } from 'os-detect/vue'

const os = useOS() // Readonly<Ref<OS>>
</script>

<template>
  <p>Running on {{ os }}</p>
</template>

useIsWindows11()

Returns a readonly Ref that starts as null and resolves to true or false after the async detection completes inside onMounted.

vue
<script setup lang="ts">
import { useOS, useIsWindows11 } from 'os-detect/vue'

const os = useOS() // Readonly<Ref<OS>>
const isWin11 = useIsWindows11() // Readonly<Ref<boolean | null>>
</script>

<template>
  <p v-if="isWin11 === null">Detecting Windows version…</p>
  <p v-else-if="isWin11">Windows 11</p>
  <p v-else-if="os === 'windows'">Windows 10 or older</p>
  <p v-else>OS: {{ os }}</p>
</template>
ComposableReturnsNotes
useOS()Readonly<Ref<OS>>Synchronous, cached
useIsWindows11()Readonly<Ref<boolean | null>>null while detecting

Node.js & SSR

All core functions work in Node.js. When navigator is absent the library reads process.platform instead of the userAgent.

ts
import { getOS, detectIsWindows, detectIsWindows11 } from 'os-detect'

getOS() // 'macos' | 'windows' | 'linux' | 'android' | 'unknown'
detectIsWindows() // true on Windows

const isWin11 = await detectIsWindows11() // uses os.release() build number

process.platform mapping

process.platformDetected as
darwinmacOS
win32Windows (32-bit and 64-bit)
linuxLinux
androidAndroid
anything else'unknown'

Functions that require a browser environment (detectIsIOS(), detectIsChromeOS()) always return false in Node.js — there is no userAgent or maxTouchPoints to read.

SSR hydration note

In Next.js or Nuxt SSR, getOS() returns the server's OS during server-side rendering — not the client's. To avoid hydration mismatches, run detection only on the client:

React (Next.js):

tsx
import { useEffect, useState } from 'react'
import { getOS } from 'os-detect'
import type { OS } from 'os-detect'

function OSBanner() {
  const [os, setOS] = useState<OS | null>(null)

  useEffect(() => {
    setOS(getOS())
  }, [])

  if (!os) return null
  return <p>OS: {os}</p>
}

Vue (Nuxt):

vue
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { getOS } from 'os-detect'
import type { OS } from 'os-detect'

const os = ref<OS | null>(null)
onMounted(() => {
  os.value = getOS()
})
</script>

<template>
  <p v-if="os">OS: {{ os }}</p>
</template>

Alternatively, use the Vue composable useOS() from os-detect/vue — it calls getOS() inside ref() which is evaluated only on the client when used with <script setup> and SSR-safe composition.

UMD / CDN

A prebuilt UMD bundle is available via unpkg and jsDelivr — no build step required.

html
<script src="https://unpkg.com/os-detect/dist/index.umd.js"></script>
<script>
  console.log(OsDetect.getOS())
  console.log(OsDetect.detectIsIOS())
  console.log(OsDetect.isMobileDevice())

  OsDetect.detectIsWindows11().then((isWin11) => {
    console.log('Windows 11:', isWin11)
  })
</script>

The global name is OsDetect. All functions from the core entry point are exposed on it.