• Stars
    star
    886
  • Rank 49,031 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 14 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Useragent parser for Node.js, ported from browserscope.org

useragent - high performance user agent parser for Node.js

Useragent originated as port of browserscope.org's user agent parser project also known as ua-parser. Useragent allows you to parse user agent strings with high performance and accuracy by using hand tuned regular expressions for browser matching. This database is needed to ensure that every browser is correctly parsed as every browser vendor implements it's own user agent schema. This is why regular user agent parsers have major issues because they will most likely parse out the wrong browser name or confuse the render engine version with the actual version of the browser.


Build status BuildStatus


High performance

The module has been developed with a benchmark driven approach. It has a pre-compiled library that contains all the Regular Expressions and uses deferred or on demand parsing for Operating System and device information. All this engineering effort has been worth it as this benchmark shows:

Starting the benchmark, parsing 62 useragent strings per run

Executed benchmark against node module: "useragent"
Count (61), Cycles (5), Elapsed (5.559), Hz (1141.3739447904327)

Executed benchmark against node module: "useragent_parser"
Count (29), Cycles (3), Elapsed (5.448), Hz (545.6817291171243)

Executed benchmark against node module: "useragent-parser"
Count (16), Cycles (4), Elapsed (5.48), Hz (304.5373431830105)

Executed benchmark against node module: "ua-parser"
Count (54), Cycles (3), Elapsed (5.512), Hz (1018.7561434659247)

Module: "useragent" is the user agent fastest parser.

Hand tuned regular expressions

This module relies on uap-core's regexes.yaml user agent database to parse user agent strings.

This database is up-to-date thanks to contributors such as you. Feel free to submit issues and pull requests.


Installation

Installation is done using the Node Package Manager (NPM). If you don't have NPM installed on your system you can download it from npmjs.org

npm install useragent --save

The --save flag tells NPM to automatically add it to your package.json file.


API

Include the useragent parser in you node.js application:

var useragent = require('useragent');

The useragent library allows you do use the automatically installed RegExp library or you can fetch it live from the remote servers. So if you are paranoid and always want your RegExp library to be up to date to match with agent the widest range of useragent strings you can do:

var useragent = require('useragent');
useragent(true);

This will async load the database from the server and compile it to a proper JavaScript supported format. If it fails to compile or load it from the remote location it will just fall back silently to the shipped version. If you want to use this feature you need to add yamlparser and request to your package.json

npm install yamlparser --save
npm install request --save

useragent.parse(useragent string[, js useragent]);

This is the actual user agent parser, this is where all the magic is happening. The function accepts 2 arguments, both should be a string. The first argument should the user agent string that is known on the server from the req.headers.useragent header. The other argument is optional and should be the user agent string that you see in the browser, this can be send from the browser using a xhr request or something like this. This allows you detect if the user is browsing the web using the Chrome Frame extension.

The parser returns a Agent instance, this allows you to output user agent information in different predefined formats. See the Agent section for more information.

var agent = useragent.parse(req.headers['user-agent']);

// example for parsing both the useragent header and a optional js useragent
var agent2 = useragent.parse(req.headers['user-agent'], req.query.jsuseragent);

The parse method returns a Agent instance which contains all details about the user agent. See the Agent section of the API documentation for the available methods.

useragent.lookup(useragent string[, js useragent]);

This provides the same functionality as above, but it caches the user agent string and it's parsed result in memory to provide faster lookups in the future. This can be handy if you expect to parse a lot of user agent strings.

It uses the same arguments as the useragent.parse method and returns exactly the same result, but it's just cached.

var agent = useragent.lookup(req.headers['user-agent']);

And this is a serious performance improvement as shown in this benchmark:

Executed benchmark against method: "useragent.parse"
Count (49), Cycles (3), Elapsed (5.534), Hz (947.6844321931629)

Executed benchmark against method: "useragent.lookup"
Count (11758), Cycles (3), Elapsed (5.395), Hz (229352.03831239208)

useragent.fromJSON(obj);

Transforms the JSON representation of a Agent instance back in to a working Agent instance

var agent = useragent.parse(req.headers['user-agent'])
  , another = useragent.fromJSON(JSON.stringify(agent));

console.log(agent == another);

useragent.is(useragent string).browsername;

This api provides you with a quick and dirty browser lookup. The underlying code is usually found on client side scripts so it's not the same quality as our useragent.parse method but it might be needed for legacy reasons.

useragent.is returns a object with potential matched browser names

useragent.is(req.headers['user-agent']).firefox // true
useragent.is(req.headers['user-agent']).safari // false
var ua = useragent.is(req.headers['user-agent'])

// the object
{
  version: '3'
  webkit: false
  opera: false
  ie: false
  chrome: false
  safari: false
  mobile_safari: false
  firefox: true
  mozilla: true
  android: false
}

Agents, OperatingSystem and Device instances

Most of the methods mentioned above return a Agent instance. The Agent exposes the parsed out information from the user agent strings. This allows us to extend the agent with more methods that do not necessarily need to be in the core agent instance, allowing us to expose a plugin interface for third party developers and at the same time create a uniform interface for all versioning.

The Agent has the following property

  • family The browser family, or browser name, it defaults to Other.
  • major The major version number of the family, it defaults to 0.
  • minor The minor version number of the family, it defaults to 0.
  • patch The patch version number of the family, it defaults to 0.

In addition to the properties mentioned above, it also has 2 special properties, which are:

  • os OperatingSystem instance
  • device Device instance

When you access those 2 properties the agent will do on demand parsing of the Operating System or/and Device information.

The OperatingSystem has the same properties as the Agent, for the Device we don't have any versioning information available, so only the family property is set there. If we cannot find the family, they will default to Other.

The following methods are available:

Agent.toAgent();

Returns the family and version number concatinated in a nice human readable string.

var agent = useragent.parse(req.headers['user-agent']);
agent.toAgent(); // 'Chrome 15.0.874'

Agent.toString();

Returns the results of the Agent.toAgent() but also adds the parsed operating system to the string in a human readable format.

var agent = useragent.parse(req.headers['user-agent']);
agent.toString(); // 'Chrome 15.0.874 / Mac OS X 10.8.1'

// as it's a to string method you can also concat it with another string
'your useragent is ' + agent;
// 'your useragent is Chrome 15.0.874 / Mac OS X 10.8.1'

Agent.toVersion();

Returns the version of the browser in a human readable string.

var agent = useragent.parse(req.headers['user-agent']);
agent.toVersion(); // '15.0.874'

Agent.toJSON();

Generates a JSON representation of the Agent. By using the toJSON method we automatically allow it to be stringified when supplying as to the JSON.stringify method.

var agent = useragent.parse(req.headers['user-agent']);
agent.toJSON(); // returns an object

JSON.stringify(agent);

OperatingSystem.toString();

Generates a stringified version of operating system;

var agent = useragent.parse(req.headers['user-agent']);
agent.os.toString(); // 'Mac OSX 10.8.1'

OperatingSystem.toVersion();

Generates a stringified version of operating system's version;

var agent = useragent.parse(req.headers['user-agent']);
agent.os.toVersion(); // '10.8.1'

OperatingSystem.toJSON();

Generates a JSON representation of the OperatingSystem. By using the toJSON method we automatically allow it to be stringified when supplying as to the JSON.stringify method.

var agent = useragent.parse(req.headers['user-agent']);
agent.os.toJSON(); // returns an object

JSON.stringify(agent.os);

Device.toString();

Generates a stringified version of device;

var agent = useragent.parse(req.headers['user-agent']);
agent.device.toString(); // 'Asus A100'

Device.toVersion();

Generates a stringified version of device's version;

var agent = useragent.parse(req.headers['user-agent']);
agent.device.toVersion(); // '' , no version found but could also be '0.0.0'

Device.toJSON();

Generates a JSON representation of the Device. By using the toJSON method we automatically allow it to be stringified when supplying as to the JSON.stringify method.

var agent = useragent.parse(req.headers['user-agent']);
agent.device.toJSON(); // returns an object

JSON.stringify(agent.device);

Adding more features to the useragent

As I wanted to keep the core of the user agent parser as clean and fast as possible I decided to move some of the initially planned features to a new plugin file.

These extensions to the Agent prototype can be loaded by requiring the useragent/features file:

var useragent = require('useragent');
require('useragent/features');

The initial release introduces 1 new method, satisfies, which allows you to see if the version number of the browser satisfies a certain range. It uses the semver library to do all the range calculations but here is a small summary of the supported range styles:

  • >1.2.3 Greater than a specific version.
  • <1.2.3 Less than.
  • 1.2.3 - 2.3.4 := >=1.2.3 <=2.3.4.
  • ~1.2.3 := >=1.2.3 <1.3.0.
  • ~1.2 := >=1.2.0 <2.0.0.
  • ~1 := >=1.0.0 <2.0.0.
  • 1.2.x := >=1.2.0 <1.3.0.
  • 1.x := >=1.0.0 <2.0.0.

As it requires the semver module to function you need to install it seperately:

npm install semver --save

Agent.satisfies('range style here');

Check if the agent matches the supplied range.

var agent = useragent.parse(req.headers['user-agent']);
agent.satisfies('15.x || >=19.5.0 || 25.0.0 - 17.2.3'); // true
agent.satisfies('>16.12.0'); // false

Migrations

For small changes between version please review the changelog.

Upgrading from 1.10 to 2.0.0

  • useragent.fromAgent has been removed.
  • agent.toJSON now returns an Object, use JSON.stringify(agent) for the old behaviour.
  • agent.os is now an OperatingSystem instance with version numbers. If you still a string only representation do agent.os.toString().
  • semver has been removed from the dependencies, so if you are using the require('useragent/features') you need to add it to your own dependencies

Upgrading from 0.1.2 to 1.0.0

  • useragent.browser(ua) has been renamed to useragent.is(ua).
  • useragent.parser(ua, jsua) has been renamed to useragent.parse(ua, jsua).
  • result.pretty() has been renamed to result.toAgent().
  • result.V1 has been renamed to result.major.
  • result.V2 has been renamed to result.minor.
  • result.V3 has been renamed to result.patch.
  • result.prettyOS() has been removed.
  • result.match has been removed.

License

MIT

More Repositories

1

memcached

A fully featured Memcached client build on top of Node.js. Build with scaling in mind so it will support Memcached clusters and consistent hashing.
JavaScript
1,311
star
2

node-hashring

hashring is a consistent hashing algorithm for Node.js that is compatible with libketama and python's hash_ring package
JavaScript
349
star
3

versions

Versions, A small module for creating a flexible CDN application
JavaScript
204
star
4

licensing

Discover the license footprint of your application
JavaScript
87
star
5

jackpot

Jackpot, tcp connection pooling for Node.js
JavaScript
74
star
6

creditcard

Creditcard number parsing, validation and information extraction
JavaScript
61
star
7

npmjs

An alternative npm registry client that I like.
JavaScript
49
star
8

argh

argh is a extremely light weight option/argument/process.argv parser for Node.js. It only parses options, nothing more than that.
JavaScript
46
star
9

FlashPolicyFileServer

A simple Flash Policy File Server for node
JavaScript
39
star
10

diagnostics

Tools for debugging your node.js modules
JavaScript
34
star
11

load

Load JavaScript files that do not use the bloat module patterns
JavaScript
24
star
12

cluster.exception

Exception handler for cluster
JavaScript
23
star
13

kuler

Color your terminal using CSS/hex color codes
JavaScript
21
star
14

realtimeplatform.github.com

TBA
21
star
15

licenses

Retrieve accurate license information for a given npm package.
JavaScript
21
star
16

fs.notify

File change notification that doesn't suck hairy monkey balls and just works.
JavaScript
19
star
17

canihaz

canihaz, lazy installing node.js modules
JavaScript
19
star
18

expirable

Expirable cache for node.js, FUCKING AWESOME YO!
JavaScript
18
star
19

mana

Mana allows api-oriented clients greater stability and high availability in demanding distributed battles and boss fights.
JavaScript
16
star
20

fingerprinting

Produce a unique string for any given resource, commonly used in cache busting practices.
JavaScript
11
star
21

nodejsconfit-2011

Demo's from nodejsconf 2011
JavaScript
11
star
22

find-package-json

Find package.json files in parent directories using an iterator based API. Keep searching till you find the one you're looking for or when you run out of folders to search in.
JavaScript
11
star
23

one-time

Run the supplied function exactly one time (once).
JavaScript
9
star
24

.files

The . files, vim & build commands etc
Vim Script
9
star
25

renderme

Render README files that people use on Github
JavaScript
9
star
26

shrinkwrap

npm shrinkwrap parsing, generation and comparison
JavaScript
9
star
27

text-hex

Create a hash from a string of text and transforms it to a color
JavaScript
8
star
28

env-variable

Cross platform environment variables with process.env, window.name, location.hash and localStorage fallbacks
JavaScript
7
star
29

commenting

Wrap content in a comment that is valid for a given file type.
JavaScript
7
star
30

node-bisection

Bisection algorithm for node.js
JavaScript
7
star
31

fn.name

Extract the name from a function.
JavaScript
7
star
32

senpai

Notice me senpai! A graceful degrading notification system for browsers.
JavaScript
7
star
33

memcached-stream

High performance streaming memcached protocol parser for Node.js. Code name: flaming-octo-bear
JavaScript
6
star
34

node-algorithms

A series of algorithms ported to JavaScript to be used on Node.js
JavaScript
5
star
35

koekje

A sessionStorage interface for cookies
JavaScript
5
star
36

uni

uni[versal] command line
JavaScript
5
star
37

ansidown

Convert a subset of markdown do a somewhat ANSI compatible output
JavaScript
5
star
38

failover

cluster-fuck management
JavaScript
4
star
39

Spry-Configurator

Spry files configurator and combinator. Version 2.0 is currently running on config-spry-it.com
JavaScript
4
star
40

gjallarhorn

Child process management without blasting your server in to pieces.
JavaScript
3
star
41

setup-env

Automated, feature detected, environment setup for your test suite
JavaScript
3
star
42

jQuery-scrollector

Navigate to elements using hashtag based CSS3 selectors,
JavaScript
3
star
43

odoyle

Micro Rules Engine powered by a simple JSON structure
JavaScript
3
star
44

woohoo

WooHoo is Celebration as a Service.
JavaScript
3
star
45

require-poisoning

Cache-Poisoning applied to Node.js require statements so you inject your own modules
JavaScript
3
star
46

assign

Map/Reduce promise like returned API -- Really not way to properly describe this module..
JavaScript
3
star
47

YUNO-UPDATE

Y U NO update your browser
JavaScript
3
star
48

enabled

Check if a certain flag is enabled.
JavaScript
3
star
49

colorspace

Generate HEX colors for a given namespace.
JavaScript
3
star
50

connected

Simple wrapper to ensure that your `server.listen` calls receive an err like all regular callback signatures.
JavaScript
3
star
51

queueback

Callback queue system for optimizing your HTTP requests
JavaScript
3
star
52

rip-out

Rip out properties from an object that you don't want to have included in the cloned result.
JavaScript
2
star
53

setHeader

Protect headers from being overridden before they are written to response.
JavaScript
2
star
54

Outside

Go Outside to chat
JavaScript
2
star
55

package-link

npm link that doesn't suck
JavaScript
2
star
56

shrubbery

Shrubbery is small Map() backed plugin registry
JavaScript
2
star
57

treason

Cheating on React's JSX by using JSON
JavaScript
2
star
58

booting

Async Initialization Process
JavaScript
2
star
59

darknode

HTTP/Docker interface for Darkweb/yolo
JavaScript
2
star
60

node-browserscope

Browerscope.org results based on user agent queries
JavaScript
2
star
61

storage-engine

EventEmitter abstraction on top the React-Native AsyncStorage API
JavaScript
2
star
62

connection-parse

Simple TCP connection string parser
JavaScript
2
star
63

enu

Extract enumerable and non-enumerable properties from an object.
JavaScript
2
star
64

mono-repos

Highly opinionated set of utilities to orchestrate and administrate mono repositories.
JavaScript
2
star
65

dollars

The "write less, do more, save dollars" library
JavaScript
2
star
66

timbers

Shiver me timbers! A tool to map short CLI argument to long CLI arguments
JavaScript
1
star
67

debug.css

debug.css
1
star
68

argh-matey

Argh Matey allows you to easily find the right cli command using language processing.
JavaScript
1
star
69

truth

Data is the only source of truth.
JavaScript
1
star
70

window.name

A module which exposes sessionStorage API for storing data in the window.name
JavaScript
1
star
71

parser

Redis based IRC protocol parser based on lua scripting
Lua
1
star
72

platform-specific

Platform specific information for isomorphic applications
JavaScript
1
star
73

nock-knock

Advanced router handling for nock
JavaScript
1
star
74

sparklet

Sparklet is a sparkline pagelet for BigPipe
JavaScript
1
star
75

send-help

Generate developer friendly output of a help command based on a given object structure.
JavaScript
1
star
76

dotfig

Configuration extraction from dot files or package.json fields
JavaScript
1
star
77

Spry-UI-ProgressBar

Progress bar widget for the Spry Framework
JavaScript
1
star
78

orbited

JavaScript
1
star
79

all-the-things

Random development of all the things, which should not be published yet, but does need to be tested
JavaScript
1
star
80

zoidberg

Flow control? Why not zoidberg
JavaScript
1
star
81

Spry-YQL-DataSet

YQL for Spry Data Sets
JavaScript
1
star