getEngine()
The rendering-engine counterpart to
detect(). Returns one of theenginesvalues, narrowed to theEngineunion.
| Signature | (options?: DetectOptions) => Engine |
| Returns | 'blink' | 'gecko' | 'webkit' | 'trident' | 'presto' | 'edgehtml' | 'unknown' |
| SSR safe | ✅ Pass { userAgent } to pin |
Why the engine, not the brand?
Rendering bugs live in the engine, not the badge on the icon. Two reasons this is the function you often actually want:
-
iOS forces WebKit on everyone. Apple requires every browser on iOS/iPadOS to use WKWebView. Chrome-iOS, Firefox-iOS, and Edge-iOS all render with WebKit — they just paint a different UI on top.
detect()honestly reports them aschrome/firefox/edge, but for a rendering workaround you wantgetEngine(), which reportswebkitfor all of them in one check. -
The whole Chromium family shares Blink. Chrome, Edge, Opera, Brave, Vivaldi, Arc — all Blink. If your fix is engine-level,
getEngine() === engines.BLINKis one comparison instead of five.
import { getEngine, engines } from 'get-browser';
// One check covers Safari + Chrome-iOS + Firefox-iOS + Edge-iOS.
if (getEngine() === engines.WEBKIT) {
applyWebkitScrollFix();
}
browser → engineA naive { chrome: 'blink', safari: 'webkit', … }[detect()] lookup is wrong on iOS — it maps Chrome-iOS to Blink when the page is really rendered by WebKit. getEngine() reads the platform from the UA and gets it right.
The engines enum
export const engines: {
readonly BLINK: 'blink';
readonly EDGEHTML: 'edgehtml';
readonly GECKO: 'gecko';
readonly PRESTO: 'presto';
readonly TRIDENT: 'trident';
readonly WEBKIT: 'webkit';
readonly UNKNOWN: 'unknown';
};
| Value | Engine | Browsers |
|---|---|---|
blink | Blink (Chromium) | Chrome, Edge, Opera, Brave, Vivaldi, Arc, modern Android WebView |
gecko | Gecko | Firefox on every platform except iOS |
webkit | WebKit | Safari, every browser on iOS/iPadOS, pre-2014 Android Browser |
trident | Trident | Internet Explorer 6–11 |
presto | Presto | Opera 12 and earlier, Opera Mini |
edgehtml | EdgeHTML | Legacy Microsoft Edge 12–18 (the Edge/ token) |
unknown | — | bots, brand-new engines, empty UA |
Blink vs "Chromium": Blink is the engine; Chromium is the project it lives in. The canonical value is
'blink'— that's the actual rendering engine, and it's whatua-parser-jsandbowserreport too.
Detection order
Most-specific first:
- Trident —
Trident/orMSIE. - EdgeHTML — the legacy
Edge/token (checked before Blink, since those UAs also carryChrome/). - Presto —
Presto/orOpera Mini. - WebKit (iOS) — any
iPhone/iPad/iPod, orCriOS/FxiOS/EdgiOS/OPiOS. Every iOS browser is WebKit. - Gecko — a real
Gecko/<digits>build token orFirefox/(Chromium's"like Gecko"is deliberately not matched). - Blink —
Chrome/,Chromium/,Edg/, orOPR/. - WebKit (Safari / legacy) — any remaining
Safari//AppleWebKit— desktop Safari or the legacy Android Browser. 'unknown'.
Examples
- WebKit workaround
- Honest analytics
- SSR
- Unit test
import { getEngine, engines } from 'get-browser';
// iOS Safari (and therefore every iOS browser) needs the 100vh fix.
if (getEngine() === engines.WEBKIT) {
const setVh = () =>
document.documentElement.style.setProperty('--vh', `${innerHeight * 0.01}px`);
setVh();
addEventListener('resize', setVh, { passive: true });
}
import { detect, getEngine } from 'get-browser';
// `browser` answers "who", `engine` answers "what renders it" — and it's
// correct on iOS, where every browser is really WebKit.
analytics.track('page_view', {
browser: detect(),
engine: getEngine(),
});
import { getEngine } from 'get-browser';
export function GET(req: Request) {
const engine = getEngine({ userAgent: req.headers.get('user-agent') ?? '' });
return Response.json({ engine });
}
import { describe, expect, it } from 'vitest';
import { getEngine, engines } from 'get-browser';
it('treats Chrome-on-iOS as WebKit', () => {
const ua =
'Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 ' +
'(KHTML, like Gecko) CriOS/131.0.6778.135 Mobile/15E148 Safari/604.1';
expect(getEngine({ userAgent: ua })).toBe(engines.WEBKIT);
});
Pairs with detect() and getOS()
Three orthogonal axes — who, what renders it, where it runs:
import { detect, getEngine, getOS } from 'get-browser';
// Chrome on an iPhone:
detect(); // → 'chrome' (the brand)
getEngine(); // → 'webkit' (what actually paints — WKWebView)
getOS(); // → 'ios' (the platform)
Caveats
- Not a feature check. Knowing the engine is not the same as knowing a feature is supported. For "does this support
:has()?" useCSS.supports()/@supports.getEngine()is for grouping known engine-level quirks and for analytics. edgehtml/prestoare effectively extinct but reported honestly when their UAs appear. Exhaustiveswitchstatements should still handle them (or use adefault).