Integrations
React hooks
Import from os-detect/react. Requires React 17+.
import { useOS, useIsWindows11 } from 'os-detect/react'useOS()
Returns the current OS string synchronously. The value is computed once and stable across re-renders.
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.
function WindowsBadge() {
const isWin11 = useIsWindows11() // null → true | false
if (isWin11 === null) return <Spinner />
return <p>{isWin11 ? 'Windows 11' : 'Windows 10 or older'}</p>
}| Hook | Returns | Notes |
|---|---|---|
useOS() | OS | Synchronous, cached, stable |
useIsWindows11() | boolean | null | null while detecting |
Vue composables
Import from os-detect/vue. Requires Vue 3+.
import { useOS, useIsWindows11 } from 'os-detect/vue'useOS()
Returns a readonly Ref with the current OS string. Detection is synchronous and cached.
<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.
<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>| Composable | Returns | Notes |
|---|---|---|
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.
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 numberprocess.platform mapping
process.platform | Detected as |
|---|---|
darwin | macOS |
win32 | Windows (32-bit and 64-bit) |
linux | Linux |
android | Android |
| 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):
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):
<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.
<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.