Sitelet https://github.com/matthewhudson/current-device
Skip to content

Latest commit

 

History

431 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CI npm version npm downloads

current-device adds CSS classes to <html> for the visitor's operating system, device type and orientation, and gives you the same answers in JavaScript:

<!-- iPhone -->        <html class="ios iphone mobile portrait">
<!-- Galaxy Tab -->    <html class="android tablet landscape">
<!-- MacBook -->       <html class="macos desktop landscape">
import device from "current-device";

device.type; // 'mobile' | 'tablet' | 'desktop' | 'unknown'
device.os; // 'ios' | 'android' | 'windows' | 'macos' | ...
device.orientation; // 'portrait' | 'landscape' | 'unknown'
device.mobile(); // boolean

It is a small (under 3 KB gzipped), dependency-free classifier built for styling, layout conventions and analytics. It reads the user agent string once and sorts the device into a handful of buckets. It does not identify device models, browsers or OS versions, and user agent sniffing has hard limits in 2026: read Limitations before you rely on it.

View the Demo →

Installation

npm install current-device
// ES modules (recommended)
import device from "current-device";

// CommonJS
const device = require("current-device").default;

Importing the module adds the classes to <html> and starts listening for orientation changes. Nothing else is needed.

CDN / Script Tag

<script src="https://unpkg.com/current-device@2/dist/index.global.js"></script>
<script>
  console.log(device.type); // 'mobile', 'tablet' or 'desktop'
</script>

The script defines one global, device. See device.noConflict() if that name is taken.

React

current-device/react has hooks for React 18 and later:

import { useDevice, useOrientation } from "current-device/react";

function Navigation() {
  const { type, os, orientation } = useDevice();
  return type === "mobile" ? <MobileNav /> : <DesktopNav />;
}

function Player() {
  const orientation = useOrientation();
  return <video className={orientation} />;
}

Both re-render the component when the orientation changes.

Server-Side Rendering

current-device can be imported on a server, for example with Next.js, Remix or Astro. A server can't see the device, so there:

  • no classes are added to <html>,
  • every method, such as device.mobile(), returns false,
  • device.type, device.os and device.orientation are 'unknown'.

The React hooks also return 'unknown' on the server and while the page hydrates, and the real values right after. Render something that fits every device for 'unknown'.

In Next.js, components that use the hooks need the "use client" directive.

In a server-rendered app, don't call device methods such as device.mobile() while a component renders. They return false on the server and the real value in the browser, which causes a hydration error, and React then removes the classes from <html>. Use the hooks, or call the methods in an effect or an event handler.

TypeScript

The package ships its own types:

import device from "current-device";
import type { Device, DeviceType, DeviceOs, DeviceOrientation } from "current-device";

const os: DeviceOs = device.os;
const type: DeviceType = device.type;
const isPhone: boolean = device.mobile();

CSS Classes

One operating-system class and one type class are added to <html>, plus the orientation class.

Device CSS Classes
iPhone ios iphone mobile
iPad (also iPadOS 13+ with its Mac user agent) ios ipad tablet
iPod touch ios ipod mobile
Mac macos desktop
Android phone android mobile
Android tablet android tablet
Android TV, Google TV, Fire TV, Chromecast android television
HarmonyOS phone harmonyos mobile
HarmonyOS tablet harmonyos tablet
HarmonyOS PC harmonyos desktop
ChromeOS (also an Android app on a Chromebook) chromeos desktop
Windows desktop, laptop or 2-in-1 windows desktop
Windows RT tablet windows tablet
Windows Phone, Windows Mobile windows mobile
Linux desktop linux desktop
Other television or set-top box (Tizen, webOS, Roku, Apple TV, HbbTV...) television
BlackBerry phone blackberry mobile
BlackBerry PlayBook blackberry tablet
Firefox OS or KaiOS phone fxos mobile
Firefox OS tablet fxos tablet
MeeGo meego mobile
Other phone (feature phone, Symbian, Tizen, Sailfish...) mobile
Anything else desktop

Two more classes describe the runtime rather than the device:

Runtime CSS Class
Cordova app (window.cordova exists and the page is loaded from file:) cordova, added to the classes above
NW.js or Electron renderer (window.process exists) node-webkit. On Windows and macOS the classes above win; on Linux it is added instead of them

Orientation

Orientation CSS Class
Landscape landscape
Portrait portrait

The orientation class is the only one that changes while the page is open. On phones and tablets it follows the screen's orientation; on desktops, where the screen doesn't rotate, it follows the window's aspect ratio, so a portrait monitor or a tall window is portrait. A square window is portrait, like the CSS (orientation: portrait) media query.

JavaScript API

Type

Type Method
Phone device.mobile()
Tablet device.tablet()
Neither: desktops, laptops and televisions device.desktop()

Exactly one of the three is true in a browser.

Operating System and Device

Device Method
iOS or iPadOS device.ios()
iPhone device.iphone()
iPad device.ipad()
iPod touch device.ipod()
Mac device.macos()
Android (phones, tablets, TVs, HarmonyOS, Android apps on a Chromebook) device.android()
Android phone device.androidPhone()
Android tablet device.androidTablet()
HarmonyOS, including HarmonyOS NEXT (the Android-based versions are also android()) device.harmonyos()
ChromeOS device.chromeos()
Windows device.windows()
Windows Phone, Windows Mobile device.windowsPhone()
Windows RT tablet device.windowsTablet()
Linux desktop device.linux()
Television or set-top box (any OS) device.television()
BlackBerry device.blackberry()
BlackBerry phone device.blackberryPhone()
BlackBerry PlayBook device.blackberryTablet()
Firefox OS or KaiOS device.fxos()
Firefox OS or KaiOS phone device.fxosPhone()
Firefox OS tablet device.fxosTablet()
MeeGo device.meego()

Runtime

Runtime Method
Cordova app device.cordova()
NW.js or Electron renderer device.nodeWebkit()

Orientation

Orientation Method
Landscape device.landscape()
Portrait device.portrait()
const unsubscribe = device.onChangeOrientation((newOrientation: "landscape" | "portrait") => {
  console.log(`New orientation is ${newOrientation}`);
});

unsubscribe(); // removes the callback again

Properties

The properties hold the first match, so you don't have to call the methods one by one.

Property Type Value
device.type DeviceType 'mobile', 'tablet', 'desktop' or 'unknown'
device.os DeviceOs 'ios', 'android', 'harmonyos', 'chromeos', 'windows', 'macos', 'linux', 'television', 'blackberry', 'fxos', 'meego' or 'unknown'
device.orientation DeviceOrientation 'landscape', 'portrait' or 'unknown'

Notes on device.os:

  • It is 'ios' for every iPhone, iPad and iPod touch. The DeviceOs type also lists 'iphone', 'ipad' and 'ipod' for backwards compatibility, but device.os never has those values; use device.iphone(), device.ipad() and device.ipod() instead. The three values will be removed from the type in 3.0.
  • Where two checks match, the more specific platform wins: a HarmonyOS device is 'harmonyos' (and device.android() is also true on the Android-based versions), an Android app running on a Chromebook is 'chromeos', and an Android TV is 'android' with device.television() true. 'television' is used for TVs whose operating system isn't recognised (Tizen, webOS, Roku...).
  • Feature phones and phones on platforms without their own method are 'unknown' with device.type === 'mobile'.

device.type and device.os are computed once when the module is imported; only device.orientation changes afterwards.

device.noConflict()

Returns the device object and gives the global device variable back to its previous owner. Only relevant for the <script> build.

const currentDevice: Device = device.noConflict();

Device Support

Current platforms:

  • iOS and iPadOS: iPhone, iPad, iPod touch
  • macOS
  • Android: phones, tablets and TVs
  • HarmonyOS, including HarmonyOS NEXT (OpenHarmony): phones, tablets and PCs
  • ChromeOS, including Android apps running on a Chromebook
  • Windows: desktops, laptops and 2-in-1s (desktop), Windows RT tablets, Windows Phone and Windows Mobile
  • Linux desktops
  • Televisions and set-top boxes: Android TV, Google TV, Fire TV, Chromecast, Samsung Tizen, LG webOS, Roku, Apple TV, HbbTV, Vizio, Hisense VIDAA, Opera TV
  • Feature phones and other handsets (Java ME, Symbian, KaiOS, Tizen, Sailfish, Palm webOS...) as mobile

Legacy platforms, still recognised by user agent although their browsers cannot run the ES2015 bundle (see Browser Support): BlackBerry and the PlayBook, Windows Phone, Firefox OS and MeeGo. Their methods stay in 2.x for compatibility.

Browser Support

current-device 2.x ships ES2015 JavaScript without polyfills. It runs in any browser with full ES2015 support:

Browser Minimum version
Chrome, Android WebView 51
Edge 15
Firefox 54
Safari (macOS and iOS) 10
Samsung Internet 5
Opera 38

Internet Explorer and other browsers without ES2015 support are not supported. This includes the built-in browsers of several platforms that current-device still recognizes by user agent: the Android stock browser (Android 4.4 and earlier), BlackBerry, Windows Phone 8.x, Firefox OS and MeeGo. If you need to support them, use current-device 0.10.x, which ships ES5:

<script src="https://unpkg.com/current-device@0.10.2/umd/current-device.min.js"></script>

Limitations

current-device classifies the user agent string, once, at import. That is enough to tell phones, tablets and desktops apart and to name the operating system for the vast majority of visitors (89% of the 35,000 user agents in the Matomo device-detector fixtures get the right type). It is not device identification, and these limits are inherent to the approach:

  • Results don't follow the window. device.type, device.os and their classes describe the device and are computed once. Resizing the browser, docking a tablet or opening the page in a split screen only updates the orientation. Use CSS media queries for layout that should follow the viewport.
  • Chrome's reduced user agent. Since Chrome 110 every Android Chrome user agent says Android 10; K, without the device model. Phone versus tablet then rests on Chrome's own Mobile token, which Chrome adds on screens narrower than 600dp, so a 7" or 8" tablet is a phone. Tablet model names still help in browsers that send them (WebViews, Samsung Internet, Huawei Browser): Galaxy Tab, Lenovo Tab, MediaPad/MatePad, Huawei -W09 models, Kindle Fire and a few others are tablets even with Mobile.
  • Apple's Mac user agent. iPadOS 13+ and an iPhone with "Request Desktop Website" both send the Mac Safari user agent. current-device recognises them by their touchscreen (navigator.maxTouchPoints) and tells the iPhone from the iPad by screen size. This relies on navigator.platform, which browsers have deprecated; if Safari stops reporting it, desktop-mode iPads become Macs.
  • Windows and ChromeOS tablets are desktops. No modern browser on Windows or ChromeOS puts a tablet hint in the user agent, so a Surface, a 2-in-1 or a Chromebook tablet is desktop. Only Windows RT devices, whose Internet Explorer said ARM and Touch, are windows tablet.
  • Client Hints are not used. Detection is user agent only; navigator.userAgentData is Chromium-only and its useful fields are asynchronous, which doesn't fit classes that must be set at import time.
  • Foldables. Unfolded, a foldable's screen is wider than 600dp and Chrome drops Mobile. Galaxy Z Fold and Pixel Fold are phones in either state; other foldables are tablets when unfolded.
  • Televisions have type: 'desktop' with the television class, and an Android TV has os: 'android'; there is no television type. Wearables, game consoles, car displays, smart displays and VR headsets have no category of their own and land in mobile or desktop.
  • A phone whose model name contains "TV" as a separate word (for example "KAZAM TV 45") is detected as a television.
  • KaiOS keeps the Firefox OS user agent it descends from, so it is reported as fxos, not as a separate platform.
  • No browsers, versions or models. current-device does not report the browser, the OS version or the device model. For those, use a full parser such as ua-parser-js or device-detector.

Best Practices

Use current-device for what only the platform can tell you: interaction conventions (Android and iOS users expect different controls), app-store links, platform-specific help text, and analytics segments.

Don't use it as a proxy for capabilities or screen size. The browser can tell you those directly, on every device, and keeps them up to date:

  • layout that depends on the viewport: CSS media queries, or matchMedia()
  • touch versus mouse: (pointer: coarse) and (hover: none) media queries
  • orientation-dependent layout: the (orientation: portrait) media query
  • an API or feature: check for the feature itself

In short, check for features when you need features, and check for the platform when you need the platform.

Contributors

Thanks goes to these wonderful people (emoji key):

Matthew Hudson
Matthew Hudson

💻 🚧
Rafael Terán
Rafael Terán

💻
Allan
Allan

👀
martinwepner
martinwepner

💻
Evan Hahn
Evan Hahn

💻
Jonas Jonny
Jonas Jonny

💻
Guilherme Simoes
Guilherme Simoes

💻
Bohdan Zhuravel
Bohdan Zhuravel

💻
Markus Kaiserswerth
Markus Kaiserswerth

💻
Athou
Athou

💻
PatrickJS
PatrickJS

💻
André Tarnowsky
André Tarnowsky

💻
JSteunou
JSteunou

💻
NoobsArePeople2
NoobsArePeople2

💻
Michael Chambaud
Michael Chambaud

💻
Giorgio Cefaro
Giorgio Cefaro

💻
Daniel Paul
Daniel Paul

💻
Lauren Tan
Lauren Tan

💻
Kevin Kirsche
Kevin Kirsche

💻
sergeybochkarev
sergeybochkarev

💻
Andrey
Andrey

💻
Mustard Andrew
Mustard Andrew

💻
Jake
Jake

💻
Mikhail
Mikhail

💻
Ajith
Ajith

💻
Ivan Križnar
Ivan Križnar

💻
LeeKatz1
LeeKatz1

💻
thomasjonas
thomasjonas

💻
girvan
girvan

💻
Anson Hou
Anson Hou

💻
Vishnu Singh
Vishnu Singh

💻
Дмитрий Уткин
Дмитрий Уткин

💻
Marcel Blum
Marcel Blum

💻

This project follows the all-contributors specification. Contributions of any kind welcome!

About

📱 The easiest way to write conditional CSS and/or JavaScript based on device operating system (iOS, Android, Blackberry, Windows, Firefox OS, MeeGo), orientation (Portrait vs. Landscape), and type (Tablet vs. Mobile).

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

3.9k stars

Watchers

117 watching

Forks

Releases

Used by

Contributors

Languages