Comparing Device Description Repositories

Update: OpenDDR and dependencies have been updated on 2014-01-20.

Web content delivered to mobile devices can benefit from being tailored to take into account a range of factors such as screen size, markup language support and image format support. Such information is stored in “Device Description Repositories” (DDRs).

Until recently WURFL was the de facto DDR standard for mobile capabilities, but its license changed to AGPL (Affero GPL) v3, meaning it is not free to be used commercially anymore. Consequently some free open source alternatives to WURFL have recently started to show up and are improving quickly.

OpenDDR and are candidate substitutes to WURFL that also provide an API to access DDRs.

These tools ease and promote the development of Web content that adapts to its delivery context. This post summarizes the installation and configuration of these tools and analyzes how they compare in terms of image adaptation.

The source code used for this post is also available on GitHub.

Build configuration

This section describes how to add the dependencies to a Maven project.


WURFL is really straightforward since it is available on Maven central repository. All you have to do is to include the dependency on your project:

    <version>1.2.2</version><!-- the latest free version -->
</dependency> configuration is very similar to WURFL. Just add the dependency to your project’s pom.xml file:



OpenDDR is a bit harder to configure. Follow these steps to include OpenDDR in your project:

  1. Download OpenDDR-Simple-API zip package and unzip it.
  2. From the resulting folder, install bin/OpenDDR-Simple-API- and lib/DDR-Simple-API.jar into your local Maven repository:

    mvn install:install-file -DgroupId=org.w3c.ddr.simple -DartifactId=DDR-Simple-API -Dversion=2008-03-30 -Dpackaging=jar -Dfile=DDR-Simple-API.jar -DgeneratePom=true -DcreateChecksum=true
    mvn install:install-file -DgroupId=org.openddr.simpleapi.oddr -DartifactId=OpenDDR-Simple-API -Dversion= -Dpackaging=jar -Dfile=OpenDDR-Simple-API- -DgeneratePom=true -DcreateChecksum=true
  3. Add the dependencies to your project pom.xml file:


Loading repository/capabilities file

This section describes how to load repository files and import them into your project.


Copy wurfl-2.1.1.xml.gz file (the latest free version) into your project src/main/resources folder and import it using:

WURFLHolder wurflHolder = new CustomWURFLHolder(getClass().getResource("/wurfl-2.1.1.xml.gz").toString()); does not use a separate repository file.


Copy from the OpenDDR-Simple-API src folder and all files inside OpenDDR-Simple-API resources folder into your project src/main/resources folder. Import them using:

Service identificationService = null;
try {
    Properties initializationProperties = new Properties();
    identificationService = ServiceFactory
} catch (IOException e) {
    LOGGER.error(e.getMessage(), e);
} catch (InitializationException e) {
    LOGGER.error(e.getMessage(), e);
} catch (NameException e) {
    LOGGER.error(e.getMessage(), e);

Using the API

This section describes how use WURFL and OpenDDR Java APIs to access the device capabilities.


WURFL API is very easy to use and has the greatest advantage of providing a powerful fallback hierarchy, inferring capabilities for devices not yet in its repository file.

Device device = wurflHolder.getWURFLManager().getDeviceForRequest(getContext().getRequest());
int resolutionWidth = Integer.valueOf(device.getCapability("resolution_width"));
int resolutionHeight = Integer.valueOf(device.getCapability("resolution_height"));

There’s no need to validate device.getCapability("resolution_width") against null value when no data is available.

Similarly to OpenDDR, does not provide a fallback hierarchy. The developer must always validate each property value.

// Create a Provider object
Provider provider = Reader.create();

// Read in a User Agent String
BaseDeviceInfo deviceInfo = provider.getDeviceInfo(request.getHeader("User-Agent"));

// Get the value of a property
Integer screenPixelsWidth = 320; // Default value
Integer screenPixelsHeight = 480; // Default value
try {
    screenPixelsWidth = Integer.valueOf(deviceInfo.getFirstPropertyValue("ScreenPixelsWidth"));
} catch (NumberFormatException e) {
try {
    screenPixelsHeight = Integer.valueOf(deviceInfo.getFirstPropertyValue("ScreenPixelsHeight"));
} catch (NumberFormatException e) {


OpenDDR API is very cumbersome. It does not have a fallback hierarchy, instead it assumes 800px as the default value for displayWidth and 600px as the default value for displayHeight.

PropertyRef displayWidthRef;
PropertyRef displayHeightRef;

try {
    displayWidthRef = identificationService.newPropertyRef("displayWidth");
    displayHeightRef = identificationService.newPropertyRef("displayHeight");
} catch (NameException e) {
    throw new RuntimeException(e);

PropertyRef[] propertyRefs = new PropertyRef[] { displayWidthRef, displayHeightRef };
Evidence evidence = new ODDRHTTPEvidence();
evidence.put("User-Agent", getContext().getRequest().getHeader("User-Agent"));

int displayWidth = 320; // Default value
int displayHeight = 480; // Default value
try {
    PropertyValues propertyValues = identificationService.getPropertyValues(evidence, propertyRefs);
    PropertyValue displayWidthProperty = propertyValues.getValue(displayWidthRef);
    PropertyValue displayHeightProperty = propertyValues.getValue(displayHeightRef);

    if (displayWidthProperty.exists()) { // Don't really need to validate. Returns 800 as the default value.
        displayWidth= displayWidthProperty.getInteger();
    if (displayHeightProperty .exists()) { // Don't really need to validate. Returns 600 as the default value.
        displayHeight = displayHeightProperty.getInteger();
} catch (NameException e) {
    throw new RuntimeException(e);
} catch (ValueException e) {
    throw new RuntimeException(e);


The following table shows the results of the tests run against an application for server-side image adaptation. The tests were performed on real physical devices.

Feel free to run the tests for yourself using the source code available on GitHub.

Platform Device Property WURFL max_image_width (1) / max_image_height WURFL resolution_width / resolution_height ScreenPixelsWidth / ScreenPixelsHeight OpenDDR displayWidth / displayHeight
Windows Firefox desktop width 600 640 Unknown 800
height 600 480 Unknown 600
iOS iPhone 4S width 320 320 320 320
height 480 480 480 480
Android Samsung Galaxy S II width 240 240 480 480
height 320 320 800 800
HTC One V width 600 640 480 480
height 600 480 800 800
HTC Hero width 300 320 320 320
height 460 480 480 480
Windows Phone 7.5 Nokia Lumia 710 width 600 640 480 480
height 600 480 800 800
BlackBerry BlackBerry Bold 9900 width 228 480 640 640
height 280 640 480 480
Symbian S60 Nokia E52 (Webkit) width 234 240 240 240
height 280 320 320 320
Nokia E52 (Opera Mobile) width 240 240 Unknown 800
height 280 320 Unknown 600
Bada 2.0 Samsung Wave 3 width 600 640 480 480
height 600 480 800 800
Windows Mobile 6.1 HTC Touch HD T8282 width 440 480 480 480
height 700 800 800 800

(1) max_image_width capability is very handy:

Width of the images viewable (usable) width expressed in pixels. This capability refers to the image when used in “mobile mode”, i.e. when the page is served as XHTML MP, or it uses meta-tags such as “viewport”, “handheldfriendly”, “mobileoptimised” to disable “web rendering” and force a mobile user-experience.

Note: The color #9f9 highlights the results that performed better and #f99 highlights the results that performed worse.

Pros and Cons

  Pros Cons
  • Upgradable to newer versions by only replacing its database file.
  • A Device Hierarchy that yields a high-chance that the value of capabilities is inferred correctly even when the device is not yet recognized.
  • Lots and lots of capabilities.
  • Very easy to configure.
  • Clean API.
  • Has a Lite version licensed under the Mozilla Public Licence, free to use, even commercially.
  • Easier to install and configure than OpenDDR.
  • Decent list of capabilities.
  • Even though the list of capabilities is better than OpenDDR’s it still cannot compete with WURFL’s.
  • Free to use, even commercially.
  • Growing community.
  • Limited capabilities. OpenDDR seems to be limited to W3C DDR Core Vocabulary.
  • Returns 800 for displayWidth and 600 for displayHeight when the User-Agent does not exist in its database. It should let the developer choose which values result better for each particular application.

Let me stress how advantageous is to be able to upgrade WURFL by just replacing its XML database file. For the changes to take effect, there is no need to restart the application server or change the application source code. WURFL is also the only one supporting Opera Mobile browser.

Ending note

Keep in mind that while OpenDDR and test results may improve over time as I update the tests to use newer versions of them, WURFL will not be updated due to its new restrictive license. However, if a DDR solution is crucial to your business, you should really consider new versions of WURFL. It has improved a lot since the version used in this post making it is probably the best DDR money can buy.

Published by

Samuel Santos

Java developer, Open Source hacker, Web technologist, JUG Leader.

  • James Rosewell

    Thank you for including in your comparison. The following may assist the reader understand a little more about the approach.

    Properties are maintained by a team of professionals who work to consistent quality standards. ScreenPixelsWidth and Height represent the size of screen in pixels if known. We have 50 properties in the free Lite data, and over 100 properties in the Premium data. We deliberately decided not to include some capabilities. For example; i-mode support and WML support. We do receive requests for new properties, a recent example being the inclusion of Ringmark browser properties to provide a server side alternative to Modernizr. What properties/capabilities would readers like to see included?

    The Java API can optionally be passed a data file when the provider is constructed.

    Provider p = Reader.create(“PATH_TO_DATA_FILE”);

    New data files are published monthly on Codeplex, or weekly if a Premium data file is purchased. If a data file is not provided the embedded one is used.

  • Luca Passani

    Hi, Luca Passani, creator of WURFL and ScientiaMobile CTO, here.

    Thank you for reporting about WURFL in your article.
    WURFL was created in 2001 and has laid the way for virtually all other DDRs that have copied it conceptually or in more consistent (and arguably not always legitimate) ways (I don’t want to digress…).

    WURFL moved to the AGPL license last year to make the economic model behind it sustainable and bring more better Device Detection to developers, while, at the same time, making sure that small shops and hobbysts could still benefit from the product (among other things, we have a free of charge WURFL Cloud offering).

    Apart from the grumbling of some open-source zealots, everyone agrees that this was a positive move for the product and for the support that ScientiaMobile is now able to offer WURFL adopters at a reasonable cost.

    A clear example of the advantage of the new WURFL is ScientiaMobile’s ability to deliver new products in the DDR space. This week, we launched WURFL Modules for Varnish-Cache, NGINX and Apache.
    These will enable developers to do things like:

    // PHP
    if ($_SERVER[‘HTTP_X_WURFL_IS_TABLET’] == ‘true’) {
    //Do whatever makes sense for a tablet

    without the need to install the WURFL libraries as part of the application itself,
    More info (and more use-cases) can be found here:

    Thank you

    Luca Passani
    CTO @ScientiaMobile

  • Werner Keil


    Thank you for the technically motivated and vendor-neutral view on 3 popular Device Description Repositories including OpenDDR. And for providing the test Open Source on GitHub, where OpenDDR is also maintained.

    I can confirm, compatibility with W3C DDR has been a driving factor behind OpenDDR so far, which explains some of the results or differences you mention. OpenDDR can be both configured and where necessary extended/patched very easily. You mention the, but without having looked at your example code, the threshold value in the properties file can or needs to be adjusted allowing to tweak precision of findings over other factors like memory consumption. Tests against the latest available and free WURFL showed, that while it produces results similar to what you observed, its memory consumption in a similar setup are up to 500MB where a full scale OpenDDR (full W3C DDR vocabulary) required no more than 100MB, with a limited vocabulary even as low as 50MB. Did you do any tests in that direction?
    I haven’t personally looked at the footprint of but given it uses a different approach and does not claim to be W3C DDR compatible either, it may have a memory footprint as good or below OpenDDR.

    Especially if you host your solutions in the Cloud, not just storage but other behavior of your application is measured and may be charged for, too. Not just the different pricing of the actual DDR solutions you outlined rather accurately.

    Let me add, that OpenDDR has been contributed to Apache DeviceMap as of last week and there may be different strategies for e.g. the mentioned fallback if enough members of the Apache community demand that or contribute to. Please keep an eye on the DeviceMap project. Like some of its siblings, especially client-side Device Recognition and cross-scripting Cordova (contributed by Phonegap) or OpenOffice, incubation may take time, so do license-adjustments (to Apache License, don’t worry, it’ll rather get more open in our case;-) but expect to get your hands on it no later than early next year. DeviceMap will be fully backward-compatible with OpenDDR, both API and resource files, while over time, it may add features or capabilities the community wishes to see.

    Thanks and Regards,
    Werner Keil | Principal Community Evangelist | OpenDDR

  • Luca Passani

    I need to get back on this to state that the numbers reported by Werner Keil about the performance of the WURFL API are incorrect.
    The WURFL API can be configured to use only a subset of the capabilities and to use different caching mechanisms (through Spring Framework configuration).
    Most WURFL Java installations have a memory usage <50Mb.
    Of course, as Albert Einstein used to say, make things simple, as simple as possible, but not simpler. Today's mobile devices go out of their way to camouflage and WURFL adds just enough complexity to stay on top of the problem.
    Of course, in addition to Java, WURFL has APIs for all platforms (even Perl, Ruby, Python and Node.js, if the WURFL Cloud is accounted for). This addresses the needs of all companies, from small shops to large organizations that need scalability and reliability.
    The W3C recommendation quoted by Keil has been totally ignored by the industry for many years. OpenDDR reverted to it in the attempt to copy from WURFL while trying to avoid the liability that comes from it.

    Luca Passani
    CTO @ScientiaMobile

  • Samuel Santos

    Thank you all for your feedback and clarification.

    @James: For new features we would like to see in next versions, I would like very much to have support for Opera Mobile.

  • Idel

    Another solution could be my open source project called Apache Mobile

    Over 16000 in 5 years and completely free

    • Werner Keil

      Sorry but Apache Mobile Filter seems only a wrapper around other solutions, so while it may be free as such, there are costly products backing it like WURFL. On the other hand, given the WURFL Java API has been dead since 2011 (according to MavenCentral) it may be a welcome client, but won’t save users the financial burden of WURFL or other subscriptions. For the definitive Open Source alternative, check out Apache DeviceMap. It comes in a traditional W3C DDR flavor, and a new client also backing a REST/JSON API.

      • Idel

        I don’t think you have seen the litedetection and AMF+ the C++ modules for Apache this module recognize if the device is mobile, tablet or with touch screen. I think this cover the 90% of necessary for mobile service.

        Just an update more 20.000 of downloads

  • Rusty

    iPhone 4S screen resolution is not 320×640 but 960×640. Not sure why all the tested solutions detected its resolution incorrectly?

    • Samuel Santos

      The detected resolution for iPhone 4 is 320×480.
      The reason is that the iPhone 4 is indistinguishable from the 3G since the user agent is exactly the same. The reported version is the iOS version, not the hardware version.

  • Alexandra Join

    Hi, can anyone tell me what DDR solution Google use?

    • Werner Keil

      They probably write their own 😉