Справочник API
Текущая ОС
getOS() — возвращает одну строку, идентифицирующую текущую операционную систему.
import { getOS } from 'os-detect'
const os = getOS()
// 'ios' | 'macos' | 'android' | 'windows' | 'linux' | 'chromeos' | 'unknown'Приоритет определения (побеждает первое совпадение):
- iOS / iPadOS
- Android
- ChromeOS
- Linux
- macOS
- Windows
'unknown'
ChromeOS проверяется раньше Linux, потому что userAgent-строки ChromeOS содержат "Linux" — неправильный порядок проверки привёл бы к тому, что Chromebook определялся бы неверно.
Тип OS
type OS = 'ios' | 'macos' | 'android' | 'windows' | 'linux' | 'chromeos' | 'unknown'Булевы проверки
Все функции ниже синхронны, не имеют побочных эффектов и кэшируют свой результат после первого вызова.
import {
detectIsIOS,
detectIsMacOS,
detectIsAndroid,
detectIsWindows,
detectIsLinux,
detectIsChromeOS,
} from 'os-detect'detectIsIOS()
boolean
true для iPhone, iPod или iPad (включая iPadOS 13+). В Node.js всегда false — не определяется на сервере.
detectIsMacOS()
boolean
true для macOS-десктопа (корректно исключает iPadOS 13+). В Node.js: process.platform === 'darwin'.
detectIsAndroid()
boolean
true для телефонов и планшетов Android. В Node.js: process.platform === 'android'.
detectIsWindows()
boolean
true для Windows-десктопа или ноутбука (32-битный и 64-битный). В Node.js: process.platform === 'win32'.
detectIsLinux()
boolean
true для Linux-десктопа (исключает Android и ChromeOS). В Node.js: process.platform === 'linux'.
detectIsChromeOS()
boolean
true для устройств ChromeOS. В Node.js всегда false — не определяется на сервере.
Особенность iPadOS 13+
Начиная с iPadOS 13, Safari сообщает Macintosh в строке userAgent. detectIsIOS() корректно обрабатывает это, проверяя navigator.maxTouchPoints > 1. detectIsMacOS() соответственно исключает устройства на iPadOS — вы никогда не получите true от обеих функций на одном устройстве.
Пример — условный рендеринг
import { detectIsIOS, detectIsAndroid, detectIsWindows } from 'os-detect'
if (detectIsIOS()) {
// показать бейдж App Store
} else if (detectIsAndroid()) {
// показать бейдж Google Play
} else if (detectIsWindows()) {
// показать бейдж Windows Store
}Определение Windows 11
detectIsWindows11()
Promise<boolean>
true только тогда, когда detectIsWindows() равно true и проверка Windows 11 прошла успешно.
import { detectIsWindows11 } from 'os-detect'
const isWin11 = await detectIsWindows11()Браузер — использует navigator.userAgentData.getHighEntropyValues(['platformVersion']) (Chrome 90+ / Edge 90+). Windows 11 сообщает platformVersion >= 13.0.0. Возвращает false, если API недоступен или вызов не удался.
Node.js — использует os.release(). У Windows 11 номер сборки >= 22000. Возвращает false, если импорт не удался.
Немедленно возвращает false, если detectIsWindows() равно false — асинхронная работа не выполняется. Как и все булевы детекторы, результат кэшируется после первого вызова; параллельные вызовы, сделанные до его разрешения, используют один и тот же промис вместо того, чтобы каждый запускал свою проверку. Чтобы принудительно перезапустить проверку, вызовите resetDetectionCache().
// Различаем Windows 10 и Windows 11
const isWindows = detectIsWindows()
const isWin11 = await detectIsWindows11()
if (isWin11) {
console.log('Windows 11')
} else if (isWindows) {
console.log('Windows 10 или старше')
}Сброс кэша
resetDetectionCache()
void
Очищает все кэшированные результаты определения — все функции detectIs*(), getOS() и detectIsWindows11() заново выполнят проверку при следующем вызове. Также сбрасывает флаг предупреждения об устаревании detectIsiOS(), поэтому следующий вызов этого алиаса снова выведет console.warn.
import { resetDetectionCache } from 'os-detect'
resetDetectionCache() // очищает все кэшированные результаты определенияВ обычной вкладке браузера ОС никогда не меняется в течение сессии, поэтому обычно это не нужно. Функция существует для продвинутых случаев:
- Долгоживущий процесс Node.js (например, главный процесс Electron), которому нужно переоценить
process.platformпосле смены контекста. - Тестовые наборы, которые мокают
navigator/process.platformв каждом тесте без повторного импорта модуля.
Устаревший алиас
detectIsiOS()
boolean · идентична detectIsIOS()
Устарела — переименована в detectIsIOS() (заглавная OS) для согласованности с остальным API в v2.0. Всё ещё работает, но выводит предупреждение console.warn об устаревании один раз за сессию (начиная с v2.2.1 — вызовите resetDetectionCache(), чтобы предупреждение появилось снова) и будет удалена в v3.0. Полный changelog v1→v2 см. в разделе Миграция.
detectIsiOS() // ⚠ устарело — выводит console.warn один раз за сессию
detectIsIOS() // ✓ используйте это вместоКатегория устройства
Быстрые грубые проверки, группирующие значения ОС в категории «мобильное» и «десктопное».
import { isMobileDevice, isDesktopDevice } from 'os-detect'
isMobileDevice() // true, если iOS или Android
isDesktopDevice() // true, если macOS, Windows, Linux или ChromeOSЗаметка:
isMobileDevice()иisDesktopDevice()не являются взаимоисключающими. Устройство с нераспознанной ОС вернётfalseдля обеих. На текущем наборе распознаваемых значений ОС пересечений нет.
Форм-фактор и ввод
getFormFactor()
FormFactor — 'phone' | 'tablet' | 'desktop' | 'tv' | 'unknown'
Определяется по ОС и физическому размеру экрана — не по наличию сенсорного экрана, так что сенсорный ноутбук на Windows всё равно вернёт 'desktop', никогда не 'tablet'. Порядок разрешения:
detectIsTV()равноtrue→'tv'- iOS или Android, меньшая сторона экрана
>= 768px(классическая граница для планшета) →'tablet', иначе'phone' - macOS, Windows, Linux или ChromeOS →
'desktop' - Всё остальное, либо нет
screenдля измерения (Node.js/SSR) →'unknown'
import { getFormFactor } from 'os-detect'
const formFactor = getFormFactor()Тип FormFactor
type FormFactor = 'phone' | 'tablet' | 'desktop' | 'tv' | 'unknown'detectHasTouch()
boolean
true, если у устройства вообще есть сенсорный экран, независимо от того, какой тип ввода сейчас основной. В Node.js всегда false. Сначала проверяет navigator.maxTouchPoints, затем переходит на устаревшее navigator.msMaxTouchPoints и, наконец, на 'ontouchstart' in window.
import { detectHasTouch } from 'os-detect'
detectHasTouch() // true на любом устройстве с сенсорным экраном — включая гибридные ноутбукиgetPrimaryInput()
PrimaryInput — 'mouse' | 'touch' | 'unknown'
Не кэшируется — в отличие от всех остальных функций на этой странице, getPrimaryInput() заново читает медиа-фичу pointer при каждом вызове, поскольку основной тип ввода может по-настоящему измениться прямо во время сессии (у гибридного устройства подключили или отключили клавиатуру/мышь). Читает window.matchMedia('(pointer: fine)') и (pointer: coarse); возвращает 'unknown', если matchMedia недоступен (старые браузеры, Node.js/SSR) или ни один из запросов не совпал. Используйте usePrimaryInput() из os-detect/vue или os-detect/react, чтобы реагировать на это вживую, вместо того чтобы опрашивать эту функцию вручную.
import { getPrimaryInput } from 'os-detect'
getPrimaryInput() // 'mouse' | 'touch' | 'unknown'Тип PrimaryInput
type PrimaryInput = 'mouse' | 'touch' | 'unknown'getPixelRatio()
number — window.devicePixelRatio, либо 1 в Node.js/SSR
Не кэшируется — дёшево читать вживую, а значение может измениться на десктопе, когда окно перетаскивают между мониторами с разным масштабированием.
import { getPixelRatio } from 'os-detect'
getPixelRatio() // например, 2 на Retina-экранеdetectIsTV()
boolean
Best-effort совпадение с известными платформами смарт-ТВ (Tizen, webOS, Android TV/Google TV, HbbTV, Fire TV, Sony BRAVIA, VIDAA). В Node.js всегда false.
import { detectIsTV } from 'os-detect'
detectIsTV() // true на Samsung Tizen TV, LG webOS TV, Android TV и т. д.Заметка: определение ТВ по userAgent по своей природе best-effort — некоторые браузеры смарт-ТВ отправляют почти обычный Android/Chrome userAgent вообще без надёжного ТВ-специфичного маркера, и на них возможен недодетект. Функция спроектирована так, чтобы никогда не принять телефон, планшет или десктоп за телевизор.
Рантайм-окружение
getRuntime()
Runtime — 'node' | 'browser' | 'webworker' | 'unknown'
Проверяется в этом порядке: detectIsWebWorker() → detectIsBrowser() → detectIsNode(). 'browser' побеждает 'node', когда присутствуют и window, и process — это renderer-процесс Electron/NW.js с включённой Node-интеграцией — см. detectIsElectron() ниже, чтобы отличить этот случай от обычной вкладки браузера.
import { getRuntime } from 'os-detect'
getRuntime() // 'browser' во вкладке, 'node' в обычном скрипте, 'webworker' внутри WorkerТип Runtime
type Runtime = 'node' | 'browser' | 'webworker' | 'unknown'detectIsNode()
boolean
true в обычном Node.js-скрипте, главном процессе Electron, либо renderer-процессе Electron/NW.js с включённой Node-интеграцией. Читает process.versions.node напрямую, поэтому остаётся точной, даже когда одновременно присутствует браузероподобный navigator.
import { detectIsNode } from 'os-detect'
detectIsNode() // true везде, где задан process.versions.nodedetectIsBrowser()
boolean
true, когда существуют и window, и document: реальная вкладка браузера или renderer-процесс Electron/NW.js. false в Node.js, внутри Web Worker и во время SSR.
import { detectIsBrowser } from 'os-detect'
detectIsBrowser() // false на сервере, true после гидратацииdetectIsWebWorker()
boolean
true внутри Dedicated, Shared или Service Worker. Проверяет наличие self без window, плюс importScripts (определён на WorkerGlobalScope, от которого наследуют все три типа worker'ов) — одного self без window недостаточно, поскольку в обычном Node.js нет ни того, ни другого.
import { detectIsWebWorker } from 'os-detect'
detectIsWebWorker() // true только внутри контекста WorkerdetectIsElectron()
boolean
true в главном процессе Electron либо в renderer-процессе, с включённой Node-интеграцией или без неё. Сначала проверяет process.versions.electron, а для изолированного (sandboxed/contextIsolated) renderer-процесса, где process вообще не доступен коду страницы, переходит на токен Electron/ в navigator.userAgent.
import { getRuntime, detectIsElectron } from 'os-detect'
if (getRuntime() === 'browser' && detectIsElectron()) {
console.log('Работаем внутри renderer-процесса Electron')
}detectIsPWA()
boolean
true, когда приложение запущено установленным, в собственном автономном окне, а не в обычной вкладке браузера. В Node.js всегда false. Проверяет по порядку: медиа-фичи display-mode: standalone и display-mode: window-controls-overlay, устаревший флаг iOS Safari navigator.standalone, и referrer вида android-app:// для Trusted Web Activity.
import { detectIsPWA } from 'os-detect'
detectIsPWA() // true после установки и запуска в автономном режимеТипы TypeScript
Все публичные типы экспортируются из корня пакета:
import type { OS, FormFactor, Runtime, PrimaryInput } from 'os-detect'
// OS: 'ios' | 'macos' | 'android' | 'windows' | 'linux' | 'chromeos' | 'unknown'
// FormFactor: 'phone' | 'tablet' | 'desktop' | 'tv' | 'unknown'
// Runtime: 'node' | 'browser' | 'webworker' | 'unknown'
// PrimaryInput: 'mouse' | 'touch' | 'unknown'Сужение типа через getOS()
import { getOS } from 'os-detect'
import type { OS } from 'os-detect'
const os: OS = getOS()
switch (os) {
case 'ios':
case 'android':
console.log('Mobile device')
break
case 'windows':
case 'macos':
case 'linux':
case 'chromeos':
console.log('Desktop device')
break
case 'unknown':
console.log('Unrecognised OS')
break
}TypeScript знает, что после switch все ветки исчерпаны — отдельный default не нужен, если вы обрабатываете 'unknown'.