Skip to content

yankouskia/get-browser

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

30 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

get-browser β€” lightweight, SSR-safe browser detection

get-browser

Tiny, typed, SSR-safe browser detection.
One call. One canonical answer. ~1.4Β kB min+gzip. Zero dependencies.

npm size CI types MIT

πŸ“š Docs site Β· πŸ§ͺ Playground Β· 🍳 Recipes Β· ↗️ v1 β†’ v2


import { detect, getOS, isMobile, browsers, oses } from 'get-browser';

if (detect() === browsers.SAFARI && isMobile()) {
  applyMobileSafariFix();
}

const shortcut = getOS() === oses.MACOS ? '⌘ K' : 'Ctrl K';

That's the whole pitch. detect() returns a strict browser union β€” 'chrome' | 'edge' | 'firefox' | 'safari' | 'opera' | 'ie' | 'android' | 'unknown'. getOS() returns a strict OS union β€” 'macos' | 'windows' | 'linux' | 'ios' | 'android' | 'chromeos' | 'unknown'. A handful of tree-shakeable predicates do the boolean versions.

Install

pnpm add get-browser    # or npm / yarn / bun

No bundler? Drop in the UMD bundle:

<script src="https://unpkg.com/get-browser/dist/umd/get-browser.global.js"></script>
<script>
  if (GetBrowser.isMobile()) document.body.classList.add('is-mobile');
</script>

Why you'd use this

  • πŸͺΆ Tiny β€” ~1.4 kB min+gzip, zero dependencies, tree-shakeable.
  • 🧠 Typed β€” detect() returns the Browser union, never string. Exhaustive switches compile.
  • πŸ—οΈ SSR-safe β€” every detector takes { userAgent }. Works in Node, Next.js, Remix, Astro, Workers, Deno.
  • 🎯 Honest β€” it answers who, not what. For capability checks use @supports / matchMedia.

Tip

Want to see it in action without installing anything? Open the Playground β€” paste any user-agent and watch every predicate light up.

Usage

Switch on the browser
import { detect, browsers } from 'get-browser';

switch (detect()) {
  case browsers.CHROME:  loadChromeShim();          break;
  case browsers.SAFARI:  patchSafariScrollBug();    break;
  case browsers.FIREFOX: enableFirefoxOnlyFeature(); break;
  case browsers.UNKNOWN: /* bot or new browser */    break;
}
Booleans β€” tree-shakes to ~400 bytes per predicate
import { isMobile, isChrome, isSafari } from 'get-browser';

if (isMobile() && !isChrome()) showNonChromeMobileBanner();
if (isSafari() && isMobile()) applyMobileSafariFix();
Server-side β€” Next.js, Remix, Workers, Deno
// Next.js Edge route β€” runs on Cloudflare too
export const runtime = 'edge';

import { detect, getOS } from 'get-browser';

export function GET(req: Request) {
  const userAgent = req.headers.get('user-agent') ?? '';
  return Response.json({
    browser: detect({ userAgent }),
    // Prefer Sec-CH-UA-Platform β€” Chrome's UA Reduction is hollowing
    // out the legacy UA string. Get-browser reads either.
    os: getOS({
      userAgent,
      clientHints: { platform: req.headers.get('sec-ch-ua-platform') ?? undefined },
    }),
  });
}

The library never touches window at import time. Pass an explicit UA and detection becomes a pure function β€” perfect for tests and SSR. Full framework cookbook in the SSR guide.

Cross-platform UI β€” shortcuts, downloads, deep links
import { getOS, oses } from 'get-browser';

const os = getOS();

const shortcut    = os === oses.MACOS ? '⌘ K' : 'Ctrl K';
const downloadUrl = os === oses.WINDOWS ? '/dl/app.exe'
                  : os === oses.MACOS   ? '/dl/app.dmg'
                  : os === oses.LINUX   ? '/dl/app.deb'
                  : '/dl/';
const storeUrl    = os === oses.IOS     ? 'https://apps.apple.com/…'
                  : os === oses.ANDROID ? 'https://play.google.com/…'
                  : '/install';
In-app browsers β€” Instagram, Facebook, TikTok, X, LinkedIn, …
import { isInAppBrowser } from 'get-browser';

// OAuth providers (Google, Apple, Microsoft) block sign-in inside
// most in-app browsers. Bounce to the system browser first.
if (isInAppBrowser()) {
  showOpenInBrowserBanner({
    message: 'Tap β‹― β†’ "Open in browser" to continue with Google sign-in.',
  });
}

Catches Facebook (FBAN/FBAV/FB_IAB), Instagram, X/Twitter, LinkedIn, TikTok, Snapchat, WeChat, Line, Telegram, Pinterest. Stable token-based matching β€” version-agnostic.

Type-safe analytics tagging
import { type Browser, detect } from 'get-browser';

const engineOf = (b: Browser) =>
  ({
    chrome: 'chromium', edge: 'chromium', opera: 'chromium',
    firefox: 'gecko',   safari: 'webkit', ie: 'trident',
    android: 'legacy-webkit', unknown: 'unknown',
  } as const)[b];

analytics.track('page_view', { engine: engineOf(detect()) });

If a future major bumps Browser, the compiler refuses to build. No silent drift.

API

A small surface β€” every export pulls its weight.

detect(opts?) Returns one of the browsers values
getOS(opts?) Returns one of the oses values
isChrome / isEdge / isFirefox / isSafari (opts?) => boolean
isOpera / isIE / isAndroid / isMobile (opts?) => boolean
isInAppBrowser (opts?) => boolean β€” true inside Instagram, Facebook, TikTok, X, LinkedIn, …
browsers, oses Frozen enums: { CHROME: 'chrome', ... }, { MACOS: 'macos', ... }
Browser, OS, DetectOptions, ClientHints Type-only exports

opts is { userAgent?: string; vendor?: string; clientHints?: { platform?: string } } β€” pass userAgent for SSR or tests, pass clientHints.platform (the Sec-CH-UA-Platform header) for the most reliable OS read.

Full API reference β†’

How it stacks up

Bundle (min+gz) get-browser detect-browser bowser ua-parser-js
πŸ† ~1.4 kB ~2 kB ~7 kB ~10 kB

Pick ua-parser-js if you need version numbers or device info. Pick get-browser if you just need the single, lowercase, typed answer to which browser is this? β€” see the full comparison.

What it detects

Chrome Edge Firefox Safari Opera Safari iOS Android IE

Chrome, Edge (legacy & Chromium), Firefox, Safari (desktop, iOS, iPadOS), Opera (Presto & OPR), Internet Explorer 6-11, Android WebView β€” including iOS variants (CriOS, FxiOS, EdgiOS) and mobile / tablet user-agents. Coverage details: browser support.

Requirements

  • Node β‰₯ 20 (active LTS β€” 20, 22, 24)
  • TypeScript β‰₯ 5.0 if you use types
  • Browsers β€” evergreen. UMD bundle is ES2018.

Documentation

The full docs are built with Docusaurus and deployed to GitHub Pages:

πŸ“š Docs πŸ”Œ API πŸ§ͺ Playground 🍳 Recipes πŸ—οΈ SSR πŸ”„ Migration

Run the docs locally:

pnpm install
pnpm run build              # build the library first
pnpm run website:install
pnpm run website:dev        # http://localhost:3000

Contributing & license

PRs welcome β€” see CONTRIBUTING.md. For security issues, see SECURITY.md (please don't open public issues for vulnerabilities).

MIT Β© yankouskia and contributors.

About

πŸ’» Lightweight tool to identify the browser (mobile+desktop detection)πŸ“±

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors