Putting the Web back in the Web of Things

We spent over a decade standardising the Web of Things, but I believe it’s still missing a key component it needs in order to grow.

The Web of Things started with the simple but powerful idea of giving connected devices URLs on the web, to extend the World Wide Web of pages into a web of physical objects which can be monitored and controlled over the internet. The idea was to apply lessons learnt from the World Wide Web to the Internet of Things to create a unifying application layer that is to the Internet of Things what the World Wide Web is to the internet.

Over the last decade the W3C Web of Things Working Group has made great progress in standardising key building blocks for discovering and describing connected devices. However, when it comes to actually communicating with those devices we seem to have got stuck with just describing the fragmented landscape of IoT protocols that already existed, rather than defining something native to the web which truly has the potential to scale in the way the World Wide Web has.

In this blog post I will take a deep dive into the last 10+ years of Web of Things standardisation (from my own personal perspective), how we got where we are today, and why I believe the Web of Things is still missing an essential component due to a subtle misunderstanding about what makes the web the web.

Crucially, I explain how I think we can put the “web” back in the “Web of Things” with a universal web-based application layer protocol, to enable an open ecosystem of IoT web services which weave together the rich tapestry of the Internet of Things, rather than simply cementing the fragmentation that currently exists.

Table of Contents

  1. Beginnings
  2. WoT Community Group & Early Ideas
  3. Mozilla WebThings
  4. Standardising the Web of Things
    1. WoT Working Group
    2. The Web Thing Model and Mozilla’s Web Thing API
    3. Descriptive vs. Prescriptive: Two Schools of Thought
    4. Web Thing Protocol Community Group
    5. WoT Thing Description
    6. WoT Discovery & WoT Profile
    7. Binding Templates vs. Profiles: Two Sides Remain
    8. Bringing the Sides Together
    9. Changing of the Guard
  5. How is the Web of Things being used today?
    1. Matter & WoT at Deutsche Telekom
    2. OPC UA & WoT at the OPC Foundation
    3. BACnet & WoT at Siemens
    4. MQTT & WoT at Microsoft
    5. What’s Not Working
  6. What is the narrow waist of the Web of Things?
  7. The Web Thing Protocol
  8. What’s Next?
  9. Call to Action

Beginnings

I first learnt about the “Web of Things” from a book by Dominique Guinard and Vlad Trifa called Building the Web of Things, published in 2016.

The front cover of the book Building the Web of Things.
Building the Web of Things, by Dominique Guinard and Vlad Trifa, 2016

The book was based on the culmination of their learning from the Web of Things community they started in 2007 including an annual series of international workshops from 2010, with some early thinking the pair captured in a paper published in 2009, and Dominique’s PhD thesis in 2011. Dominique and Vlad went on to co-found EVRYTHNG Ltd., who developed what they described as the first commercial Web of Things platform.

I was inspired by the simple but powerful idea of giving connected devices URLs on the web to make them linkable and discoverable, and defining a standard data model and API to make them interoperable. The Web of Things would apply lessons learnt from the World Wide Web to the Internet of Things, in order to create a unifying application layer for the Internet of Things, linking together multiple underlying IoT protocols using existing web technologies.

“For the Internet of Things to become real, we need a single universal application layer protocol (think language) for devices and applications to talk to each other, regardless of how they’re physically connected. Rather than inventing yet another protocol from scratch (as many IoT projects have been – and keep – doing), why not reuse something that’s already widely used to build scalable and interactive applications, such as the web itself? This is what the Web of Things (and this book) is all about: using and reusing readily available and widely popular web protocols, standards, and blueprints to make data and services offered by Things more accessible to a larger pool of (web) developers.”

— Guinard & Trifa, Building the Web of Things, 2016

The book talks about three “integration patterns” for connecting IoT devices to the Web of Things:

  • Direct – A Thing hosts an HTTP (REST and WebSocket) API directly
  • Gateway – An on-premises application gateway translates non-Web and non-Internet protocols (e.g. MQTT and Zigbee respectively) to an HTTP API
  • Cloud – A cloud service which acts as a gateway on a remote server to translate non-Web IoT protocols (e.g. MQTT) to an HTTP API

In all cases devices are ultimately exposed via HTTP REST and WebSocket APIs. Examples are given using the CoAP and MQTT protocols, but only in the context of the gateway and cloud integration patterns where a gateway and cloud service respectively are used to bridge these protocols to the web.

The book even goes as far as to say that if you can’t send an HTTP request to a device, then it’s not part of the Web of Things*:

Web Things must be an HTTP server. Simply put, if you can’t send an HTTP request to a device, then it’s not part of the Web of Things.

— Guinard & Trifa, Building the Web of Things, 2016

That doesn’t necessarily mean that every physical device has to talk HTTP directly, but that one way or another it must be possible to communicate with the web thing that represents it over the web. This was important because in order for the Web of Things to achieve the kind of scale that the World Wide Web has enjoyed, everyone needs to be talking the same language.

Just like the web has become the global integration platform for distributed applications over the internet, the Web of Things facilitates the integration of all sorts of devices and the applications that interact with them. In other words, by hiding the complexity and differences between various transport protocols used in the IoT, the Web of Things allows developers to focus on the logic of their applications without having to bother about how this or that protocol or device actually works.

–Guinard & Trifa, Building the Web of Things, 2016

* I’m not sure I would go quite as far as to restrict this to only HTTP, because I think we need to allow some room for innovation in web protocols. For example, CoAP is a very web-like protocol (kind of a mini HTTP) which can operate in very constrained environments where HTTP can’t, and adds the ability to observe resources. The important point is that the intention was for all web things to be communicated with via the web, not just described by the web, (i.e. a Web of Things, not a Web about Things).

WoT Community Group & Early Ideas

By the time Building the Web of Things was published, there was already a W3C Working Group doing early work to standardise the Web of Things. It had started with the creation of the WoT Community Group by Dave Raggett back in 2013, which led to the first W3C WoT Workshop in Berlin in 2014 where over 100 participants shared their early ideas.

The position papers submitted for the first W3C WoT Workshop in Berlin in 2014 make for very interesting reading. The paper that Dave Raggett himself put forward starts very clearly by saying:

This paper presents an architecture for a scalable services platform for the Web of Things with APIs for services layered on top of HTTP and Representational State Transfer (REST).

Raggett, An architecture for the Web of Things, 2004

I would also highlight (because it becomes important later on), that at the time of this workshop that also very much seemed to be the consensus of the workshop hosts, Siemens:

Web Architecture provides a general-purpose way of establishing an interlinked network of resources, which are interacted with through the exchange of representations of their state. We argue that the “Web of Things” fits well into this general framework, and thus should be built firmly on the foundation provided by Web Architecture…

For the “Web of Things” to become a global reality, there needs to be an open, modular, extensible, and flexible set of technologies that are in line with the Architecture of the World Wide Web, and can be used as a platform to build on. As a result, this platform should be a RESTful SOA

–Wilde, Michahelles and L¨uder, Leveraging the Web Platform for the Web of Things: Position Paper for W3C Workshop on the Web of Things, 2014

Siemens actually suggested Activity Streams as one potential way that “streams of resource updates could be represented in a uniform, extensible, and machine-readable way”, and talked about “prescribed design patterns” or maybe “additional specifications to help increase interoperability”. They also said that “what matters is identification and interaction, but only via a representation (a.k.a. REST)”.

I recently used a Large Language Model to help analyse all 68 position papers from that workshop (one of the things that LLMs are actually very useful for, shout out to the Dia web browser which is very useful for this kind of thing). This revealed that based on those submissions the overwhelming consensus is that “things” are web resources with URIs, manipulated through a REST interface over HTTP/CoAP, described with common web data formats. They treat the web (HTTP/REST/URIs/Linked data) as the native application layer for the Web of Things, often extended with CoAP for constrained devices. They see existing IoT protocols (MQTT, Modbus, BACnet, OPC-UA, Zigbee etc.) as technologies to be wrapped, bridged or mapped into this web model, not as the primary “surface” of the Web of Things.

There is definitely a strong desire for a shared information model from semantic web/linked data folks, with common ontologies and a way to describe things and their capabilities. But this semantic layer is much more diverse (multiple ontologies, domain-specific models), often very domain-driven, and explicitly something that will evolve and be extended, not frozen as a tiny stable core.

Some of the browser folks also talk about a unified programming model (e.g. a uniform JavaScript API for both HTTP and CoAP requests). However, these APIs are seen as sitting on top of the REST/URI interface, not instead of it.

Ultimately what these papers really describe as the “narrow waist” of the Web of Things is:

  • Resources with URIs
  • RESTful methods (GET/PUT/POST/DELETE plus Observe/notify)
  • HTTP or CoAP as the protocol surface
  • A small set of web media types (JSON/CBOR, RDF/JSON-LD/Turtle)

… with information models and scripting APIs layered on top of that.

The reason I say all of this is to eventually contrast the clear early consensus about what the Web of Things should be, with what the current set of W3C WoT standards actually defines.

Shortly after the workshop in Berlin the WoT Interest Group was created at TPAC 2014 to start identifying use cases and requirements.

Mozilla WebThings

The book Building the Web of Things was what inspired me to start “Project Things” in the Emerging Technologies department at Mozilla, which was started in early 2017, announced in June 2017, became the Mozilla WebThings IoT platform in 2019, and would later be spun out as the independent WebThings open source project in 2020.

At Mozilla we observed that the Internet of Things at the time was mostly built on proprietary vertical technology stacks, each dependent on a central point of control, which didn’t always talk to each other, and when they did it required per-vendor integrations. Driven by Mozilla’s mission to “to ensure the Internet is a global public resource, open and accessible to all”, we saw the Web of Things as a potential solution to this problem.

Having read Building the Web of Things I eagerly shared the vision of the Web of Things with leaders at Mozilla as being a very Mozilla-like approach to the Internet of Things. I pitched the idea of “Mozilla WebThings” as an IoT platform developed by Mozilla, taking the form of an open source implementation of the Web of Things, providing a unifying horizontal application layer for the Internet of Things.

Inspired by the three integration patterns from the book, the three main components would be a gateway, a cloud service and framework for developing native web things. A few months later, Mozilla announced what was initially called “Project Things” (to emphasise its experimental status).

Standardising the Web of Things

WoT Working Group

By December 2016 the WoT Working Group had already started work on writing the first normative specifications – WoT Thing Description and WoT Architecture.

The Mozilla IoT team were clear that we didn’t want Project Things to create another proprietary vertical technology stack, we wanted to participate in the existing Web of Things community and make the Web of Things the platform. Mozilla WebThings was intended to be one open source implementation of a Web of Things standard, in the same way that Firefox is one implementation a web user agent and Apache is one implementation of a web server.

I had therefore been keeping a close eye on the W3C’s standardisation work and had managed to convince Mozilla’s W3C representatives (they did require some convincing) that Mozilla should join the WoT Interest Group. However, Mozilla initially declined to join the WoT Working Group because they disagreed about some parts of the first charter. They had made formal objections which were not addressed, so they decided not to join. Mozilla’s reservations (some coming from the Mozilla’s platform team and some coming from the Mozilla IoT team) were:

  • They thought several of the proposed deliverables lacked sufficient incubation to be placed on the W3C Recommendation track.
  • They thought the charter had an overly broad scope and should first focus on defining a core Thing Description format rather than pursuing a wide range of other deliverables.
  • They were concerned about the dependency on semantic web technologies like RDF and JSON-LD and felt the default representation format for Thing Descriptions should be plain JSON (RDF was very unpopular at Mozilla at the time because of a bad experience of trying to use RDF in XUL as part of the architecture of Firefox).
  • They thought that defining declarative “protocol bindings” using “binding templates” and “hypermedia forms” was unnecessarily complicated, and favoured a prescriptive HTTP API and simple hyperlinks instead.
  • They thought the architecture document should be an informative note rather than another normative specification.
  • They didn’t support the Scripting API specification (which didn’t have the support of any other browser vendors either).
  • They expressed concerns over privacy and security.

The Web Thing Model and Mozilla’s Web Thing API

The book Building the Web of Things had introduced a proposal called the “Web Thing Model” (a formal W3C member submission) which defines an HTTP REST & WebSocket API for retrieving metadata about a Thing, and communicating with it. This included a root JSON resource which was an early version of a Thing Description containing top level metadata about the Thing, then a fixed URL structure for interaction with “properties” and “actions” using HTTP GET and POST. The Mozilla IoT team saw this as a simpler, more pragmatic approach.

Screenshot of the Web Thing Model member submission.
Web Thing Model Member Submission

So instead of jumping straight into implementing the W3C’s nascent work on Thing Descriptions, the Mozilla IoT team took the Web Thing Model as a starting point and designed our own Web Thing API which took what we considered to be a more pragmatic approach, with plain JSON Thing Descriptions and simple hyperlinks rather than JSON-LD and “hypermedia forms”. Our early single specification defined a plain JSON Web Thing Description format for describing Things, a prescriptive Web Thing REST API (with URLs provided in Thing Descriptions rather than using a fixed URL structure) which could be used for communicating with Things using HTTP, and a Web Thing WebSockets API for push notifications and real-time communication.

Screenshot of the Web Thing API Unofficial Draft from 13 May 2019.
Mozilla Web Thing API specification

Looking to build consensus around this approach I met Dominique and Vlad at the EVRYTHNG headquarters in London in October 2017 to work towards a joint member submission to the W3C, which combined their early work on the Web Thing Model with an early version of Mozilla’s Web Thing API specification.

We came up with a joint proposal from Mozilla, EVRYTHNG and Ambrosus Technologies for a plain JSON Web Thing Description format which could be parsed as plain JSON, with optional semantic annotations using JSON-LD. We also still favoured “links” over “forms”.

We shared this proposal as members of the Interest Group (though weren’t allowed to call it a member submission), and the ensuing discussion in the Working Group eventually resulted in some simplifications to the nascent Thing Description specification.

The Working Group agreed that the default representation format should be plain JSON (with optional JSON-LD style semantic annotations), but we lost the argument about “links” vs. “forms”.

Descriptive vs. Prescriptive: Two Schools of Thought

Overall we felt that the Thing Description specification was now going in a better direction, which would enable us to standardise the Web Thing Description part of Mozilla’s Web Thing API specification, but the REST & WebSockets APIs were still specific to Mozilla WebThings.

In the 1.0 family of specifications the Working Group had decided to define something which was entirely programming language agnostic, protocol agnostic, and content type agnostic in order to be as extensible and flexible as possible. They had decided (contrary to the early consensus about a largely HTTP-based REST style architecture) that Thing Descriptions should be able to describe any existing IoT protocol through an extensible system of declarative “protocol bindings”, serialised as “hypermedia forms”.

“Binding templates” would define a semantic vocabulary for binding a fixed set of WoT operations like “readproperty”, “invokeaction” and “subscribeevent” to concrete messages in a given protocol. So for example, the HTTP vocabulary would enable a Thing Description author to say that if a Consumer wants to read a property they should send an HTTP GET request to a certain URL with certain HTTP headers set, and should expect a certain response code in response.

Rather than a prescribing a concrete REST & WebSockets API like those proposed in the Web Thing Model and Mozilla’s Web Thing API, this declarative approach would theoretically be able to describe any REST API, even existing proprietary ones. If it had stopped there, I think that would almost have been OK. But the concept of protocol bindings was also then extended to describing any protocol and data format, even non-web ones which were not inherently resource oriented (e.g. MQTT, Modbus, BACnet and OPC-UA). The only requirement (which we had to fight for) was that the protocol would have to have a URI scheme and the data format would have to have a MIME type in order to be described in forms.

Rather than providing a universal web-based application layer protocol for the Internet of Things, the Web of Things would therefore provide metadata that described how to communicate using existing IoT protocols. Many members of the Working Group were worried that if we tried to define anything that looked like a new protocol, the Web of Things would be seen as just another IoT protocol that added to the problem, rather than a solution to the fragmentation. The infamous XKCD 927 comic strip was often referenced when trying to justify this direction.

Whilst that comic strip is quite funny and makes a valid point about standards, I also think it was very unhelpful in this particular instance. Our argument was never that HTTP was the best IoT protocol (it definitely isn’t) and should replace all other IoT protocols (it definitely shouldn’t). It was that due its simplicity and ubiquity, an HTTP-based application layer protocol could help provide a universal web abstraction on top of other IoT protocols that an open ecosystem of apps and services could then consume.

The irony of the xkcd argument is that the exact same comic strip is printed in the book Building the Web of Things to justify defining a prescriptive universal application layer protocol built on HTTP, rather than re-inventing the wheel. I think the fact that the same image was used to argue opposite sides of the argument shows just how nonsensical it was.

Whilst very flexible, the downside of all the open ended extensibility of “binding templates” was that it was now effectively impossible to build a single WoT Consumer which was guaranteed to be able to communicate with any Web Thing, in the way that any web browser can render just about any web page. Whilst Thing Descriptions provided a common metadata format, Consumers ultimately still had to implement each individual IoT protocol in order to communicate with different devices.

The Mozilla IoT team still believed the Web of Things needed a more prescriptive universal application layer protocol, so I started to seek support for a separate community group to explore that direction further.

Web Thing Protocol Community Group

After defining a proposed scope and gathering enough initial supporters, in September 2019 I launched the Web Thing Protocol Community Group to “define a common protocol for communicating with connected devices over the web, to enable ad-hoc interoperability on the Web of Things.”

The deliverables defined in the group charter included:

  1. Definition of a WebSocket sub-protocol for the Web of Things, using the W3C “Web of Things (WoT) Thing Description” data model and operations
  2. Definition of an HTTP sub-protocol for the Web of Things
    (or support of the Web of Things Working Group in defining this sub-protocol and ensuring consistency with the WebSocket sub-protocol where appropriate)
  3. Evaluation of other potential Web of Things sub-protocols (e.g. for CoAP)

We hoped that the Working Group would eventually come around to defining a prescriptive HTTP protocol binding. There was general agreement that a WebSocket sub-protocol was needed, but the WoT Working Group felt it needed incubating somewhere before joining a standards track, so they were at least happy for the community group to be spun off to work on that.

The community group started work on a Use Cases & Requirements report which outlined requirements for both an HTTP and WebSocket sub-protocol.

Screenshot of the Web Thing Protocol Use Cases & Requirements Draft Community Group Report.
Web Thing Protocol Use Cases & Requirements Draft Report, 2020

WoT Thing Description

The first formal W3C WoT Recommendations were published in April 2020:

  • Web of Things (WoT) Architecture 1.0 – Described the building blocks of the Web of Things and how they fitted together (and did end up being a separate normative specification).
  • Web of Things (WoT) Thing Description 1.0 – Defined an information model and representation format for describing the metadata and interfaces of “things” (including a default JSON representation, but “forms” in addition to “links”)
Screenshot of the WoT Architecture W3C Recommendation from 9 April 2020.
W3C WoT Architecture 1.0 Recommendation, 2020
Screenshot of the WoT Thing Description W3C Recommendation from 9 April 2020.
W3C WoT Thing Description 1.0 Recommendation, 2020

This was a promising starting point, but Mozilla didn’t immediately implement the W3C WoT specifications in WebThings. Instead we continued to implement an evolved version of the Web Thing API which was a little closer to the W3C specifications (e.g. used a very similar information model with properties, actions and events, and allowed semantic annotations for describing capability schemas) but still used links rather than forms.

It was around this time that Mozilla also laid off the entire Emerging Technologies department that built the WebThings platform, and some ex-colleagues and I spun WebThings out of Mozilla as an independent open source project.

In December 2020 I set out a vision for the future of the now community-run WebThings platform under the new stewardship of my startup, Krellian. One of the items in that roadmap was compliance with the newly published W3C WoT standards, using the proposed Web Thing Protocol to fill the gaps I perceived existed in the W3C specifications.

WoT Discovery & WoT Profile

Meanwhile, after multiple extensions, a new charter for the WoT Working Group had been published in January 2020 which added new normative deliverables for the Working Group:

  • The Web of Things (WoT) Discovery specification would focus on how Thing Descriptions are discovered, including the definition of various discovery mechanisms and the Directory Service API.
  • The Web of Things (WoT) Profile specification would define “profiles for subsets of TDs to enable plug-and-play interoperability.”

(Still suffering from a lack of consensus the Scripting API also became an informative rather than normative deliverable, but it would still stick around as a Working Group Note).

I supported the work on both of the new normative deliverables.

The WoT Discovery specification included the definition of a prescriptive HTTP REST API called the Directory Service API for managing a directory of Thing Descriptions (which was similar to the “Things” resource in Mozilla’s Web Thing API specification), and standardised DNS-based discovery of Things using mDNS/DNS-SD (which was also something we had defined in Mozilla’s Web Thing API specification).

The WoT Profile specification was originally proposed by Oracle as a way of improving interoperability on the Web of Things. Profiles would ensure that any WoT Consumer conforming to a profile would be able to communicate with any Thing also conforming to that profile, by limiting complexity and constraining the extension points in Thing Descriptions to a finite set of options.

When I heard about Profiles I jumped on the idea because it sounded like a potential way to achieve the kind of universal application layer we had set out to define in the first place. By constraining Things to a finite set of prescriptive protocol bindings and payload formats, and constraining other extension points, we could offer a prescriptive approach to using the Web of Things which implementations could opt-in to using in order to benefit from more interoperability guarantees.

Unfortunately it didn’t go very well.

From the beginning there were disagreements over what Profiles should and shouldn’t define. On the one hand early drafts of profiles tried to constrain the sizes of strings and data structures in Thing Descriptions to optimise for constrained devices, but on the other hand made more of the members of a Thing Description mandatory in order to optimise for human readability, and even extended its ontology to describe concepts that couldn’t otherwise be described. There were disagreements over whether there should be profiles for specific application domains, or whether they should be domain agnostic, and whether specific ontologies should be required for describing units.

Profiles tried to prescribe fixed protocol bindings in order to enable out-of-the-box interoperability, but when it was found that the APIs for some operations were not possible to fully describe using declarative protocol bindings, they ended up defining APIs that Thing Descriptions alone would not be able to describe. There were disagreements over which eventing mechanisms to use in the protocol bindings, and whether to re-use existing de-facto standards for event payloads or invent new approaches that were tailored to the Web of Things information model.

By the time WoT Architecture 1.1, Thing Description 1.1 and WoT Discovery 1.0 were published as W3C Recommendations in December 2023, the WoT Profile specification was still stuck at the draft stage.

Screenshot of the WoT Discovery W3C Recommendation from 5 December 2023.
W3C WoT Discovery Recommendation, 2023

Binding Templates vs. Profiles: Two Sides Remain

Once the dust had settled, we arrived at a Working Draft of the WoT Profile specification in 2023 which defined a set of common constraints around accessibility, units, date format, security, discovery and links, and then three initial domain-agnostic profiles – the HTTP Basic Profile, HTTP SSE Profile and HTTP Webhook Profile.

Screenshot of the WoT Profile W3C Working Draft rom 18 January 2023.
W3C WoT Profile Working Draft, 2023

These profiles make it possible to drastically reduce the complexity of Thing Descriptions and Consumer implementations. For example, below is the Thing Description for a simple web thing representing a connected lamp when using the HTTP Basic and HTTP SSE profiles:

{
  "@context": "https://www.w3.org/2022/wot/td/v1.1",
  "id": "https://mywebthingserver.com/things/lamp",
  "profile": [
      "https://www.w3.org/2022/wot/profile/http-basic/v1",
      "https://www.w3.org/2022/wot/profile/http-sse/v1"
  ],
  "base": "https://mywebthingserver.com/things/lamp/",
  "title": "My Lamp",
  "description": "A web connected lamp",
  "securityDefinitions": {
    "oauth2": {
      "scheme": "oauth2",
      "flow": "code",
      "authorization": "https://mywebthingserver.com/oauth/authorize",
      "token": "https://mywebthingserver.com/oauth/token"
    }
  },
  "security": "oauth2",
  "properties": {
    "on": {
      "type": "boolean",
      "title": "On/Off",
      "description": "Whether the lamp is turned on",
      "forms": [
        {
          "href": "properties/on"
        },
        {
          "href": "properties/on",
          "op": ["observeproperty", "unobserveproperty"],
          "subprotocol": "sse"
        }
      ]
    },
    "level" : {
      "type": "integer",
      "title": "Brightness",
      "description": "The level of light from 0-100",
      "unit": "percent",
      "minimum" : 0,
      "maximum" : 100,
      "forms": [
        {
          "href": "properties/level"
        },
        {
          "href": "properties/level",
          "op": ["observeproperty", "unobserveproperty"],
          "subprotocol": "sse"
        }
      ]
    }
  },
  "actions": {
    "fade": {
      "title": "Fade",
      "description": "Fade the lamp to a given level",
      "synchronous": false,
      "input": {
        "type": "object",
        "properties": {
          "level": {
            "title": "Brightness",
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "unit": "percent"
          },
          "duration": {
            "title": "Duration",
            "type": "integer",
            "minimum": 0,
            "unit": "milliseconds"
          }
        }
      },
      "forms": [{"href": "actions/fade"}]
    }
  },
  "events": {
    "overheated": {
      "title": "Overheated",
      "data": {
        "type": "number",
        "unit": "degree celsius"
      },
      "description": "The lamp has exceeded its safe operating temperature",
      "forms": [{
        "href": "events/overheated",
        "subprotocol": "sse"
      }]
    }
  },
  "forms": [
    {
      "op": ["readallproperties", "writemultipleproperties"],
      "href": "properties"
    },
    {
      "op": ["observeallproperties", "unobserveallproperties"],
      "href": "properties",
      "subprotocol": "sse"
    },
    {
      "op": "queryallactions",
      "href": "actions"
    },
    {
      "op": ["subscribeallevents", "unsubscribeallevents"],
      "href": "events",
      "subprotocol": "sse"
    }
  ]
}

Below is my best attempt at describing this same Web Thing without Profiles:

{
  "@context": "https://www.w3.org/2022/wot/td/v1.1",
  "id": "https://mywebthingserver.com/things/lamp",
  "base": "https://mywebthingserver.com/things/lamp/",
  "title": "My Lamp",
  "description": "A web connected lamp",
  "securityDefinitions": {
    "oauth2": {
      "scheme": "oauth2",
      "flow": "code",
      "authorization": "https://mywebthingserver.com/oauth/authorize",
      "token": "https://mywebthingserver.com/oauth/token"
    }
  },
  "schemaDefinitions": {
    "error": {
      "type": "object",
      "properties": {
        "type": {
          "type": "string",
          "format": "uri"
        },
        "title": {
          "type": "string"
        },
        "status": {
          "type": "number"
        },
        "detail": {
          "type": "string"
        },
        "instance": {
          "type": "string",
          "format": "uri"
        }
      }
    },
    "actionStatuses": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "type": "array",
        "items": { 
          "type": "object",
          "properties": {
            "state": {
              "type": "string",
              "emum": ["pending", "running", "completed", "failed"]
            },
            "output": {},
            "error": {
              "$ref": "#/schemaDefinitions/error"
            },
            "href": {
              "type": "string",
              "format": "uri"
            },
            "timeRequested": {
              "type": "string",
              "format": "date-time"
            },
            "timeEnded": {
              "type": "string",
              "format": "date-time"
            }
          }
        }
      }
    }
  },
  "security": "oauth2",
  "properties": {
    "on": {
      "type": "boolean",
      "title": "On/Off",
      "description": "Whether the lamp is turned on",
      "forms": [
        {
          "href": "properties/on",
          "op": "readproperty",
          "response": {"htv:statusCodeNumber": 200},
          "additionalResponses": [
            {
              "success": false,
              "schema": "error"
            }
          ]
        },
        {
          "href": "properties/on",
          "op": "writeproperty",
          "response": {"htv:statusCodeNumber": 204},
          "additionalResponses": [
            {
              "success": false,
              "schema": "error"
            }
          ]
        },
        {
          "href": "properties/on",
          "op": "observeproperty",
          "htv:methodName": "GET",
          "subprotocol": "sse",
          "htv:headers": [
            {
              "@type": "htv:RequestHeader",
              "htv:fieldName": "Accept",
              "htv:fieldValue": "text/event-stream"
            },
            {
              "@type": "htv:RequestHeader",
              "htv:fieldName": "Connection",
              "htv:fieldValue": "keep-alive"
            }
          ],
          "response": {
            "htv:statusCodeNumber": 200,
            "htv:headers": [
              {
                "@type": "htv:ResponseHeader",
                "htv:fieldName": "Content-Type",
                "htv:fieldValue": "text/event-stream"
              }
            ]
          },
          "additionalResponses": [
            {
              "success": false,
              "schema": "error"
            }
          ]
        },
        {
          "href": "properties/on",
          "op": "unobserveproperty",
          "subprotocol": "sse"
        }
      ]
    },
    "level" : {
      "type": "integer",
      "title": "Brightness",
      "description": "The level of light from 0-100",
      "unit": "percent",
      "minimum" : 0,
      "maximum" : 100,
      "forms": [
        {
          "href": "properties/level",
          "op": "readproperty",
          "response": {"htv:statusCodeNumber": 200},
          "additionalResponses": [
            {
              "success": false,
              "schema": "error"
            }
          ]
        },
        {
          "href": "properties/level",
          "op": "writeproperty",
          "response": {"htv:statusCodeNumber": 204},
          "additionalResponses": [
            {
              "success": false,
              "schema": "error"
            }
          ]
        },
        {
          "href": "properties/level",
          "op": "observeproperty",
          "subprotocol": "sse",
          "htv:methodName": "GET",
          "htv:headers": [
            {
              "@type": "htv:RequestHeader",
              "htv:fieldName": "Accept",
              "htv:fieldValue": "text/event-stream"
            },
            {
              "@type": "htv:RequestHeader",
              "htv:fieldName": "Connection",
              "htv:fieldValue": "keep-alive"
            }
          ],
          "response": {
            "htv:statusCodeNumber": 200,
            "htv:headers": [
              {
                "@type": "htv:ResponseHeader",
                "htv:fieldName": "Content-Type",
                "htv:fieldValue": "text/event-stream"
              }
            ]
          },
          "additionalResponses": [
            {
              "success": false,
              "schema": "error"
            }
          ]
        },
        {
          "href": "properties/level",
          "op": "unobserveproperty",
          "subprotocol": "sse"
        }
      ]
    }
  },
  "actions": {
    "fade": {
      "title": "Fade",
      "description": "Fade the lamp to a given level",
      "synchronous": false,
      "input": {
        "type": "object",
        "properties": {
          "level": {
            "title": "Brightness",
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "unit": "percent"
          },
          "duration": {
            "title": "Duration",
            "type": "integer",
            "minimum": 0,
            "unit": "milliseconds"
          }
        }
      },
      "output": {
        "type": "object",
        "properties": {
          "state": {
            "type": "string",
            "emum": ["pending", "running", "completed", "failed"]
          },
          "output": {
            "type": "boolean"
          },
          "error": {
            "$ref": "#/schemaDefinitions/error"
          },
          "href": {
            "type": "string",
            "format": "uri"
          },
          "timeRequested": {
            "type": "string",
            "format": "date-time"
          },
          "timeEnded": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "uriVariables": {
        "actionID": {
          "type": "string"
        }
      },
      "forms": [
        {
          "href": "actions/fade",
          "op": "invokeaction",
          "response": {
            "htv:statusCodeNumber": 201,
            "htv:headers": [
              {
                "@type": "htv:ResponseHeader",
                "htv:fieldName": "Location",
                "htv:fieldValue": "{actionID}"
              }
            ]
          },
          "additionalResponses": [
            {
              "success": false,
              "schema": "error"
            }
          ]
        },
        {
          "href": "{actionID}",
          "op": "queryaction",
          "htv:methodName": "GET",
          "response": {"htv:statusCodeNumber": 200},
          "additionalResponses": [
            {
              "success": false,
              "schema": "error"
            }
          ]
        },
        {
          "href": "{actionID}",
          "op": "cancelaction",
          "htv:methodName": "DELETE",
          "response": {"htv:statusCodeNumber": 204},
          "additionalResponses": [
            {
              "success": false,
              "schema": "error"
            }
          ]
        }
      ]
    }
  },
  "events": {
    "overheated": {
      "title": "Overheated",
      "data": {
        "type": "number",
        "unit": "degree celsius"
      },
      "description": "The lamp has exceeded its safe operating temperature",
      "forms": [
        {
          "href": "events/overheated",
          "op": "subscribeevent",
          "subprotocol": "sse",
          "htv:methodName": "GET",
          "htv:headers": [
            {
              "@type": "htv:RequestHeader",
              "htv:fieldName": "Accept",
              "htv:fieldValue": "text/event-stream"
            },
            {
              "@type": "htv:RequestHeader",
              "htv:fieldName": "Connection",
              "htv:fieldValue": "keep-alive"
            }
          ],
          "response": {
            "htv:statusCodeNumber": 200,
            "htv:headers": [
              {
                "@type": "htv:ResponseHeader",
                "htv:fieldName": "Content-Type",
                "htv:fieldValue": "text/event-stream"
              }
            ]
          },
          "additionalResponses": [
            {
              "success": false,
              "schema": "error"
            }
          ]
        },
        {
          "href": "events/overheated",
          "op": "unsubscribeevent",
          "subprotocol": "sse"
        }
      ]
    }
  },
  "forms": [
    {
      "op": "readallproperties",
      "href": "properties",
      "response": {"htv:statusCodeNumber": 200},
      "additionalResponses": [
        {
          "success": false,
          "schema": "error"
        }
      ]
    },
    {
      "op": "writemultipleproperties",
      "href": "properties",
      "response": {"htv:statusCodeNumber": 204},
      "additionalResponses": [
        {
          "success": false,
          "schema": "error"
        }
      ]
    },
    {
      "op": "observeallproperties",
      "href": "properties",
      "subprotocol": "sse",
      "htv:methodName": "GET",
      "htv:headers": [
        {
          "@type": "htv:RequestHeader",
          "htv:fieldName": "Accept",
          "htv:fieldValue": "text/event-stream"
        },
        {
          "@type": "htv:RequestHeader",
          "htv:fieldName": "Connection",
          "htv:fieldValue": "keep-alive"
        }
      ],
      "response": {
        "htv:statusCodeNumber": 200,
        "htv:headers": [
          {
            "@type": "htv:ResponseHeader",
            "htv:fieldName": "Content-Type",
            "htv:fieldValue": "text/event-stream"
          }
        ]
      },
      "additionalResponses": [
        {
          "success": false,
          "schema": "error"
        }
      ]
    },
    {
      "op": "unobserveallproperties",
      "href": "properties",
      "subprotocol": "sse"
    },
    {
      "op": "queryallactions",
      "href": "actions",
      "htv:methodName": "GET",
      "additionalResponses": [
        {
          "success": "true",
          "htv:statusCodeNumber": 200,
          "schema": "actionStatuses"
        },
        {
          "success": false,
          "schema": "error"
        }
      ]
    },
    {
      "op": "subscribeallevents",
      "href": "events",
      "subprotocol": "sse",
      "htv:methodName": "GET",
      "htv:headers": [
        {
          "@type": "htv:RequestHeader",
          "htv:fieldName": "Accept",
          "htv:fieldValue": "text/event-stream"
        },
        {
          "@type": "htv:RequestHeader",
          "htv:fieldName": "Connection",
          "htv:fieldValue": "keep-alive"
        }
      ],
      "response": {
        "htv:statusCodeNumber": 200,
        "htv:headers": [
          {
            "@type": "htv:ResponseHeader",
            "htv:fieldName": "Content-Type",
            "htv:fieldValue": "text/event-stream"
          }
        ]
      },
      "additionalResponses": [
        {
          "success": false,
          "schema": "error"
        }
      ]
    },
    {
      "op": "unsubscribeallevents",
      "href": "properties",
      "subprotocol": "sse"
    }
  ]
}

We had ended up with essentially two different ways of using the Web of Things:

  • A descriptive approach for brownfield devices using Binding Templates to describe existing IoT protocols
  • A prescriptive approach for greenfield implementations using Profiles to provide fixed HTTP-based APIs and out-of-the-box interoperability

This made some amount of sense, but unfortunately the two different approaches didn’t work very well together. A major point of contention was that the prescriptive protocol bindings defined in Profiles could not be fully described using declarative protocol bindings in Thing Descriptions. The descriptive camp blamed the prescriptive camp for trying to extend rather than just constrain Thing Descriptions, and the prescriptive camp blamed the descriptive camp for defining something that wasn’t expressive enough to properly describe the full set of operations.

Bringing the Sides Together

After lots of discussions about how we could reconcile the two different approaches, we eventually came up with an idea of how Profiles and Binding Templates could work together.

The prescriptive protocol binding definitions from Profiles would be moved into binding documents as defaults for protocol bindings, which could be overridden using declarative protocol bindings in forms. Profiles would become simpler and more structured around a fixed set of extension points they could constrain. Rather than defining a protocol binding, a profile would just reference a binding document and mandate that a conformant Thing must stick to its defaults.

This way we would still have the two different approaches, but Profiles would be built on binding documents rather than providing an alternative to them.

It was around this time that some participants from Intel and Oracle (key contributors and supporters of the Profile specification) had to step back from contributing to the Working Group due to redundancies and retirement. However, in 2025 I managed to secure some grant funding to work one day per week on W3C standardisation work, with the following goals:

  • Publish a first draft of the Web Thing Protocol WebSocket sub-protocol (which it was agreed was needed regardless of Profiles)
  • Polish and publish WoT Profiles 1.0 as a Working Group Note, with a view to discontinuing that work but keeping it as a point of reference.
  • Publish a Use Cases & Requirements document for WoT Profiles 2.0, setting out the new proposed approach for the next charter period.

The Web Thing Protocol Community Group succeeded in publishing the first draft of the Web Thing Protocol WebSocket sub-protocol.

Screenshot of the Web Thing Protocol WebSocket Sub-protocol Draft Community Report from 2 December 2025.

I took over leading the Profiles task force and we spent a lot of time polishing the WoT Profile 1.0 working draft (now renamed to WoT Profiles), but a change in W3C process meant that we weren’t allowed to publish it as a Working Group Note and had to just publish a new Working Draft instead.

Screenshot of the WoT Profiles W3C Working Draft from 4 November 2025.
W3C WoT Profiles Working Draft, 2025

The Profiles task force wrote a Use Cases & Requirements document for WoT Profiles 2.0 formalising the new proposed approach to Profiles.

Screenshot of the WoT Profiles 2.0 Use Cases & Requirements Editor's Draft from 29 October 2025.
W3C WoT Profiles 2.0 Use Cases & Requirements, 2025

This all seemed to be going quite well…

Changing of the Guard

With participants from Oracle and Intel stepping back from the WoT Working Group, the balance of power in the Working Group shifted significantly towards Siemens. The Siemens employees who had written the early position papers at the first W3C WoT Workshop were no longer involved, and the current set of contributors were focused on a very specific set of use cases relating to the onboarding of IoT devices using a range of different protocols to Siemens’ industrial IoT platforms.

Meanwhile, the OPC Foundation published an OPC UA Binding for Web of Things and Microsoft started to adopt WoT Thing Models as a replacement for their own DTDL language in their Azure IoT Operations platform using their own protocol over MQTT.

With the charter of the Working Group soon due for renewal the Chairs of the Working Group were mindful that the overall level of participation in Working Group meetings (of which there were around seven per week across all task forces!) had fallen, and it may be necessary to streamline the growing list of deliverables.

Siemens effectively blocked the publication of the WoT Profiles 2.0 Use Cases & Requirements document as a Working Group Note, and shared the opinion that WoT Profiles should be removed from the list of deliverables for the next charter period (ostensibly delayed, along with WoT Discovery, until the next charter in 2+ years time). They pointed out that the member organisations (particularly Oracle and Intel) who had previously been driving the work on Profiles had now stopped contributing, and unless multiple member organisations stepped forward in support, they would be unable to justify its presence in the charter to the W3C Advisory Committee who need to approve it.

I should explain at this point that the W3C is a paid membership organisation. Member organisations have to pay significant fees in order to participate in standards track activities, and these fees are out of the reach of small startup businesses like mine. After being laid off from Mozilla I had graciously been invited to continue participating in the WoT Working Group (and Web Applications Working Group) as an individual Invited Expert instead, for which there are no fees.

The Invited Expert programme is something I really value and is an important way of getting a more diverse set of people contributing to standardisation at the W3C. However, Invited Experts do not quite have the same set of rights as paid up member organisations, and the reality is their opinions therefore don’t always count for as much. Whilst there were multiple Invited Experts still in support of WoT Profiles, it lacked member organisations willing to commit to active participation.

At the time of writing, the next charter is still being drafted, but the most likely outcome currently seems to be:

  1. WoT Profiles will be removed as a deliverable from the W3C WoT Working Group charter.
  2. The WoT Profiles 1.0 specification will never be published as a W3C Recommendation and may eventually have to be published as a Discontinued Draft, which nobody will want to implement.
  3. The WoT Profiles 2.0 specification will never be written.

How is the Web of Things being used today?

Let’s take a step back from the politics of W3C standardisation for a moment to look at a few practical examples of how the “Web of Things” is actually being used today. For the purposes of this exercise I am going to put aside how we are using the Web of Things at Krellian and the WebThings open source project, and instead look at how other people are using it.

Matter & WoT at Deutsche Telekom

This first example presented at a W3C WoT Community Group Meetup is a project by Till Langen at Deutsche Telekom to integrate the Matter protocol into the Magenta Zuhause platform, using the Web of Things as an abstraction. Matter is a popular smart home protocol that has been adopted by big tech companies like Apple, Google and Amazon.

First Till describes a design concept he worked on as part of his Bachelor thesis for integrating Matter by directly describing the Matter protocol using Thing Descriptions. Due to the hierarchical nature of how a physical device is modelled in Matter, Till found the easiest way was to create a Thing Description for each Matter “endpoint”. This means that a single physical device is actually described by a collection of Thing Descriptions, with link relations describing the relationships between them.

The Matter concepts of attributes, commands and events map quite neatly onto the WoT concepts of properties, actions and events. However, whilst the Matter protocol technically does have a URI scheme, mt:, URIs only contain information like vendor ID, product ID and some other parameters that help with the onboarding process, they are not used for identifying individual resources. This meant that in order to directly describe Matter operations using hypermedia forms in Thing Descriptions Till had to invent his own theoretical matter:// URI scheme.

So for example:

  • A URI for carrying out a read property operation has the form matter://<node_id>/<endpoint_id>/<cluster_name>/read/<attribute_name>
  • A URI for carrying out an invoke operation has the form matter://<node_id>/<endpoint_id>/<cluster_name>/invoke/<command_name>?<parameterX>=<value>
  • A URI for subscribing to an event has the form matter://<node_id>/<endpoint_id>/<cluster_name>/subscribe/<event_name>?<parameterX>=<value>

Whilst a clever way of embedding all the information needed to carry out an operation in a URI, you can see that these URIs are not very RESTful (e.g. using verbs like “read”, “invoke” and “subscribe” in the URIs). This is because the Matter protocol is not inherently resource-oriented or RESTful, so trying to serialise operations as hypermedia forms is not a natural fit. You’ll see that this approach of trying to retrofit a contrived URI scheme onto a protocol which is not inherently resource oriented will become a bit of a common theme.

The theoretical Matter binding also defines semantic ontologies for describing a range of Matter-specific concepts including a custom security scheme called mattersecurity:SecurityScheme, semantic types for affordances like matter0x0006:0x02 and custom link relation names like matterDescriptorCluster:0x0003.

I think it’s also important to note that whilst Matter is technically an internet protocol (it’s based on IPv6), in practice it is almost exclusively used on local networks rather than being directly exposed to the internet.

Later in the presentation Till goes on to explain that the proof of concept implementation he worked on did not actually use this matter:// URI scheme at all, but instead bridged Matter to the HTTP protocol using a much more RESTful approach that also works well over the internet and is easier for apps to consume.

Creating an abstraction on top of Matter for apps to consume is not unusual. In fact end user applications rarely speak the Matter protocol directly, but use an abstraction like Apple’s HomeKit, Google’s Home API on Android and Home Graph in the cloud, and Amazon’s Smart Home Skills API for Alexa.

OPC UA & WoT at the OPC Foundation

OPC UA is an IEC standard for data exchange mostly used in industrial IoT and sometimes commercial buildings. The OPC UA standard is intended to be protocol agnostic, but the most commonly used protocol mapping is a binary format over TCP. There are also mappings for UDP/IP, WebSockets, AMQL and MQTT.

In this WoT Community Group meetup, Erich Barnstedt from Microsoft and Sebastian Käbisch from Siemens (also co-chair of the W3C WoT Working Group) describe their work with the OPC Foundation to use OPC UA with the Web of Things via companion specifications.

Erich set out to try to make industrial assets more discoverable using WoT Thing Descriptions. He describes a project which uses the GPT4 large language model to automatically generate Thing Descriptions for assets in order to map them to the OPC UA information model. He gives examples of describing devices using WoT Thing Descriptions, with Forms using URIs with a modbus:// URI scheme, and adding Modbus and OPC UA specific semantic annotations. The modbus:// URI scheme is not formally registered with IANA, and whilst some Modbus devices use an IP transport others actually use a serial connection and a WoT Consumer would not be able to distinguish between the two.

Erich mentions the OPC WoT Connectivity specification which describes an OPC UA specific API for managing assets and uploading a WoT Thing Description, and the UA Edge Translator open source project which bridges a range of proprietary industrial protocols to OPC UA. I think it’s important to note that here is a project which is using WoT Thing Descriptions to map non-web protocols to another non-web protocol. The web as we traditionally understand it is not actually involved at all, and yet it is described under the banner of the “Web of Things”.

Sebastian then goes on to introduce another OPC UA companion specification he worked on with Erich – the OPC UA WoT Binding. He explains that while OPC UA has an existing solution for describing devices using XML, it is very complex and requires a deep understanding of the protocol. The OPC UA WoT Binding makes it possible to expose a small subset of the functionality of OPC UA using a WoT Thing Description, which makes it easier for a range of IoT applications to consume.

To make it possible to describe OPC UA directly using a WoT Thing Description, the OPC UA WoT Binding defines a URI scheme for OPC UA (again, is not formally registered with IANA), with the following format:

opc.tcp://<address>:<port>[/<resourcePath>]/?id=<nodeId>

Whilst OPC UA’s information model is object and reference-centric with a graph of nodes which may feel kind of resource-oriented, the OPC UA protocol was primarily designed as a connection-oriented, stateful industrial protocol and is not inherently resource-oriented or RESTful. OPC UA over TCP uses its own binary protocol with long-lived sessions and a rich set of services (e.g. browser, read, write, call methods, subscribe etc.), rather than the constrained HTTP verbs of REST. This means that trying to describe operations using hypermedia forms is not a natural fit.

The OPC UA WoT Binding manages to squeeze the important information needed to carry out operations on an OPC UA device into a URI, but there is also an optional semantic ontology for annotating a Thing Description with OPC UA specific concepts with terms like uav:object, uav:variable, uav:method, uav:hasComponent and uav:componentOf. Whilst these annotations are optional, this is another example of protocol specific terms creeping into the Thing Description, which is being used to directly describe an existing protocol rather than providing a web abstraction on top of it.

Next Sebastian gives some examples of what he describes as the benefit of giving devices Thing Descriptions, using the WoT Scripting API implemented in the Eclipse Thingweb (node-wot) open source project. Below is an example he gives of a script which consumes devices using both OPC UA and HTTP, without worrying about protocol specific concepts like nodeID, HTTP methods, contentType etc.

These examples really made something click for me. When consuming different protocols using node-wot it is the scripting API which appears to be the “narrow waist” of the Web of Things. This is where the abstraction happens and all of the protocol-specific concepts fall away. Suddenly it made sense to me why people working with node-wot don’t see protocol bindings as a problem, but as the solution – because the bindings are entirely hidden from developers writing application code.

The problem with this approach for me is that whilst you may be able to write an application in JavaScript (specifically JavaScript, which is what the Scripting API is designed for) which doesn’t have to worry about protocol specifics, fundamentally every WoT Consumer implementation still has to implement potentially dozens of individual protocols in order to interoperate. This is not web-style interoperability, as I will discuss further below.

Interestingly, after attending this meetup I discovered that OPC UA now has its own Web API and WebSocket sub-protocol – which do expose devices directly to the web using HTTP and WebSockets, but they are not used here.

BACnet & WoT at Siemens

The next example is from a WoT Community Group presentation by Doğan Fennibay at Siemens.

Doğan explains that a typical complex commercial building may have systems which use a range of protocols like KNX, M-bus, Modbus and BACnet. Siemens has the Desigo CC building management platform on the edge, and Building X platform in the cloud, which help to bridge all of these systems together. He says that whilst BACnet is very popular and has a 77% market share in buildings, an increasing number of IoT developers creating edge and cloud applications like to have a web-like paradigm to interact with. There are also specific verticals like integration into the energy grid which BACnet does not currently support.

Doğan notes the trend towards using IP everywhere, including IPv6 replacing serial protocols, and that WoT is well placed to extend BACnet to help complete these integrations.

BACnet is an ISO/ASHRAE/ANSI standard protocol for building automation and control systems like HVAC, lighting, access, control, fire alarms, meters and sensors. It models devices as collections of “objects” using 60 object types (e.g. Analog Input, Binary Output, Schedule, and Trend Log) that are acted upon by “services”. The standard (which you have to pay for a copy of if you want to read it) defines a number of transports including ARCNet, Ethernet, IP, MSTP, RS-232 and even Zigbee – but IP and MS/TP dominate today. BACnet over IP uses binary messages with a compact TLV-style (tag, length, value) structure encapsulated in UDP packets.

Doğan then goes on to introduce the WoT BACnet Binding – a draft specification that aims to directly describe BACnet devices using WoT Thing Descriptions. He emphasises that the binding takes a use case driven approach to only describing a small subset of BACnet features (he notes that the bacowl ontology contains 17,601 triples alone!).

The BACnet binding re-uses and extends the bacnet:// URI scheme defined in BACnet specifications (which again is not yet formally registered with IANA), an example of which is shown below.

bacnet://5/0,1/85

This URI scheme represents a device ID, object ID and optional property ID. The WoT Binding extends this URI scheme with the URI variables commandPriority, relinquish and covIncrement to provide further information. The binding also defines a vocabulary for annotating a Thing Description with additional BACnet-specific details such as bacv:usesService, bacv:isISO8601 and bacv:hasBinaryRepresentation. It maps BACnet objects (not properties) to WoT properties, notification classes to events, and uses action affordances for things like synchronisation. BACnet only supports one encoding format based on ASN.1, but since there is no specific IANA registered MIME type for that, the binding enforces that application/octet-stream should always be used.

The BACnet protocol is kind of resource-oriented if you squint, but it’s certainly not RESTful, and the vocabulary defined in the binding surfaces a lot of BACnet-specific concepts in Thing Descriptions.

When asked, Doğan says he sees the WoT information model (properties, actions and events) as being the narrow waist of the Web of Things. There are protocol specifics in Thing Descriptions, but the data model is common.

After the meetup I discovered that BACnet actually has a standardised REST API called BACnet/WS which was defined in the ASHRAE 135-2024 release, but that isn’t used here.

MQTT & WoT at Microsoft

The final example is a potentially quite exciting usage by Microsoft, which had been alluded to in some WoT Working Group meetings, but has finally been revealed in a GitHub repository. The headline is that the Azure IoT team are working on replacing their own DTDL language for describing digital twins with W3C WoT Thing Models in their Azure IoT Operations platform.

On the surface this seems like a huge win for the Web of Things, but when you dig down into the details you will see that rather than creating web things that any existing WoT Consumer would be able to consume, the AIO team are creating a vendor-specific AIO binding to describe their own AIO protocol over MQTT.

The W3C Working Group has an existing draft of a WoT MQTT binding, but Microsoft’s implementation does not use it. The README in the GitHub repository explains why they made this decision, but essentially whilst AIO is built on an MQTT transport, the specific dialect it speaks to perform operations (topic patterns, a JSON-based RPC “state store” protocol, and CloudEvents wrapper for telemetry events etc.) is vendor-specific. Presumably this could not all be fully described using existing binding vocabularies.

This means that in order to consume these web things, WoT Consumers would first need to implement this Azure-specific WoT ontology (including 17 custom RDF terms like aov:capability, aov:component and aov:reference) in order to parse Thing Descriptions, and then implement an Azure-specific protocol to communicate with the Things. This is not really how WoT bindings were intended to be used, and whilst I understand why they did it (they had an existing platform they wanted to describe), unfortunately the resulting implementation has a bit of an embrace, extend and extinguish flavour to it.

As you can probably guess by now, it appears that Azure IoT Operations also has its own HTTP REST API (although it is primarily designed for getting data into the system rather than out of it).

What’s Not Working

There are countless more examples I could give of how the Web of Things is being used today, many of which are implementing the Web of Things using web protocols like the WebThings project does, but I hope these examples are sufficient to get my point across.

That point is that we started out by creating a tool for describing level 3 maturity REST APIs using hypermedia controls, and then over time tried to use it for describing a bunch of IoT protocols which in most cases are not even level 0. The Working Group tried to make this work by retrofitting URI schemes to existing protocols, but unfortunately contriving a URI scheme for a connection-oriented stateful protocol doesn’t make it resource-oriented or stateless.

At times this has inevitably led people to ask whether the strict constraint of requiring protocols to have URI schemes should just be dropped, and Thing Descriptions should be free to use other ways of describing communication interfaces. I strongly reject that idea, because if URLs are removed from the Web of Things then there’s really no “web” left at all, and it’s just another IoT metadata format.

However, because existing IoT protocols are not a natural fit for hypermedia forms, describing them directly in Thing Descriptions requires extending the WoT information model using complex semantic ontologies. These ontologies then surface a lot of protocol specifics in Thing Descriptions, which Consumers have to parse and understand. Whilst this declarative mechanism may work for simple examples and one-off single-vendor integrations, I still haven’t seen much evidence that it can really provide the kind of cross-vendor plug-and-play interoperability we have come to expect from the web. There are always cases when a Thing Description is not expressive enough and unambiguous enough to describe a given protocol and payload binding to the extent that a Consumer can understand what to do without additional out-of-band knowledge.

What is also clear is that in all of the above examples we know it would be possible to bridge the protocols to an HTTP-based REST API if we wanted to, because it has already been done!

I want to be clear that it is not my intention to criticise implementers like Deutsche Telekom, Siemens and Microsoft here for “doing WoT wrong”. They have specific use cases they are trying to solve like onboarding industrial IoT devices and bridging smart home protocols to their own platforms. (Siemens in particular deserve a huge amount of credit for pushing the Web of Things forward.) If the existing WoT specifications are solving those use cases for them then that’s great, I don’t think there’s anything wrong with that. Even just defining a common metadata format for IoT is useful.

What I think is missing is the bigger picture thinking about what a Web of Things was originally envisioned to be and what makes it the Web of Things as opposed to the Internet of Things. Rather than lots of isolated networks of things using different protocols, how we can achieve a universal Web of Things on the scale of the World Wide Web which is greater than the sum of its IoT parts?

What is the narrow waist of the Web of Things?

After attending a lot of WoT Community Group meetups like the ones above, I started asking people a question. What do you think is the “narrow waist” of the Web of Things? I’ve used that term a few times now so let me just explain what it means.

This term comes from the hourglass model of computer networking, for describing “a layered system design in which a single, widely adopted spanning layer sits at the narrow “waist” of the stack and serves as the sole common interface between many heterogeneous lower-layer technologies and many diverse higher-layer applications.” In the context of the wider internet, the Internet Protocol (IP) is traditionally considered this spanning layer.

When I ask this question about the Web of Things, which also has a layered system design, the most common answers I get are:

  1. WoT Scripting API – since it allows the same application logic to be used across different protocols
  2. WoT Information Model – the common abstraction in Thing Descriptions for describing capabilities of devices across different protocols

Neither of these answers feel satisfying to me, because in both cases it means that WoT Consumers (like apps, services and intelligent agents) still ultimately have to implement potentially dozens of underlying IoT protocols in order to communicate with the full range of devices. Whilst it might help slightly with onboarding or scripting, it doesn’t really effectively “counter the fragmentation of the IoT” as per the stated mission of the W3C Web of Things. It doesn’t provide web-style interoperability.

I recently read the book This is for Everyone by Tim Berners-Lee, the inventor of the World Wide Web. Along with his previous book, Weaving the Web, the book charts the history of the invention and evolution of the web, the problems he set out to solve, and how the web came to be what it is today (including the design issues he now sees, and how he proposes to fix them).

The cover of the book This is for Everyone by Tim Berners-Lee.

This is a great book which I really recommend reading, but in the book Tim is very clear about the important components that made up his invention – URLs, HTTP and HTML.

To look at web development today you could be forgiven for thinking that the JavaScript runtime in the browser is the “narrow waist” of the Web, which enables web applications to run on browsers from different vendors, and to a small extent that is true. However, what enabled the World Wide Web to grow in the first place was not JavaScript (which didn’t even exist in the first web browsers), but HTML, HTTP and URLs. Whilst JavaScript provides an important layer of client-side application logic on top, what really defines the web is that it is a global network of resources linked together by URLs, whose value comes just as much from the links representing relationships between the resources as it does from the content of the resources themselves.

If the web had started as a JavaScript (or probably Mocha or LiveScript back then) runtime which had a consistent data model and scripting API, but all the web pages had to be retrieved using different protocols and parsed from different data formats (instead of predominantly HTTP and HTML), I simply don’t believe that it would have got off the ground in the first place. There were certainly other hypertext protocols competing with HTTP in the early days of the web, but it didn’t start to really take off until we settled on one. The narrow waist of the web is HTTP (and URLs).

This is important, because if we genuinely want to learn lessons from how the World Wide Web transformed the Internet and apply them to the Internet of Things, we need understand what made it unique.

So what is the narrow waist of the Web of Things? I don’t think it’s the Scripting API. I don’t think it’s the information model. I think the narrow waist of the Web of Things is missing.

The Web Thing Protocol

Enter the Web Thing Protocol – a common protocol for communicating with connected devices over the web. Not just the WebSocket sub-protocol which has been defined so far (which itself is not particularly resource-oriented or RESTful), but a dedicated HTTP-based application layer protocol for the Web of Things as originally set out in the Web Thing Protocol Use Cases & Requirements report.

Going back to the original vision from Building the Web of Things and the original Web of Things community. Going back to the clear early consensus from the very first W3C Workshop on the Web of Things. Going back to the proposed approach from EVRYTHNG’s Web Thing Model and Mozilla’s Web Thing API. Choosing not to limit the Web of Things to simply describing the existing fragmented IoT landscape, but reaching for something more universal.

Rather than trying to design a JSON-based metadata format which is theoretically capable of describing the minute details of individual operations in any protocol and payload format, I propose that the Web of Things should instead provide a prescriptive universal web-based abstraction on top of those protocols. Thing Descriptions should hide rather than expose protocol and platform-specific concepts, and instead represent Things using collections of resources with URLs (with real IANA-registered URI schemes and MIME types), and a prescriptive RESTful API using the basic set of HTTP verbs (extended with Server-Sent events for push notifications, and WebSockets for efficient real-time communication where necessary).

Semantic annotations can add a rich optional additional layer of meaning on top of Thing Descriptions, using (sometimes domain-specific but always protocol-agnostic) ontologies to explain the information that is being represented, not the protocol or payload format used to transport it. This will result in a truly plug-and-play, domain-agnostic Web of Things where any Consumer can communicate with any Thing on at least a basic level, and Consumer implementations like apps, services and intelligent agents don’t have to implement dozens of different protocols in order to participate.

Although I still think a more structured profiling mechanism could still be useful in the long term, overall I feel that WoT Profiles may have been a distraction that just delayed me from working on the thing that the Mozilla IoT team originally set out to build – a universal application layer protocol for the Internet of Things. I believe that this is the missing waist of the Web of Things, and the key missing piece needed for it to really grow.

The good news is that the work from WoT Profiles will not have been wasted. As a starting point for the Web Thing Protocol HTTP Sub-protocol I have created a strawman proposal which takes the protocol bindings from the HTTP Basic Profile and HTTP SSE Profile and combines them into a single “sub-protocol”.

I’m not sure that “sub-protocol” is exactly the best term for what this is. The WebSocket protocol specification specifically defines the concept of “sub-protocols”, but the HTTP protocol does not. I’m calling it a sub-protocol because it is initially intended to use the sub-protocol mechanism which is already baked into Forms in Thing Descriptions, instead of the profiling mechanism. Below is an example Thing Description for the same web thing described in the profile examples above, but using the sub-protocol mechanism rather than the profiling mechanism:

{
  "@context": "https://www.w3.org/2022/wot/td/v1.1",
  "id": "https://mywebthingserver.com/things/lamp",
  "base": "https://mywebthingserver.com/things/lamp/",
  "title": "My Lamp",
  "description": "A web connected lamp",
  "securityDefinitions": {
    "oauth2": {
      "scheme": "oauth2",
      "flow": "code",
      "authorization": "https://mywebthingserver.com/oauth/authorize",
      "token": "https://mywebthingserver.com/oauth/token"
    }
  },
  "security": "oauth2",
  "properties": {
    "on": {
      "type": "boolean",
      "title": "On/Off",
      "description": "Whether the lamp is turned on",
      "forms": [
        {
          "href": "properties/on",
          "op": [
            "readproperty",
            "writeproperty",
            "observeproperty",
            "unobserveproperty"
          ],
          "subprotocol": "webthingprotocol"
        }
      ]
    },
    "level" : {
      "type": "integer",
      "title": "Brightness",
      "description": "The level of light from 0-100",
      "unit": "percent",
      "minimum" : 0,
      "maximum" : 100,
      "forms": [
        {
          "href": "properties/level",
          "op": [
            "readproperty",
            "writeproperty",
            "observeproperty",
            "unobserveproperty"
          ],
          "subprotocol": "webthingprotocol"
        }
      ]
    }
  },
  "actions": {
    "fade": {
      "title": "Fade",
      "description": "Fade the lamp to a given level",
      "synchronous": false,
      "input": {
        "type": "object",
        "properties": {
          "level": {
            "title": "Brightness",
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "unit": "percent"
          },
          "duration": {
            "title": "Duration",
            "type": "integer",
            "minimum": 0,
            "unit": "milliseconds"
          }
        }
      },
      "forms": [
        {
          "href": "actions/fade",
          "op": [
            "invokeaction",
            "queryaction",
            "cancelaction"
          ],
          "subprotocol": "webthingprotocol"
        }
      ]
    }
  },
  "events": {
    "overheated": {
      "title": "Overheated",
      "data": {
        "type": "number",
        "unit": "degree celsius"
      },
      "description": "The lamp has exceeded its safe operating temperature",
      "forms": [{
        "href": "events/overheated",
        "op": [
          "subscribeevent",
          "unsubscribeevent"
        ],
        "subprotocol": "webthingprotocol"
      }]
    }
  },
  "forms": [
    {
      "href": "properties",
      "op": [
        "readallproperties",
        "writemultipleproperties",
        "observeallproperties",
        "unobserveallproperties"
      ],
      "subprotocol": "webthingprotocol"
    },
    {
      "op": "queryallactions",
      "href": "actions",
      "subprotocol": "webthingprotocol"
    },
    {
      "op": [
        "subscribeallevents",
        "unsubscribeallevents"
      ],
      "href": "events",
      "subprotocol": "webthingprotocol"
    }
  ]
}

A more accurate term than “sub-protocol” might be “domain application protocol” (where the domain is IoT as a whole). But regardless of what you call it, the idea of building an application layer protocol on top of HTTP is certainly not new. Existing successful examples include the Atom Publishing Protocol, ActivityPub, AT Protocol, Matrix, GraphQL, gRPC, the currently very trendy MCP and even Solid – designed by Tim Berners-Lee himself.

Again, I want to emphasise that my argument is not that a protocol built on HTTP is going to be the best IoT protocol, or that all IoT protocols should be replaced with it. There are many reasons that HTTP is poorly suited to IoT, which require it to be extended with mechanisms like Server-Sent Events and (the not so RESTful) WebSockets for certain use cases. My argument is instead that the history of the web suggests that a simple ubiquitous protocol based on a resource-oriented REST architecture can provide a universal abstraction layer on top of a rich tapestry of specialised underlying protocols, that an open ecosystem of apps, services, and intelligent agents can consume. And that this simple abstraction layer could have the potential to unlock an exponential increase in the size and value of the network.

What’s Next?

It appears that for its next charter period the WoT Working Group will be focusing on WoT Thing Description 2.0 as its only normative deliverable, along with the WoT Binding Registry, WoT Scripting API and other supporting documents.

Thing Description 2.0 will bring some welcome optimisations that will be useful for the Web Thing Protocol as well. I suggest that we accept that work on WoT Profiles is at least paused for now, and rather than try to define a comprehensive profiling mechanism which can constrain all of the different extension points of the Web of Things, we narrow our focus to defining a re-usable, prescriptive HTTP protocol binding (the Web Thing Protocol) using the existing sub-protocol mechanism instead.

Whilst the Working Group focuses on the Thing Description specification I propose that the Web Thing Protocol Community Group continues to incubate the Web Thing Protocol specification as a complement to that key building block, working closely with the Working Group to ensure continued alignment.

We should then work on a plan for eventually getting the Web Thing Protocol onto a standards track, either as a deliverable in the next charter of the WoT Working Group, a new dedicated Working Group at the W3C, or alternatively a new Working Group at the IETF.

To be clear, I think the descriptive approach and prescriptive approach can continue to co-exist (as long as it doesn’t result in too much complexity in the core specifications). Time will tell which one of them will allow the Web of Things to truly scale.

Call to Action

What can you do to help?

📄 Firstly, the Web Thing Protocol Community Group needs a diverse set of people to contribute to writing and reviewing the Web Thing Protocol specification, so that it’s the best protocol it can be. With the group’s support I hope we will soon start to work on defining the Web Thing Protocol HTTP sub-protocol, starting from the use cases and requirements we have defined and the strawman proposal I have already shared. We will also continue to work on refining the WebSocket sub-protocol based on implementation feedback. Note that anyone can join the Web Thing Protocol Community Group and contribute on GitHub, you don’t need to be a W3C member.

💡 Secondly, you can help by implementing the Web Thing Protocol in your project, product or service. The WebThings project will need help implementing the Web Thing Protocol in WebThings Gateway, and in a range of different programming languages in the WebThings Framework. There is also the beginnings of a Web Thing Protocol client implementation in node-wot.

In a future blog post I will also write about what I think is a key piece of software that the Web of Things lacks – the equivalent of a browser for the Web of Things. I will explain why I am working on a WebThings app that will act as a general purpose WoT Consumer on desktop and mobile, and how I believe that will help bring the Web of Things to a broader audience.

Let’s put the web back in the Web of Things.

How I think Web Apps Should be Installed

Example web app install flow using ambient badging

There’s currently a discussion at the W3C about how web apps should be installed from web browsers.

I won’t chronicle the whole twenty year long debate here, but suffice to say over the years browser vendors and OS makers have tried lots of different approaches.

The current solutions being considered for standardisation in the Web Applications Working Group are:

  • The beforeinstallprompt event – An event on the window object implemented in Chromium by Google (but not adopted elsewhere) which allows developers to intercept the browser’s own prompt to install the current app and provide their own UI
  • A navigator.install() method – An explicit API implemented in Chromium by Microsoft and Google which allows developers to request installation of their app at any time (there is also a related cross-origin proposal for installing other apps)
  • An <install> HTML element – A declarative solution (prototyped in Chromium) with a special button, whose content and presentation is controlled by the browser, which can be placed in a document to enable a user to install the current app

beforeinstallprompt

Pros:

  • It gives the browser control over when an app can be installed, which may reduce noise slightly
  • There is a trusted native browser user interface for installing apps

Cons:

  • Unpredictable and confusing for developers. It’s an odd (though not unprecedented) API design to listen to an event which is emitted before something occurs and intercept it and call a method on the event object. Implementations of this event have so far been very unpredictable, with browsers using different heuristics to decide when to show an install app prompt.
  • Likely to lead to nagging popups, banners or install buttons inside web apps trying to get users to install an app.

navigator.install()

Pros:

  • An explicit, predictable API that developers can use when they choose

Cons:

  • Likely to lead to annoying popups, banners or install buttons inside web apps trying to get users to install an app
  • The UI is left down to developers so will be inconsistent, and could potentially even compete with the browser’s own prompts

<install>

Pros:

  • Trusted native browser user interface for installing apps (though buried in web pages)

Cons:

  • Likely to litter the web with install buttons
  • Potentially problematic for some apps like games which use canvas or WebGL instead of the DOM

In my opinion all three of these proposed solutions risk littering the web with (at best) install buttons or (at worst) nagging popups and banners. The web is already plagued with interruptions like ads, paywalls and cookie consent banners and this would just add to the noise – further eroding the experience of web apps compared with native apps.

Another Way – Ambient Badging

In my opinion, the user interface for installing web apps should be trusted, consistent, easy to discover, but keep out of the way when it isn’t needed. It should feel equivalent to installing a native app (not a second class citizen), but also work to the unique strengths of the web rather than just imitating the model used by native app stores.

My view is that we already have a declarative solution for a web page to point to a web app that can be installed, and that’s a Web Application Manifest linked to using a manifest link relation in a link element:

<link rel="manifest" href="manifest.webmanifest">

I believe Samsung coined the term “ambient badging” around 2017, but similar ideas had come before and after it, like Opera’s similar features and my own pinned apps proposal for Firefox OS in 2014 and ambient badging proposal for Fenix in 2019.

The basic idea is that the browser provides a subtle but immediately visible indication that the current web page is part of a web app that can be installed. In my opinion the best ambient badge for a web app is the web app’s own icon, but it could be a generic install button that appears somewhere in the browser chrome. The key thing is that there’s a clear indicator that the app can be installed, which doesn’t get in the way but isn’t buried deep inside a menu somewhere.

I’ve quickly created some example wireframes below to illustrate how this could look in existing mobile and desktop web browsers. When a user navigates to a page which links to a web app manifest (and the page falls within the navigation scope of that manifest), the browser displays a badge in the browser chrome indicating that there is an app that can be installed. Browsers can decide the criteria that a manifest needs to meet in order to show this badge (e.g. a valid manifest with a start_url and at least one icon), but it should be documented, consistent and predictable. The badge could potentially replace the site info icon if one is usually displayed, in order to reduce clutter.

App install hint

The first few times a user navigates to a web page which links to a valid manifest it might be useful to show a hint which teaches the user about the feature (ideally displacing the viewport rather than obscuring it), so that they know where to find it. Note that the hint overlaps the URL bar so that it’s clear it is browser chrome and not content. Once the user has used the feature, or the prompt has displayed a certain number of times, or they have explicitly requested it not be shown again, the hint would no longer be displayed. The install app feature would then keep out of the way until it is needed (and could additionally be present inside an overflow menu for discoverability). Subtle animated cues could also help draw attention to the badge.

When the user clicks on the badge, they are presented with an app install dialog.

The app install dialog shows the name and icon of the app, and importantly the origin it is being installed from. Again note that the dialog overlaps the URL bar to show that it is browser chrome rather than content. In my opinion it’s important that the language used in this dialog matches the language used for installing native apps on that platform (i.e. “install” rather than “add to home” or “add shortcut”) so that it’s clear that this action is equivalent to installing a native app.

The app install dialog could be combined with other site information like a site info dialog if that helps to reduce clutter in the browser chrome.

Depending on the design of the particular operating system, once the user clicks the install button (and after any progress indicator has completed) they could either be navigated to a homescreen or app dock to show the new icon appearing, or the browser chrome could simply disappear as the manifest is applied to the browsing context to create an application context using the display mode specified in the manifest.

Installed app in standalone display mode

Once installed, web apps should ideally be treated as first class citizens on operating systems, appearing in lists of installed apps in app launchers and settings, and getting the same icon treatment as native apps.

Example Implementation

I’ve implemented the W3C Web Application Manifest specification a few times now, on Firefox OS and a prototype tablet, but most recently for the in-development Krellian OS smart building operating system.

Like Firefox OS, Krellian OS only runs web applications and the terminology used in the UI is to “pin” them. Pinning an app immediately transforms its browsing context into a standalone display mode and adds its icon to the app launcher.

Early screen capture of pinning an app on Krellian OS

Why only websites with manifests?

A change to the Editor’s Draft of the Web Application Manifest specification in February 2025 added a new informative definition of “installable web application” which includes the text “Any website is an installable web application.” This is to reflect a recent direction of browser vendors to treat all web pages the same whether they link to an app manifest or not. I don’t agree with this and think it’s actually inconsistent with the normative text of the specification, which says a web site can only become an “installed” web application if it links to a web application manifest.

Saying that any website is an installable web application also implies that all websites are web apps, which I don’t agree with. In my view, allowing any web page to be “installed” dilutes the concept of web apps and further erodes their perceived value and quality when compared with native apps. I think good web apps have certain important characteristics which differentiate them from websites, but as a minimum bar a website should need to self-declare as a web app by providing a web application manifest.

What about app stores?

Another feature that Microsoft in particular seem interested in is the installation of cross-origin or background documents. Both the navigator.install() and <install> solutions have been proposed as working cross-origin to install another web app, in addition to just the current web app. It appears Apple are not happy with that idea, but importantly the W3C TAG have also expressed concerns.

A key use case for this feature is to allow a website to act as an app store from which users can directly install web applications from other websites. Whilst this is something that we implemented back in the days of Firefox OS and the Firefox Marketplace, I’m not convinced it’s actually needed, or in fact in the interests of the web.

I personally think that rather than app stores, the web can benefit from web app directories with curated collections of apps including links that users can follow to immediately start using the app before deciding to install it through the native browser UI. I think this better leverages the unique strengths of the web, which are that web apps can be discovered and used immediately without needing to be installed, with installation being an optional additional step a user can take if they want to save the app to their device to use regularly.

The Caveat

I acknowledge that these ideas are not new, and they have been tried before. For this to become the de-facto solution for users to install web applications it requires all major browser vendors to be willing to surface web app installation much more visibly in their user interface. The solution is one of UI design using existing technologies, rather than prescribing a new API design in a specification. Unfortunately this is in conflict with bad incentives some browser makers have to bury web application installation deep inside an overflow menu.

In particular, I think it requires Apple to start seeing web apps as a complement to their curated proprietary app store, rather than a threat, and treat web apps as first class citizens on iOS and macOS. Otherwise I think we are doomed to a further degraded experience which makes the web suffer. I urge Apple to embrace Steve Jobs’ original vision of web apps being first class citizens on the iPhone.

I think browsers which visibly but subtly surface a trusted browser-native UI for installing web apps, which are treated as first class citizens on operating systems, would be the best outcome for the web.

Introducing the Web Thing Protocol

I am excited to share that the W3C Web Thing Protocol Community Group has published the first draft of the Web Thing Protocol WebSocket sub-protocol, a dedicated real-time protocol for the Web of Things.

The Web Thing Protocol provides a WebSocket sub-protocol for monitoring and controlling connected devices over the Web, and I believe could be a key enabling technology for an open ecosystem of IoT web services.

The Web of Things

The Web of Things extends the World Wide Web of pages into a web of physical objects in the real world, by giving connected devices URLs on the web. I think of the Web of Things as being to the Internet of Things what the Web is to the Internet, providing a unifying application layer for monitoring and controlling connected devices using web technologies.

Existing building blocks of the Web of Things include:

  • The W3C WoT Thing Description specification which defines a JSON-based metadata format for describing “Things” (connected devices) and their capabilities.
  • The W3C WoT Discovery specification which defines mechanisms for discovering Things on the Web.
  • The draft W3C WoT Profiles specification which defines interoperability profiles that provide out-of-the-box interoperability for Things which conform to certain constraints.

Motivation

When we started building the Krellian Cloud cloud service, we needed a way for our Krellian Hub commercial IoT gateway to stream data from hundreds of sensors in a commercial building to the cloud in real-time, to create a digital twin of the building in order to model how it is being used and identify potential optimisations.

The WoT Profiles specification (of which I am also an editor) currently provides two ways to observe properties and subscribe to events from devices over the Web:

  • HTTP SSE Profile – Using the existing W3C/WHATWG Server-Sent Events standard to upgrade an HTTP request sent from a WoT Consumer to a WoT Thing to an open channel through which data can be pushed to the Consumer as changes occur, but requiring a separate TCP connection per interaction affordance and only providing uni-directional communication.
  • HTTP Webhook Profile – Using the common Webhook design pattern such that a WoT Thing acts as an HTTP client which sends property changes and events to a WoT Consumer acting as an HTTP server, but requiring a new TCP socket to be opened for each message sent, and the reversal of the usual client/server roles of Things and Consumers.

My conclusion from trying to use these Profiles for Krellian Hub and Krellian Cloud was that…

  • Server-Sent Events are good for listening to high frequency events from a small number of devices.
  • Webhooks are good for listening to low frequency events from a large number of devices.

…but neither solution scales well for frequent events from a large number of devices.

You can see a more detailed analysis in this talk that I gave to the Web of Things Community Group last year:

What we really needed was a web-based protocol that could stream a high frequency of messages to and from a large number of devices over a single persistent connection.

Enter WebSockets…

WebSockets

WebSockets are an existing W3C/WHATWG/IETF standard which provide a way to upgrade a standard HTTP request to a full-duplex, persistent, real-time communication channel over a TCP socket.

This can be used to create a versatile and efficient two-way channel with which a WoT Consumer can communicate with one or more WoT Things to carry out the full set of WoT operations. However, since a WebSocket is essentially just a raw TCP socket with no semantics of its own, a sub-protocol needs to be defined in order for a Consumer and Thing to communicate.

The Web Thing Protocol

I started the W3C Web Thing Protocol Community Group in 2019 with the mission of defining “a common protocol for communicating with connected devices over the web, to enable ad-hoc interoperability on the Web of Things”. One of the deliverables of the group was a WebSocket sub-protocol.

We published a Use Cases & Requirements document in 2023, but it is only recently, driven by the commercial needs of my startup, Krellian, and made possible by funding from a StandICT.eu fellowship, that I have been able to dedicate significant time to working on the WebSocket sub-protocol specification.

I’ve been very fortunate to be joined in this endeavour by an active community of contributors, with special thanks going to Ege Korkan from Siemens, Robert Winkler from Deutsche Telekom, Henk Spaaij, Christian Paul, Daniel Peintner and Cristiano Aguzzi for their many code reviews and invaluable feedback on the specification.

The Web Thing Protocol specification complements the existing building blocks of the Web of Things by defining a dedicated real-time protocol for communicating with one or more WoT Things over the Web.

It is a WebSocket sub-protocol specifically designed around the Web of Things information model, making it native to the Web of Things. The sub-protocol defines message payload formats for each of the operation types defined in the WoT Thing Description specification and makes it possible to carry out the full set of WoT operations on one or more WoT Things over a single WebSocket connection.

The Web Thing Protocol is intended to be used by IoT gateways, cloud services, and even directly by connected devices themselves. Often it will likely be used as a web-based abstraction on top of another underlying IoT protocol like Zigbee, Z-Wave, HomeKit, Matter, Modbus or BACnet – to enable an open ecosystem of IoT web services which link together otherwise incompatible IoT platforms.

Part of the inspiration for this sub-protocol comes from the legacy Mozilla IoT Web Thing WebSocket API used by WebThings Gateway (and actually even further back than that to an experimental new architecture for Firefox OS where web applications would use HTTP & WebSockets to access local hardware features of a device). Its design has also been informed by contributors’ experiences using other existing IoT protocols and APIs.

So how does it work..?

Opening a Connection

On the Web of Things, a connected device or “Thing” is described by a Thing Description, which is a piece of JSON metadata that describes a device and its capabilities. The Thing Description contains lists of “properties”, “actions” and “events” (types of “interaction affordances“) that the Thing exposes. Each affordance is given a name, data schemas which describe the format of any input and output data, and “forms” which describe how to communicate with them. A form contains a URL endpoint, a list of operations that endpoint supports (e.g. readproperty, invokeaction or subscribeevent), and any other metadata needed to carry out those operations.

To open a connection with a Thing using the Web Thing Protocol, a Consumer (e.g. a web app, native app or cloud service) looks for a form inside an interaction affordance in a Thing Description which has a href member set to a WebSocket URL (i.e. a URL with the ws:// or wss:// URI scheme), and a subprotocol member set to the value "webthingprotocol".

For example, the fragment of a Thing Description below shows the description of a property called “on”, which has a type of “boolean” (i.e. true or false), the URL endpoint "wss://myweblamp.io/", and supports the readproperty, writeproperty, observeproperty and unobserveproperty operations.

"properties": {
    "on": {
      "type": "boolean",
      "title": "On/Off",
      "description": "Whether the lamp is turned on",
      "forms": [
        {
          "href": "wss://myweblamp.io/",
          "op": [
            "readproperty",
            "writeproperty",
            "observeproperty",
            "unobserveproperty"
          ],
          "subprotocol": "webthingprotocol"
        }
      ]
    }
}

To connect to this Thing to carry out an operation on the “on” property, a Consumer would open a WebSocket using the endpoint URL, requesting the use of the webthingprotocol sub-protocol.

Most programming languages already have a WebSocket implementation which makes this easy to do, for example in JavaScript you can use the built-in WebSocket API to open a connection:

const socket = new WebSocket('wss://myweblamp.io/', 'webthingprotocol');

Behind the scenes the WebSocket implementation carries out a special protocol handshake where it asks to upgrade a standard HTTP request to a persistent WebSocket connection, and negotiates what sub-protocol to use.

When a Thing is using the Web Thing Protocol, all interaction affordances of a Thing can share the same WebSocket URL. The specification says that Consumers should re-use a WebSocket connection for all affordances of a Thing, or even multiple Things, which share the same WebSocket URL. This helps to reduce the number of TCP sockets that a Consumer needs to keep open at any one time.

Sending and Receiving Messages

Once a connection has been opened with a Thing, a Consumer can start sending messages to it.

In the Web Thing Protocol, every message is a JSON object. Messages contain some common members such as:

  • thingID – The URI identifying the Thing being communicated with
  • messageID – A UUID for the current message, provided by the sender of the message
  • messageType – One of request (sent from Consumer ➡ Thing), response (sent from Thing ➡ Consumer in response to a request), or notification (pushed from Thing ➡ Consumer)
  • operation – The name of the WoT operation being carried out (e.g. readproperty, invokeaction, subscribeproperty)
  • correllationID – An optional UUID provided by the Consumer, which the Thing must then also provide in response or notification messages relating to the same operation

Messages may also contain other members depending on the type of operation, of which there are some examples in the sections below.

Each operation has a specific lifecycle, which usually consists of either a request followed by a response, or a request followed by a response and then one or more notifications.

Messages are sent to the Thing following the WebSocket protocol, with the JSON object serialised as a string. In JavaScript the WebSocket API makes this easy to do, e.g.:

const request = {
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "request",
  "operation": "readproperty",
  "name": "on",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}
socket.send(request.toString());

In order to listen to responses from the Thing, in JavaScript the Consumer would register an event listener for a “message” event on the WebSocket object. The response can then be parsed from a string into a JSON object.

socket.addEventListener("message", (event) => {
  console.log("Message from Thing ", event.data);
  const response = JSON.parse(event.data);
  ...
});

Reading and Writing Properties

Things can have “properties” which represent the physical state of a device, such as an on/off state, a temperature value, or brightness value.

To read a property of a Thing, a Consumer sends a request message specifying the readproperty operation and the name of the property to read, e.g.

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c370da58-69ae-4e83-bb5a-ac6cfb2fed54",
  "messageType": "request",
  "operation": "readproperty",
  "name": "on",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

The Thing then responds with a message containing the value of the property, with a type and format conforming to the data schema of the property in the Thing Description e.g.:

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "79057736-3e0e-4dc3-b139-a33051901ee2",
  "messageType": "response",
  "operation": "readproperty",
  "name": "on",
  "value": true,
  "timestamp": "2024-01-13T23:20:50.52Z",
  "correlationID": "5afb752f-8be0-4a3c-8108-1327a6009cbd"
}

Similarly, to write a property of a Thing a Consumer would send a request message specifying the writeproperty operation and the name and value of the property to write, e.g.

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "97d22676-6d45-4435-aef5-dd87467a0c44",
  "messageType": "response",
  "operation": "writeproperty",
  "name": "on",
  "value": true,
  "correlationID": "f6cf46a8-9c96-437e-8b53-925b7679a990"
}

The Thing then responds, echoing back the value that was set, e.g.

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "db25fe4f-bee8-43a7-8ff0-3a1ff6e620b0",
  "messageType": "response",
  "operation": "writeproperty",
  "name": "on",
  "value": true,
  "timestamp": "2024-01-13T23:20:50.52Z",
  "correlationID": "f6cf46a8-9c96-437e-8b53-925b7679a990"
}

Invoking Actions

As well as properties, Things can have “actions”, which are functions that can be carried out on a device. Actions are used when the setting of a property alone is not sufficient to affect a required change in state, e.g. to describe a function which takes a period of time to complete or has a different outcome based on provided arguments or current state.

To invoke an action on a Thing a Consumer sends a request message specifying the invokeaction operation, the the name of the action to be invoked, and optional input data conforming to the input data schema specified in the Thing Description, e.g.

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "ff29aac5-062a-4583-9044-be2d45d6ad57",
  "messageType": "request",
  "operation": "invokeaction",
  "name": "fade",
  "input": {
    "level": 100,
    "duration": 5
  },
  "correlationID": "50d5f441-cb07-4513-80b4-cd062cddc1e0"
}

There are two types of responses to an invokeaction request – a synchronous response which includes the output (if any) of the action directly in the response (conforming to the output data schema in the Thing Description), or an asynchronous response which provides an actionID which can then be used to query or cancel the status of the action using follow-up operations. Below is an example of the simpler synchronous response:

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "e47c3727-d68b-4284-a2cc-5883d8fa43a4",
  "messageType": "response",
  "operation": "invokeaction",
  "name": "fade",
  "output": true,
  "timestamp": "2025-09-03T18:14:55.541Z",
  "correlationID": "50d5f441-cb07-4513-80b4-cd062cddc1e0"
}

Asynchronous action responses may be used for longer running actions, or where multiple instances of an action are invoked concurrently or in a queue (e.g. a printer queue).

Subscribing to Events

In addition to properties and actions, Things may have “events” which are emitted by a device that are not just a change in the value of a property, e.g. if a device is overheating or is about to reboot.

To subscribe to an event a Consumer sends a request message to a Thing specifying the subscribeevent operation and the name of the event to be subscribed to, e.g.

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "c347b27b-f567-4faf-b9b7-4c9e577b10fa",
  "messageType": "request",
  "operation": "subscribeevent",
  "name": "overheated",
  "correlationID": "206a6935-5978-47a5-a327-1ce1c656728b"
}

Once an event subscription has been registered successfully, the Thing then responds with a response message confirming the name of the event that has been subscribed to, e.g.

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "cf13d49b-abe8-45bc-8a3c-b4df9d892366",
  "messageType": "response",
  "operation": "subscribeevent",
  "name": "overheated",
  "correlationID": "206a6935-5978-47a5-a327-1ce1c656728b"
}

Whilst an event subscription is active, whenever an event of that name is emitted by the device, the Thing sends a notification message to the Consumer containing the name of the event that occurred, and an optional data payload which confirms to the data schema defined for that event in the Thing Description, e.g.

{
  "thingID": "https://mythingserver.com/things/mylamp1",
  "messageID": "b15e2e3f-c8b7-4a76-81c3-0f110edf51ca",
  "messageType": "notification",
  "operation": "subscribeproperty",
  "name": "overheated",
  "data": 90,
  "timestamp": "2025-10-08T11:15:53.376Z",
  "correlationID": "206a6935-5978-47a5-a327-1ce1c656728b"
}

Other Operations

The above are just a few of the 18 different operations defined in the Web Thing Protocol specification. Other operations include observing and unobserving properties, querying and cancelling actions, unsubscribing from events, and various batch operations which act on multiple interaction affordances at once.

Next Steps

The Web Thing Protocol is still very much in the early stages, being incubated in the Web Thing Protocol Community Group before hopefully joining a standards track at the W3C (or IETF) to be fully standardised.

Today the Web Thing Protocol Community Group is sending out a call for implementations of the Web Thing Protocol, so that we can put it through its paces in the real world and improve its design through feedback based on real implementation experience and interoperability testing.

One of those implementations will be the WebThings open source project, where the Web Thing Protocol is a critical part of my vision of building a smart building operating system using web technologies.

There’s a lot more we could do to improve the Web Thing Protocol WebSocket sub-protocol, e.g. by adding features like rate-limiting, traceability and quality of service, but potentially also lots of refinements based on implementation feedback.

The charter of the Web Thing Protocol Community Group also covers defining an HTTP sub-protocol, and evaluating the need for other potential Web of Things sub-protocols.

Anyone can join a W3C Community Group for free, so please join us on the Web Thing Protocol Community Group to further refine this powerful new Web of Things protocol.

You can read the latest draft of the specification, subscribe to our public mailing list, file issues on GitHub and chat with us in the #web-thing-protocol channel on the Web of Things Community Discord server.

As with all W3C specifications the Web Thing Protocol is a royalty free open standard which anyone is free to use, so we can’t wait to see what you do with it!

My Vision of a Smart Building Operating System

I have a vision of a smart building operating system.

A whole building operating system, built on web technologies, which weaves together every sensor, actuator and human-computer interface in a building into a seamless user experience.

Smart Building OS User Interface

This vision builds on everything I’ve learnt from working on Webian, Firefox OS and Mozilla WebThings.

Rather than a single desktop or mobile computer, the OS is designed to operate over many different pieces of hardware spread throughout a building.

Hub, Terminals and Devices

Every terminal is a web client, every device has a URL and a hub acts as a central web server.

OS Architecture

Hub

The hub is a central computer for the building.

Hub

This central computer is inspired by the “ship computer” trope and similar ideas often portrayed in science fiction (e.g. the duotronic ship computer from Star Trek, Holly from Red Dwarf, HAL 9000 from 2001: A Space Odyssey, Eddy from The Hitchkiker’s Guide to the Galaxy, KITT from Knight Rider or The Great Machine from Forbidden Planet1).

It acts as a central hub for monitoring, controlling and automating a building. Think of it as a permanent electrical appliance, like a boiler or a fuse box, but for information rather than heat or electricity.

As a long term vision, imagine the hub hosting a semi-autonomous software agent with a conversational voice interface and an interactive 3D model of the building. As a starting point, a server for hosting 2D graphical web applications.

Hub Architecture

Fundamentally the hub is a web server which hosts web applications and stores user data. Each application is isolated inside its own sandboxed container which includes all of the dependencies the application needs and can be atomically updated. Both the host operating system and applications receive automatic over-the-air updates. A reverse proxy sits in front of all the applications and routes HTTP requests to the correct application.

Hub UI

The first of those applications, the “killer app” and default home page of the OS, provides a unified web interface for monitoring, controlling and automating all of the connected devices in the building. It does this by bridging a range of different smart home protocols and commercial building management systems to a single standardised Web of Things API using the Web Thing Protocol, which is then consumed by the web front end. Third party apps and services can also request access to this API.

Terminals

Terminal

“A computer terminal is an interface where the mind and body can connect with the universe and move bits of it about.” — Douglas Adams, Mostly Harmless

Terminals could be a smart display or smart TV (think tabs, pads and boards), or even a smart speaker or VR headset. These are devices which provide a human-computer interface through vision, audio or touch.

Terminals act as web user agents which enable users to interact with the web applications hosted on the hub, but also discover and use installable web applications from anywhere on the World Wide Web.

Terminal Architecture

On the front end is a shell for discovering and using web applications. On the back end are core services which provide the shell with access to hardware such as network adapters, displays, cameras, speakers and microphones.

Terminal UI

The shell communicates with the core services using the Web Thing Protocol. This also means that terminals can act as web things themselves, so that they can be remotely controlled over the network.

Devices

Devices

Devices are the sensors and actuators which interface with the physical world. That could be a motion sensor, door sensor, smoke alarm, smart socket or a light bulb for example.

Devices may natively be web things, or may be bridged to the Web of Things by the hub, from a range of different protocols like Zigbee, Z-Wave, HomeKit, Matter, BACnet and Modbus.

Either way every device has a URL on the Web of Things which acts as a globally unique identifier and resolves to a machine readable WoT Thing Description. The Thing Description describes the capabilities of the device in a machine readable format and provides URL endpoints with which to communicate with it.

Implementation

Interested? Come and join us in the WebThings open source community where Krellian are building the key components which will eventually make up “Krellian OS”, including WebThings Gateway and WebThings Shell.


  1. The name Krellian is actually inspired by the 1956 science-fiction film Forbidden Planet. Krellian meaning “of or belonging to the Krell”. The Krell were an ancient alien race who created “The Great Machine” on Altair IV, a vast underground machine controlled by thought and capable of monitoring and affecting change throughout the whole planet. The machine continued to function autonomously for thousands of years after the Krell themselves went extinct. It serves as both an inspiration and a warning. ↩︎

A New Future for the WebThings IoT Platform


Originally posted on Medium.

After four years of incubation at Mozilla, Krellian is proud to become the new commercial sponsor of WebThings, an open platform for monitoring and controlling devices over the web.

Today we are announcing the release of WebThings Gateway 1.0 and setting out a vision for the future of the WebThings project.

WebThings

WebThings is an open source implementation of emerging W3C Web of Things standards and consists of three main components:

  • WebThings Gateway — a software distribution for smart home gateways which enables users to directly monitor and control their home over the web, without a middleman
  • WebThings Framework — a collection of re-usable software components to help developers build their own web things which directly expose the Web Thing Protocol
  • WebThings Cloud — a collection of cloud services for securely deploying connected devices and remotely managing them over the internet

Flying the Nest

Following a company restructuring in August, Mozilla was looking for a new home for the WebThings community to continue their work.

Having co-founded the project whilst working at Mozilla, I joined discussions with two of my former colleagues Michael Stegeman and David Bryant about spinning out WebThings as an independent open source project. We worked with Mozilla on an agreement to transition the project to a new community-run home at webthings.io, and have spent the last three months working together on that transition.

WebThings Gateway 1.0

Today marks the public release of WebThings Gateway 1.0 and the formal transition of the WebThings platform to its new home at webthings.io. Going forward, Krellian will be sponsoring the new WebThings website and replacement cloud infrastructure, to continue to provide automatic software updates and a secure remote access service for WebThings gateways around the world.

You can read more about the 1.0 release and the transition of existing gateways to the new infrastructure on the Mozilla Hacks blog.

Krellian & WebThings

Krellian’s mission is to “extend the World Wide Web into physical spaces to make our built environment smarter, safer and more sustainable.” WebThings provides an ideal open source platform, built on web standards, to help achieve that mission.

In the short term Krellian will be leveraging the WebThings Cloud remote access service as part of our new digital signage platform. In the longer term we plan to explore other enterprise use cases for the WebThings platform, to help make buildings smarter, safer and more sustainable.

These commercial applications of WebThings will help provide revenue streams to support the long term sustainability of the open source project and allow it to continue to develop and grow.

The WebThings Community

Krellian highly values the thriving community who have supported the WebThings project over the last four years. From hackers and makers to educators and hobbyists, the community have been pivotal in building, testing and promoting WebThings around the world.

Amongst their achievements is the translation of WebThings Gateway into 34 spoken languages, the creation of over a hundred gateway add-ons and the building of countless DIY projects in a dozen different programming languages. Community members have contributed their time and effort to help build and promote WebThings and support other members in using it in thousands of private smart homes around the world.

We intend to support the community to continue with their great work, and have put in place an open governance structure to distribute decision making and foster leadership amongst the global WebThings community.

Future Roadmap

The following are some ideas about where to take the platform next, but we’d also very much like to hear from the community about what they would like to see from the project going forward.

W3C Compliance

WebThings has been developed in parallel with, and has contributed to, the standardisation of the Web of Things at the W3C. Since the last release of WebThings Gateway in April, the W3C Thing Description specification has reached “recommendation” status and is now an international standard.

We’d like to work towards making WebThings compliant with this standard, as there are still a remaining number of differences between the W3C and Mozilla specifications. In order to fill in the gaps between Mozilla’s Web Thing API and the W3C’s Thing Description standard, we plan to continue to lead work on standardising the Web Thing Protocol as a concrete protocol for communicating with devices over the web.

Production Gateway OS

The main WebThings Gateway software image is currently built on top of the Raspbian Linux distribution. This served the project well for its initial target of DIY smart home users, using the popular Raspberry Pi single board computer.

As the platform matures, we would like to explore a more production-quality IoT operating system like Ubuntu Core or Balena OS on which to base the WebThings Gateway distribution.

This will have the following benefits:

  1. A smaller footprint, reducing the minimum system requirements for running the gateway
  2. Enabling the targeting of a wider range of hardware for consumer and enterprise use cases
  3. Better security, through containerisation and automatic software updates for the underlying operating system

WebThings Controller

There was previously a project to build controller software for WebThings, to run on a controller device such as a smart speaker or smart display. The initial prototype was built on Android Things, but was discontinued when Google locked down the Android Things platform to specific OEMs and introduced restrictions on how it could be used.

Krellian would like to explore new controller software built on our open source Krellian Kiosk web runtime, which could allow for touch and voice input. This software would be designed so that it could either run on the same device as the gateway software, or on a separate controller device.

WebThings App

A native WebThings mobile app could act as a general purpose Web of Things client. This could potentially:

  1. Help to streamline the setup process of a WebThings Gateway
  2. Act as a client for native web things which don’t need a gateway
  3. Help with the standardisation process by providing a user friendly reference implementation of a Web of Things client

WebThings Cloud

Finally, we would like to explore expanding the WebThings Cloud offering. This could include an online dashboard for monitoring and controlling devices across multiple premises, and cloud to cloud integrations with other IoT platforms and voice assistants.


We’re excited about this new chapter in the WebThings story, and look forward to working closely with the community on our vision of a connected world where technology is seamlessly woven into the spaces around us and improves the lives of those who use it.

You can find out more about WebThings at its new home of webthings.io, follow @WebThingsIO on Twitter and sign up for the email newsletter to keep up to date with all the latest news.

Introducing Krellian — Interactive Digital Signage

Orignally posted on Medium.

For the last six weeks I’ve been enrolled in YCombinator’s Startup School, working towards the launch of a new technology startup.

Today I’m excited to introduce Krellian, a software platform for interactive digital signage, built on web standards.

If you walk around any large town or city today you’ll notice that you’re surrounded by screens. Digital billboards, information kiosks, self-service kiosks, interactive exhibits, digital menus and departure boards.

A lot of those screens are running outdated consumer-grade operating systems and proprietary content runtimes. They’re unreliable, inefficient and insecure. How many times have you seen a digital billboard that’s gone dark, departure boards with a Windows error message on the screen or even ATMs with a blue screen of death?

With Krellian, I am building a software platform for interactive digital signage, built on web standards. A simple, reliable web-based operating system and a secure cloud service for monitoring, controlling and deploying content to connected displays over the internet.

Krellian’s products will build on everything I have learnt over the last decade working on Webian, Firefox OS and Mozilla WebThings. I believe the web technologies I’ve helped standardise around installable web apps and the Web of Things could have enormous potential if applied to the digital signage market.

For example, a purpose-built operating system for displaying modern web content, which can be remotely managed over the internet, could significantly reduce content creation costs and technician call-out fees.

I’m also delighted that Krellian has been accepted onto the High Potential Startups programme, powered by the North East Local Enterprise Partnership. Over the next six months we’ll be working together to better understand customer needs, bring products to market and ultimately grow the business to create more high-tech jobs in the North East of England.

Are you interested in providing in-person digital experiences to your customers? Perhaps you work in advertising, hospitality, healthcare, museums, travel, retail or entertainment? Or do you sell digital signage to your own customers? I’d love to hear more about your needs and the problems you are trying to solve.

Register your interest today at krellian.com and follow Krellian on Twitter and Facebook.

The Legacy of Firefox OS

Originally posted on Medium.

In 2017 I wrote about the story of Firefox OS, from the birth of the B2G (Boot to Gecko) open source software project as an empty GitHub repository in 2011, to shipping as Firefox OS on five million devices worldwide, and then eventually being “transitioned” to the community in 2016.

In the two years or so since Mozilla announced the end of Firefox OS as a Mozilla-run project, the B2G source code has found its way into a surprising number of commercial products. In fact since Mozilla moved on from Firefox OS, its derivatives have shipped on an order of magnitude more devices than during its entire time under Mozilla’s leadership and it has gone on to form the basis of the third largest and fastest growing mobile operating system in the world.

In this blog post I take a look at the legacy of the B2G project, some of the devices you can buy today running B2G code, and other related efforts which still continue inside and outside Mozilla. I will cover KaiOS, Panasonic’s My Home Screen, Servonk, Webian, Astian OS, IceWolf OS and the latest in Mozilla Research & Development. I’ll then explain why I think there’s a strong argument for Mozilla to take a more active role in supporting downstream users of Gecko in future, and even the B2G codebase itself.

KaiOS

Probably the most notable fork of the B2G source code is KaiOS from KaiOS Technologies. It was started in 2016 with a team of 30 people and has since grown to have offices in France, Germany, Taiwan, India, Brazil, Hong Kong and mainland China in addition to its headquarters in the US.

KaiOS logo

KaiOS has a UI optimised for non-touch “smart feature phones” with physical keypads and small colour screens. That includes the hugely popular JioPhone in India, HMD’s nostalgic re-launch of the Nokia 8110, and the recently announced $7 WizPhone in Indonesia. With these devices KaiOS is very much continuing the Firefox OS vision of “connecting the next billion”, with low end devices aimed mainly at emerging markets.

KaiOS Technologies CEO Sebastien Codeville with KaiOS devices at CES 2019

JioPhone

The JioPhone has been extremely popular in India since its launch in July 2017, in part due to being given away for free, with a security deposit of ₹1500 ($21 USD) which can be refunded by returning the device to Jio stores after three years.

The JioPhone 2 was released in July 2018 at a price of ₹2,999 ($42 USD). It has a full QWERTY keyboard and has apps for Facebook, WhatsApp and YouTube.

JioPhone & JioPhone 2

Nokia 8110

The Nokia 8110 is available internationally, including here in the UK with a recommended retail price of £69.99 ($89) unlocked. It’s available from many popular retailers and mobile network providers including Carphone Warehouse, Currys, John Lewis, Amazon, Vodafone, EE, GiffGaff and BT.

Nokia 8110

The Nokia 8110 is a very neat little device with an intuitive UI reminiscent of Symbian, but with a modern twist. It’s surprising how much of the web actually works on such a small non-touch screen, though it’s a very fiddly experience if you’re used to a touch screen smartphone.

The presence of Google Assistant on feature phones at this price point is remarkable and it works surprisingly well. To implement Google Assistant for KaiOS, Google have created a custom HTML5 app packaged for the mozApp app runtime KaiOS inherited from B2G.

Nokia 8110 running Google Assistant

When I first bought the Nokia 8110 the bundled app store had a grand total of eight apps in it and there’s no way to install web apps from the browser. Since then it has grown a little, but only to about 30 apps and most of them are games. (The JioPhone comes with its own app store called JioStore and not all apps are available on all KaiOS devices, e.g. WhatsApp.)

WizPhone WP006

The WizPhone WP006 was recently announced in Indonesia in partnership with Google and Alfamart and can be purchased from vending machines for only IDR99,000 ($7).

WizPhone WP006

Other KaiOS Devices

Other devices running KaiOS include:

Rapid Growth

By the end of 2017 KaiOS had shipped on 30 million phones in the U.S., Canada, and India via partnerships with 20 carriers.

By June 2018 it had reached 40 million devices and Google made a $22m investment in the company. As part of that agreement KaiOS Technologies agreed to bundle Google services, including Google Assistant.

As of the end of 2018 it has reached over 50 million devices across North America, Asia, Europe, and Africa.

According to StatCounter, as of the end of 2018 KaiOS was the third largest mobile operating system in the world after Android and iOS, with 1.13% market share worldwide.

Worldwide mobile operating system market share, December 2018. Source: StatCounter

In India it has 4.55% market share, beating Apple’s iOS into second place.

India mobile operating system market share, December 2018. Source: StatCounter

Strategy Analytics are forecasting that KaiOS device shipments will grow 50% year on year in 2019, with more than 30% of those shipments coming from non-India markets such as Africa, South East Asia and Latin America. This, they say, will make it the “world’s fastest growing major platform”.

Panasonic My Home Screen

KaiOS is not the only fork of B2G. Panasonic was the first hardware vendor to create Firefox OS based smart TVs, which received great reviews for their user friendly design when they were released in 2015. When Mozilla stopped work on Firefox OS, Panasonic continued development of the software as My Home Screen 2.0 and later My Home Screen 3.0.

Panasonic 65″ OLED 4K Smart TV (TX-65FZ802B) running My Home Screen 3.0

As of 2019 most Panasonic smart TVs are still running this B2G fork. There are localised variations being sold running My Home Screen all over the world including in North America, Latin America, Europe, Middle East, Africa, Asia and Oceania. They range from the low end 24″ LED TX-24FS500B in the UK for £279 ($359) to the very high end 77″ OLED TH-77EZ1000H in Hong Kong for HK$139,000 ($17,700).

A notable exception is the US, where Panasonic recently stopped selling TVs due to difficult market conditions. But here in the UK you’ll come across these smart TVs when walking into most popular high street electronics retailers like John Lewis, Currys and Argos. Some listings on online stores even still refer to these TVs as “powered by Firefox OS”, despite the official change in branding.

My Home Screen 3.0 is probably a bit of a Frankenstein of web and native code under the hood at this point, with support for a wide range of live and on-demand video platforms, but the user interface has remained largely the same.

Panasonic 49″ 4K TV (TX-49FX750B) running My Home Screen 3.0

I have Panasonic TVs running both the Firefox OS branded and My Home Screen 3.0 branded software and while the browser has barely changed, app development has become much more locked down.

With the latest “HTML v3 SDK” (based on the “Hybrid broadcast broadband TV” standard), developer accounts are basically invitation only. I applied for an account and Panasonic first wanted to know what app I was developing so they could decide whether they wanted it in their store.

This is quite a contrast from the original Firefox OS TVs where anyone could enable developer mode and and anyone could submit an app to the Firefox Marketplace.

Still, with most of the major apps like Netflix, YouTube and Amazon Prime Video already supported, My Home Screen continues to provide a slick and compelling user experience for smart TVs.

In total Panasonic sells approximately 7 million TVs per year worldwide.

Servonk

In January 2018 the tech lead of KaiOS, Fabrice Desré (previously tech lead of B2G at Mozilla), started an open source project called Servonk. Servonk is kind of a “Boot to Servo” like the original Boot to Gecko project, but based on Mozilla’s experimental Servo rendering engine.

Servonk running in an emulator
Servonk running on an Android device

Servonk takes advantage of the cutting edge features of Servo, is largely built on the Rust programming language and roughly follows the slimmed down architecture we started to transition to towards the end of the B2G project.

Whilst a very cool open source project, Servonk is unlikely to ship on commercial devices any time soon, although there are some early discussions around shipping a version of the Necunos NC_1 (community edition) with B2G or Servonk pre-loaded.

Servo is still a very experimental browser engine which can’t render the majority of web pages on the web today. Inside Mozilla, work on Servo has recently mostly been focused on VR applications and moving parts of Servo over to Gecko as part of the Quantum project. Servo itself is currently still a research project.

According to the README, the main motivation of Servonk is to scratch a personal itch to build an alternative open source OS, and encourage contributions to Servo from outside Mozilla. If you join the (still surprisingly busy) #b2g channel on irc.mozilla.org, you’ll find that most recent discussions are around Servonk.

Webian

My own Webian project predated B2G but still continues to crawl along, learning from many of the lessons of Firefox OS and using the web standards it helped create. Webian is an operating system dedicated to running standards-based web apps.

The desktop version is currently built on the experimental Quantum Browser Runtime (qbrt) from Mozilla and the touch version is based on Android Things and GeckoView.

Webian Desktop 0.3
Webian Touch
Webian Touch running on a RasPad

The current approach I’m using for touch-based devices is to implement the system UI as an Android app which runs on top of Android Things. Android Things is basically a special version of Android which only runs a single app (no default system UI like a status bar or task manager is included), enabling device makers to have full control over the system UI.

Android Things has been used to build a range of commercial “smart displays” from Lenovo, LG and Samsung (though notably not Google’s own Home Hub smart display which is based on the more lightweight Google Cast platform). I’m using Android Things to build my own browser-based OS using Gecko via GeckoView with a native system UI in written in Java. The idea is that standard web apps can then be discovered and installed from the web using their Web App Manifest and Service Workers where available.

The upside of building on Android Things is that Google maintains the underlying OS and Android APIs, while I have full control over the system UI and can use Gecko via its existing well-supported Android widget layer. The downside is that it can probably never perform as well as B2G could have done on the same hardware because it requires that additional Java layer, the removal of which was one of B2G’s biggest benefits. And of course Android itself is controlled by Google.

Astian OS

Astian OS Logo

Astian OS calls itself a successor to Firefox OS, but it’s more of a spiritual fork than an actual derivative. It’s really a desktop Linux distribution with a love for web apps, based on Devuan (a fork of Debian).

Astian OS Launcher

IceWolf OS

IceWolf Logo

Originally known as Plánium OS, IceWolf OS (see what they did there?) is an open source project started in Brazil. According to its Twitter profile, IceWolf OS was inspired by Firefox OS and is built on web technologies.

After experiments with NodeJS & Chromium, Electron and NW.js, the project leader Patrick A Lima is now making an effort to move back to Gecko, along with its new Firefox OS inspired name. Unfortunately (as I have experienced myself), Gecko is much harder to embed due to the monolithic nature of its architecture.

Plánium OS

Mozilla Projects

My current job is working in Research & Development in the Emerging Technologies department of Mozilla. Many of the current projects in Emerging Technologies have their origins in Firefox OS.

The WebVR effort culminating in the Firefox Reality browser was first started as a potential new form factor for Firefox OS in VR headsets.

Firefox Reality

DeepSpeech was born as part of the Vaani voice assistant for Firefox OS, and may eventually be used in a voice browser called Firefox Listen.

Firefox Listen on Pocket

The current Mozilla IoT effort includes some early work on smart displays using Android Things and GeckoView.

Things Controller by Mozilla

Legacy

In the five years under Mozilla’s leadership around five million devices were shipped running Firefox OS. Since then over 50 million smart feature phones and millions of smart TVs have shipped running B2G code, and several new software projects have been derived from or inspired by it.

According to StatCounter, on mobile there are now more users of the KaiOS browser than Firefox (1.13% vs. 0.34%).

Mobile Browser Market Share, December 2018. Source: StatCounter

Their numbers show that KaiOS browser market share overtook Firefox on mobile some time in April 2018 and shows no signs of stopping.

Worldwide Mobile Browser Market Share 2017–2018. Source: StatCounter

With the current rate of growth of KaiOS and corresponding decline of Firefox market share, if KaiOS sticks with Gecko and Mozilla doesn’t manage to turn things around, it’s feasible that KaiOS could eventually become the biggest consumer of Gecko altogether.

But KaiOS is currently running a very old patched version of Gecko 48 and Panasonic’s My Home Screen 3.0 is running Gecko 34, while the latest version of Gecko in Firefox is 64.

KaiOS running Gecko 48
Panasonic My Home Screen 3.0 running Gecko 34

KaiOS Technologies and Panasonic are being prevented from upgrading to a newer version of Gecko because Mozilla removed all B2G code from the mozilla-central code repository, including the Gonk widget layer. Since then there have been significant architectural changes to Gecko as part of the Quantum project which make it very difficult for downstream projects to port B2G to the latest version.

This unfortunately means that the legacy of Firefox OS is currently tens of millions of phones and TVs across the world running an out of date browser engine which can probably never be updated. This potentially puts the users of those devices at risk, but also holds back the web platform as a whole.

The Future

So what will these companies do next? It’s very likely that without support from Mozilla, KaiOS will be forced to migrate from Gecko to Google’s Blink engine. In fact I understand there’s already work under way to do this, with support from the Google Chrome team.

The resulting architecture could look a lot like an Android/Chrome OS hybrid, something which has been speculated about for years. Panasonic could then use that same codebase, or just move to another software stack altogether.

A port of B2G to Blink is a huge undertaking, but if it comes to fruition it would further contribute to the WebKit/Blink monoculture we’re increasingly seeing on the web platform today with Chrome, Safari, Opera, Samsung Internet, Edge and Brave.

With both Opera and Microsoft having given up on their own browser engines in favour of building Chromium-based browsers, Mozilla really have the last ground-up alternative implementation of the web platform. This is hugely important because without multiple interoperable implementations, there can be no web standards.

There are ongoing efforts by Mozilla to target new Android-based platforms with Gecko-based browser apps on FireTV, Amazon Echo Show and VR headsets, as well as specialised browsers aimed at emerging markets. But while the rate of decline of Firefox market share has been slowing in recent times, with competitors converging on the Chromium code base and overall Mozilla market share still shrinking, the future of Gecko and the diversity and health of the web platform is looking a little bleak.

Conclusions

Since Mozilla discontinued Firefox OS, B2G source code has found its way into a surprising number of commercial products and now forms the basis of the third largest and fastest growing mobile operating system in the world. However, those devices are currently running out of date versions of Gecko, use locked down packaged app stores, are developed behind closed doors, and are arguably not a great showcase of the open web in the way B2G was originally intended to be.

I don’t necessarily think that smart feature phones and smart TVs would have been a great success for Mozilla had they pursued those product directions themselves with Firefox OS. Nor are those form factors necessarily the best showcase of the capabilities of the open web. However, the unexpected continuing legacy of B2G does serve to demonstrate just how much value still existed in what has proven to be a very versatile and scalable platform.

From low end $7 phones with tiny 2.4″ screens to high end $17,000 TVs with 77″ 4K screens, B2G has continued to perform.

Smart feature phone to Smart TV. Sources: KaiOS Technologies & Panasonic

In my personal opinion, Mozilla should seriously consider working with KaiOS Technologies to re-introduce the Gonk widget layer to mozilla-central, and re-claim some ownership over the B2G codebase. KaiOS could then use a slimmed down B2G architecture with local system services as had been the plan with the B2G Transition Project, and adopt modern web standards for installable web apps.

This would enable KaiOS to continue running an up-to-date version of Gecko on millions of devices rather than move to Blink, which many of their employees and partners might actually prefer, and could significantly contribute to the diversity and health of the web. I also believe this could open up enormous future opportunities for new product areas for Mozilla as well.

There are new form factors emerging today such as smart displays (Amazon Echo Show, Lenovo Smart Display, Google Home Hub) and tablet hybrid devices (Pixel Slate, ASUS Chromebook Flip) which could be a great fit for B2G and the open web.

Lenovo Smart Display. Source: Stacey on IoT
Pixel Slate. Source: Wired

With continuing explorations in voice, mixed reality and IoT there are many new potential product areas for Mozilla which could benefit from the B2G software stack.

Smart displays, for example, could be the ideal home for a voice-first trusted personal agent, consistent with Mozilla’s new three year strategy. Whilst early smart display products are being built on Google’s Android Things platform and that could be an option for Mozilla as well, even Google itself used Google Cast for its own Google Home Hub product, a more lightweight technology stack much more similar to B2G. B2G could give Mozilla and partners an edge in this market, with a platform less controlled by Google.

There could be other use cases for B2G in VR headsets, the smart home and countless connected devices we have yet to dream up.

Personally I would love to see Mozilla emerge from the comfort zone I fear it has retreated into in recent years, shipping Firefox browsers on others’ platforms where the web is always a second class citizen. I’d like to see some new big bets in products and partnerships where the web platform is allowed to take centre stage once again, where Mozilla isn’t constrained by the rules of other platforms.

The Web is the Platform, MWC 2012. Source: Madhava Enros

The web is the platform. Let’s allow it to shine.

Building the Web of Things

Originally posted on Mozilla Hacks.

Mozilla is working to create a Web of Things framework of software and services that can bridge the communication gap between connected devices. By providing these devices with web URLs and a standardized data model and API, we are moving towards a more decentralized Internet of Things that is safe, open and interoperable.

The Internet and the World Wide Web are built on open standards which are decentralized by design, with anyone free to implement those standards and connect to the network without the need for a central point of control. This has resulted in the explosive growth of hundreds of millions of personal computers and billions of smartphones which can all talk to each other over a single global network.

As technology advances from personal computers and smartphones to a world where everything around us is connected to the Internet, new types of devices in our homes, cities, cars, clothes and even our bodies are going online every day.

The Internet of Things

The “Internet of Things” (IoT) is a term to describe how physical objects are being connected to the Internet so that they can be discovered, monitored, controlled or interacted with. Like any advancement in technology these innovations bring with them enormous new opportunities, but also new risks.

At Mozilla our mission is “to ensure the Internet is a global public resource, open and accessible to all. An Internet that truly puts people first, where individuals can shape their own experience and are empowered, safe and independent.”

This mission has never been more important than in a time when everything around us is being connected to the Internet. As new types of devices come online, they bring with them significant new challenges around security, privacy and interoperability.

Many of the new devices being connected to the Internet are insecure, do not receive software updates to fix vulnerabilities and raise new privacy questions around the collection, storage and use of large quantities of extremely personal data.

Additionally, most IoT devices today use proprietary vertical technology stacks which are built around a central point of control and which don’t always talk to each other. When they do talk to each other it requires per-vendor integrations to connect those systems together. There are efforts to create standards, but the landscape is extremely complex and there’s still not yet a single dominant model or market leader.

The Web of Things

Using the Internet of Things today is a lot like sharing information on the Internet before the World Wide Web existed. There were competing hypertext systems and proprietary GUIs, but the Internet lacked a unifying application layer protocol for sharing and linking information.

The “Web of Things” (WoT) is an effort to take the lessons learned from the World Wide Web and apply them to IoT. It’s about creating a decentralized Internet of Things by giving Things URLs on the web to make them linkable and discoverable, and defining a standard data model and APIs to make them interoperable.

The Web of Things is not just another vertical IoT technology stack to compete with existing platforms. It is intended as a unifying horizontal application layer to bridge together multiple underlying IoT protocols.

Rather than start from scratch, the Web of Things is built on existing, proven web standards like REST, HTTP, JSON, WebSockets and TLS. The Web of Things will also require new web standards. In particular, we think there is a need for a Web Thing Description format to describe things, a REST style Web Thing API to interact with them, and possibly a new generation of HTTP better optimised for IoT use cases and use by resource constrained devices.

The Web of Things is not just a Mozilla Initiative, there is already a well established Web of Things community and related standardization efforts at the IETF, W3C, OCF and OGC. Mozilla plans to be a participant in this community to help define new web standards and promote best practices around privacy, security and interoperability.

From this existing work three key integration patterns have emerged for connecting things to the web, defined by the point at which a Web of Things API is exposed to the Internet.

Direct Integration Pattern

The simplest pattern is the direct integration pattern where a device exposes a Web of Things API directly to the Internet. This is useful for relatively high powered devices which can support TCP/IP and HTTP and can be directly connected to the Internet (e.g. a WiFi camera). This pattern can be tricky for devices on a home network which may need to use NAT or TCP tunneling in order to traverse a firewall. It also more directly exposes the device to security threats from the Internet.

Gateway Integration Pattern

The gateway integration pattern is useful for resource-constrained devices which can’t run an HTTP server themselves and so use a gateway to bridge them to the web. This pattern is particularly useful for devices which have limited power or which use PAN network technologies like Bluetooth or ZigBee that don’t directly connect to the Internet (e.g. a battery powered door sensor). A gateway can also be used to bridge all kinds of existing IoT devices to the web.

Cloud Integration Pattern

In the cloud integration pattern the Web of Things API is exposed by a cloud server which acts as a gateway remotely and the device uses some other protocol to communicate with the server on the back end. This pattern is particularly useful for a large number of devices over a wide geographic area which need to be centrally co-ordinated (e.g. air pollution sensors).

Project Things by Mozilla

In the Emerging Technologies team at Mozilla we’re working on an experimental framework of software and services to help developers connect “things” to the web in a safe, secure and interoperable way.

Project Things will initially focus on developing three components:

  • Things Gateway — An open source implementation of a Web of Things gateway which helps bridge existing IoT devices to the web
  • Things Cloud — A collection of Mozilla-hosted cloud services to help manage a large number of IoT devices over a wide geographic area
  • Things Framework — Reusable software components to help create IoT devices which directly connect to the Web of Things

Things Gateway

Today we’re announcing the availability of a prototype of the first component of this system, the Things Gateway. We’ve made available a software image you can use to build your own Web of Things gateway using a Raspberry Pi.

So far this early prototype has the following features:

  • Easily discover the gateway on your local network
  • Choose a web address which connects your home to the Internet via a secure TLS tunnel requiring zero configuration on your home network
  • Create a username and password to authorize access to your gateway
  • Discover and connect commercially available ZigBee and Z-Wave smart plugs to the gateway
  • Turn those smart plugs on and off from a web app hosted on the gateway itself

/media/59542bdd7abe70aba71d213ff814ba64

We’re releasing this prototype very early on in its development so that hackers and makers can get their hands on the source code to build their own Web of Things gateway and contribute to the project from an early stage.

This initial prototype is implemented in JavaScript with a NodeJS web server, but we are exploring an adapter add-on system to allow developers to build their own Web of Things adapters using other programming languages like Rust in the future.

Web Thing API

Our goal in building this IoT framework is to lead by example in creating a Web of Things implementation which embodies Mozilla’s values and helps drive IoT standards around security, privacy and interoperability. The intention is not just to create a Mozilla IoT platform but an open source implementation of a Web of Things API which anyone is free to implement themselves using the programming language and operating system of their choice.

To this end, we have started working on a draft Web Thing API specification to eventually propose for standardization. This includes a simple but extensible Web Thing Description format with a default JSON encoding, and a REST + WebSockets Web Thing API. We hope this pragmatic approach will appeal to web developers and help turn them into WoT developers who can help realize our vision of a decentralized Internet of Things.

We encourage developers to experiment with using this draft API in real life use cases and provide feedback on how well it works so that we can improve it.

Get Involved

There are many ways you can contribute to this effort, some of which are:

  • Build a Web Thing — build your own IoT device which uses the Web Thing API
  • Create an adapter — Create an adapter to bridge an existing IoT protocol or device to the web
  • Hack on Project Things — Help us develop Mozilla’s Web of Things implementation

You can find out more at iot.mozilla.org and all of our source code is on GitHub. You can find us in #iot on irc.mozilla.org or on our public mailing list.

The Story of Firefox OS

Originally posted on Medium.

The Story of Firefox OS

Mobile World Congress, 2013

I remember at a team dinner once Mitchell Baker, Mozilla’s Chairwoman and “Chief Lizard Wrangler”, talked about the importance of storytelling. She talked about how telling stories in the open source software community helps us to reflect on shared experiences and learn from them.

Well, I’m Ben and I’m a Mozillian. I’m a Software Engineer who worked on the “Boot to Gecko” project full time for five years and I have a story to tell.

As an engineer on the project I don’t quite have the full picture when it comes to the high level decision making, financials and business partnerships. But I was involved in the project for a long period of time, longer in fact than any of its co-founders, and gained quite a lot of insight at the engineering, design and product levels.

So I’d like to tell you my version of the story of Firefox OS, from the birth of the Boot to Gecko open source software project as a mailing list post and an empty GitHub repository in 2011, through its commercial launch as the Firefox OS mobile operating system, right up until the “transition” of millions of lines of code to the community in 2016.

During this five year journey hundreds of members of the wider Mozilla community came together with a shared vision to disrupt the app ecosystem with the power of the open web. I’d like to reflect on our successes, our failures and the lessons we can learn from the experience of taking an open source browser based mobile operating system to market.

This is not a short version of the story, in fact it’s over 7,500 words long, so below is a summary of the key points in case you don’t make it to the end! Hopefully it goes without saying that these are just my personal opinions.

Summary

Biggest Achievements

  • Design — Designed a simple and fresh looking mobile OS with some innovative features like edge gestures for switching windows. Came up with some great designs for how a browser based OS could work, even if the vision was never fully realised.
  • Engineering — Built a mobile operating system from scratch, entirely in the open, and got it to market in less than two years. As far as I know no other team has ever done this. Got web content rendering very close to bare metal on mobile devices with a very lean technology stack, in many cases beating the performance of native code on equivalent hardware. Pushed the envelope of the web with 30 experimental new web APIs and helped create new web app trends.
  • Product — Successfully launched 20 devices in over 30 countries, mobilised the Mozilla community to help run launch parties and created slick branding and marketing campaigns. Sold the message that “the web is the platform”, even if we failed to live up to it.
  • Partnerships — Won unprecedented support from the mobile industry. Repeatedly stole the show at MWC, the world’s biggest mobile event, and got big telecommunications corporations on board with Mozilla’s mission, with competing companies working together towards common goals.

Biggest Mistakes

  • Design — Started out by imitating what already existed, not something simpler, unique and focused on the web. Assumed we could change direction later, which turned out to be harder than we thought.
  • Engineering — In a rush to get to market we imitated the app store model with packaged apps, adding to the problem we set out to solve. Lost focus on what makes the web the web (URLs). Too much focus on the client side rather than the server side of the web stack.
  • Product — After realising “open” on its own doesn’t sell, ultimately chose a strategy to compete mainly on price, which is just a race to the bottom. Suffered from a lack of product leadership and direction after the initial launch.
  • Partnerships — Treated carriers and OEMs as our customers with a tick box approach to feature prioritisation, lost sight of the needs of end users and the original mission. Failed to secure a license to distribute updates directly to users.

What I Would Do Differently Today

  • Design — Start out with a very simple browser based design with a focus on web content rather than try to recreate every feature that other operating systems have. Be ruthless about leaving features out and not even attempt to play catch up.
  • Engineering — Have a clear separation between “chrome” and web content rather than try to force the web to do things it isn’t suited to. Create device APIs using REST & WebSockets on the server side of the web stack rather than privileged JavaScript DOM APIs on the client side. Create a community curated directory of web apps on the web rather than an app store of submitted packaged apps.
  • Product — Not try to create the cheapest smartphone. Create a mid-range tablet (and later possibly a smart TV stick) with a focus on web content, gaming and entertainment. Carve out a niche in developed markets first, rather than try to tackle emerging markets at scale.
  • Partnerships — Be a lot more forceful with partners about Mozilla leading the direction of the product roadmap and be willing to turn down opportunities if they don’t fit with our strategy. Provide software updates directly to end users and walk away from any chipset vendor who blocked us from distributing binaries of our own OS (this would have been very hard back then, but easier now).

Booting to the Web

The “Boot to Gecko” (B2G) open source project was announced in July 2011 with the goal of building “a complete, standalone operating system for the open web.”

“Mozilla believes that the web can displace proprietary, single-vendor stacks for application development. To make open web technologies a better basis for future applications on mobile and desktop alike, we need to keep pushing the envelope of the web to include, and in places exceed, the capabilities of the competing stacks in question.”

The key areas of work were identified as:

New web APIs: build prototype APIs for exposing device and OS capabilities to content (Telephony, SMS, Camera, USB, Bluetooth, NFC, etc.)

Privilege model: making sure that these new capabilities are safely exposed to pages and applications

Booting: prototype a low-level substrate for an Android-compatible device

Applications: choose and port or build apps to prove out and prioritize the power of the system

The first (unofficial) B2G project logo, by Sean Martell

There was no mention of commercial smartphones or mobile market share at this stage, merely the desire to “push the envelope of the web” to prove what it was capable of.

The Co-founders

The four co-founders of the project were Andreas Gal, Chris Jones, Brendan Eich and Mike Shaver.

B2G project co-founders (From left to right: Andreas, Chris, Brendan, Mike)

Andreas is a super smart engineer who wrote his PhD thesis on just-in-time compilation of high level programming languages and joined Mozilla in 2008 to build TraceMonkey, the first JavaScript just-in-time compiler. He’d recently finished writing PDF.js, a PDF renderer written in JavaScript, and wanted to show what else JavaScript was capable of.

Chris got his PhD in Computer Science from Berkeley, joined Mozilla in 2009 and had worked on PDF.js with Andreas.

Brendan invented JavaScript and co-founded Mozilla in 1998. When B2G was announced he was Mozilla’s CTO, and the executive sponsor of the project.

Mike was a founding member of Mozilla in 1998 and had served as the VP of Engineering and VP of Technical Strategy, but left Mozilla shortly after the B2G project was announced.

I applied to work on the B2G project at Mozilla the day after it was announced so I wasn’t employed there at the time of the announcement, but my understanding is that it ruffled some feathers. Partly because it was announced on a public mailing list before any significant internal discussion, and partly because most people (including senior executives) didn’t know much about the project and weren’t expecting the announcement.

It had the feel of a skunkworks project and was run a lot like a startup, partially outside the normal operation of the Mozilla Corporation.

The Building Blocks

Starting from an empty GitHub repository the co-founders built a small initial team to work on “Gonk” (a “low-level substrate” based on the Linux kernel and Android Hardware Abstraction Layer), “Gecko” (an app runtime and device APIs built on the web engine of Firefox) and “Gaia” (a smartphone user interface built with web technologies HTML, CSS and JavaScript).

B2G Architecture

Some code was re-used from the Android Open Source Project but what was unique about this architecture was that it cut out the entire Java layer of Android, with Gecko rendering web content as close to bare metal as the team could get it. This would give B2G a real edge when it came to performance and would help put web content on a level footing with native code.

This distributed and small but growing team had their first in-person work week in Taipei in December 2011 where Mozilla’s Taiwan office was in the process of being fitted out, in a building overlooking the iconic Taipei 101. It was at this work week at the Grand Hyatt Hotel that the first ever phone call was made from a web page without the use of a browser plugin. The basics were starting to come together.

Taipei, December 2011

The Prototype

At a follow-up work week in Paris in February 2012, the team (now including Michael Vines from Qualcomm and our one-man UX team Josh Carpenter) raced up until the last minute to put together a prototype to showcase at Mobile World Congress in Barcelona that same month.

Paris, February 2012

We succeeded in delivering the initial components described in the original B2G announcement far enough to have a proof of concept demo running on existing Android hardware. We went to MWC with a prototype running on a Samsung Galaxy II smartphone. This was revealed in a joint announcement with our first partner, Telefónica, with additional support pledged from Adobe, Qualcomm and Deutsche Telekom. At the press conference Telefónica demoed B2G software running on Qualcomm reference hardware.

B2G prototype, MWC 2012, Barcelona

This caught the eye of other mobile carriers who were on the lookout for a platform with the potential to challenge Android, to create more choice in the mobile operating system space and wrangle some control back from the dominant Google and Apple.

As a non-profit with a mission to “promote openness, innovation & opportunity on the web” Mozilla was selling a unique vision — not that our own app platform would somehow become the “third platform” on mobile, but that the open web could fulfil that role. Like on desktop, the ubiquity and scale of the web could make it the only viable contender to the incumbent app platforms, with Mozilla leading the way.

Partnerships

With the support of new partners, Mozilla promised to return the following year with commercial devices ready to go to market.

One of the first partners was Telefónica, who had been working on their own “Open Web Device” project. At first the idea was that Mozilla could provide the underlying Gecko-based platform and Telefónica would add their own Open Web Device front end and contribute their expertise in certifying and taking devices to market.

Working with a huge telecommunications corporation like Telefónica was new ground for open source shop Mozilla and I’d say initially there was a bit of a culture clash. There were a few points of tension and for a while Mozilla and Telefónica worked on their own competing front ends.

Telefónica and Mozilla alternative B2G front ends

It quickly became clear that it made more sense to pool our resources and work on a single mobile front end, and soon Mozilla and Telefónica engineers were working side by side. Both teams of engineers really embraced this approach and it soon felt like we were all one team.

Deutsche Telekom was another partner who made big early contributions and with mobile carriers on board it became easier to get OEMs interested. The first two OEMs were Chinese manufacturing competitors ZTE and TCL.

One of the reasons these partnerships were so important was that Qualcomm, the first chipset manufacturer we were working with, would not license their firmware and device drivers to us directly, it had to be through a carrier or OEM. This meant that we legally couldn’t ship complete builds or updates of the OS directly to users, which due to the economics of mobile OS updates would turn out to be a serious problem for us.

Firefox OS 1.0

For the next year Mozilla worked intensively with our partners to build a full production quality mobile operating system.

Design

The brief given to the UX team was basically not to do anything too surprising for the first iteration. Stick to a grid of app icons like Android and iOS and keep it simple, we’d figure out how to differentiate the user experience later on. First we would prove it was possible to build the kind of UI that already existed using web technologies.

The designs the team came up with were pretty slick, but in retrospect starting out by imitating what already existed on the assumption we could change direction later turned out to be a mistake.

Implementation

On the Engineering side we would prove that it was possible to build a smartphone using open web technologies, with the whole user interface written in HTML, CSS and JavaScript.

It was a requirement for all of the built-in Gaia apps to function offline when an Internet connection was patchy or unavailable, so that the user could continue to make phone calls, take photos and listen to music etc. At first we started to use AppCache for this purpose, which was the web’s first attempt at making web apps work offline. Unfortunately we soon ran into many of the common problems and limitations of that technology and found it didn’t fulfil all of our requirements.

We also needed to invent lots of new APIs to talk to the underlying hardware of a smartphone from JavaScript, and a privilege model which made that possible. The existing security model of the web allows browsers to safely execute untrusted code by restricting it to a very limited sandbox. In order to provide web content access to much more privileged functions like making phone calls and sending text messages it was thought a new security system was needed.

In order to ship version 1.0 of B2G on time, it was decided that the simplest way to achieve both the offline and security requirements was to introduce the concept of packaged apps to Gecko. A package of resources could be “installed” onto the device to work offline and cryptographically signed to verify that its code is trusted.

Packaged apps solved our immediate problems but they are not truly web apps because they don’t have real URLs on the web and they ultimately have to be signed by a central authority (like Mozilla) to say that they’re safe. I argued against the packaged app approach at the time on the basis that it wasn’t really the web, but nobody could come up with a more webby solution we thought we could implement and ship on time.

At a work week in Telefónica’s offices in Barcelona in July 2012 it was decided to go ahead with packaged apps as a stop-gap solution until we came up with something better. This was another decision which I think turned out to be a mistake because, as well as creating significant technical debt, it set us on a path which would be difficult to turn back from.

Race to the Finish

Anyway, all of this effort culminated with a buzzing work week in Berlin in January 2013 where Mozilla worked side by side with partners, including chipset maker Qualcomm, carrier competitors Telefónica and Deutsche Telecom and manufacturing competitors ZTE and TCL, with the common goal of shipping version 1.0.

This event, hosted by Deutsche Telekom, turned out to be one of the most memorable moments in B2G’s development. Everyone worked together in the same room with a super fast Internet connection, and a friendly competition had been set up between the front end and back end teams to see who could fix all of their bugs first. The results were displayed in real time on a projector so everyone could monitor our progress. There was incredible energy in the room for the whole week while over 200 bugs were fixed.

Berlin work week, January 2013

By the end of the week Andreas Gal declared “zarro boogs” and Firefox OS version 1.0 was born. (The front end team won, by the way!)

Mobile World Congress 2013

The first commercial version of Firefox OS to ship was actually 1.0.1, once all of the necessary testing and certification had been completed. The first commercial devices were announced at Mobile World Congress in Barcelona (the biggest mobile conference in the world) in February 2013. They were the ZTE Open and the Alcatel One Touch and they would launch via Telefónica and Deutsche Telekom in Brazil, Colombia, Hungary, Mexico, Montenegro, Poland, Serbia, Spain and Venezuela. LG and Huawei had also committed to shipping devices.

ZTE Open & Alcatel One Touch smartphones

The announcements were made at a press conference the day before MWC. We were expecting around 250 people, but on the day over 700 press, media and analysts showed up.

Firefox OS press conference, MWC 2013, Barcelona (source)

We managed to get an unprecedented 18 CEOs of telco companies up on stage to express their support for the project, which I understand took even the GSMA by surprise.

CEOs on stage at press conference, MWC 2013, Barcelona (source)

I think it’s fair to say Firefox OS was really the star of the show that year. We made the front page of the conference magazine every day of the event, we got around 80,000 press results on Google News, and Firefox OS was trending on Twitter with the Oscars! It was a PR dream.

MWC magazine, MWC 2013, Barcelona (source)

We had a very cool custom designed booth at the conference (in addition to a presence on the Telefónica and Deutsche Telekom stands), with a reception desk, a giant fox tail overhead and demo stations dotted around.

Firefox OS booth, MWC 2013, Barcelona (source)

I was helping to give demos and press interviews at the event and I can tell you that the footfall was non-stop. There was a huge amount of interest from carriers, OEMs and press in what we were doing.

An Android mascot, trying to get in on the attention!

At an event which is infamous for its “booth babes” (companies hiring professional models to show off their wares), something which I think really made the Firefox OS booth stand out was that most of the people manning our stand had actually worked on the project, and many of them were even volunteers. This was something that really surprised some of the conference attendees, that people would be passionate enough about the project to give up their time freely to help promote it.

Mobile World Congress, Barcelona, February 2013 (source)

This volunteer community involvement continued long after MWC when the devices actually started rolling out in the first launch countries. Launch events in Spain, Poland, Venezuela, Colombia and others were manned by local members of the Mozilla community.

There’s a great video made in 2014 which tells the story up to the 1.0 launch, embedded below.

Firefox OS The Journey, the story of the v1 launch

Firefox OS 1.x

Firefox OS had made it to market. But before the 1.0 launch parties had even got going, we were already back at the office hard at work figuring out what came next.

At first the focus was mainly on adding basic smartphone features like MMS which had been missing from the 1.0 release, then the focus shifted to better development tools for app developers and an awful lot of requirements from partners.

We quite quickly slipped into a pattern where we were treating the mobile carriers and OEMs as our customers. They had a never-ending list of requirements which were essentially copy-pasted from their Android device portfolios. They wanted Firefox OS to reach feature parity with Android.

I remember spending an entire week shut in a room in Qualcomm’s offices in San Diego in 2013 with a group of very hard-working South Koreans from LG, making sure that all the built-in Firefox OS apps started quicker than equivalent Android apps on the same hardware. For confidentiality reasons they wouldn’t tell us how how many milliseconds the Android apps actually took to launch on their device, only whether or not we were quicker. We’d just have to keep hacking away until we had the faster launch time. The LG Fireweb finally launched in October 2013 running Firefox OS 1.1.

LG Fireweb with Firefox OS 1.1, October 2013

Over the course of 2013 and 2014 versions 1.1, 1.2, 1.3 and 1.4 were released. Eventually it became clear that we were just chasing the coat tails of Android, and with Android having a five year head start on us we had no chance of catching them. If we wanted Firefox OS to actually compete in the market and gain any significant market share, we had to differentiate.

Differentiation

Everyone basically agreed that we couldn’t compete with the likes of Android and iOS on their own terms. We couldn’t catch up with Google on Android features and we could never out-Apple Apple on design. Mozilla was used to punching above its weight and had taken on titans before and won, but we wouldn’t win if we played by their rules – we had to play by our own rules.

The way I remember it is that there were basically two schools of thought about how to differentiate Firefox OS.

The Web is the Platform

One school of thought was that we should not try to reach feature parity with our competitors but instead look for a different take on the user interface. We should come up with a much simpler UI which worked to the strengths of the web.

A big challenge we had was that the press would often compare Firefox OS with its competitors based on how many apps were in the app store. Firefox OS was never meant to have a single central app store, the idea was that the web was the platform. Unfortunately some of the early technical decisions we made around packaged apps had backed us into a corner where we were essentially dependent on the few thousand apps submitted to the Mozilla-run Firefox Marketplace.

We tried to patch over the problem by partnering with a startup called Everything.me who maintained a directory of web apps, in order to boost our content catalogue. But ultimately by relying on a central directory we’d ended up just adding to the centralised app store problem we’d set out to solve.

We talked about refocusing on real web content (by far the biggest collection of digital content on the planet) and coming up with an innovative user interface optimised for the interlinked nature of the web and the “flow” of navigating from page to page via hyperlinks. Working to the strengths of the open web would allow us to come up with something genuinely different to the competition.

Connecting the Next Billion

The other school of thought was based on the assumption that what we really needed was scale, and to get scale our best bet was to target emerging markets. They were the real growth areas in the mobile industry.

We did some market research and user studies in developing countries and it quickly became clear that much of the world’s population was simply priced out of the smartphone market. What was needed was an affordable smartphone that people in places like India and Bangladesh could actually buy.

If we could crack emerging markets then we could very quickly scale Firefox OS. Then at least we could escape the “other” category on those market share pie charts and start to gain some traction.

The $25 Smartphone

In mid-2013 Li Gong took the helm of Firefox OS. He was responsible for starting and running Mozilla’s China and Taiwan operations, but took on the additional role of “Senior VP of Mobile Devices”.

Li Gong, MWC 2014, Barcelona (source: CNET)

Li was firmly in the “affordable smartphone” camp and championed the concept of a $25 smartphone, which was felt was the price point we needed to hit if we were to get scale in emerging markets.

The team pulled off an incredible feat of engineering by managing to get Firefox OS to run on some very low end hardware based on a Spreadtrum chipset with only 128MB RAM — way below the minimum requirements for Android at the time.

We went to MWC 2014 with the “$25 smartphone”, new partnerships with low-cost handset makers Intex and Spice and a new message around “connecting the next billion”, which seemed a good fit with Mozilla’s mission. This message resonated well at MWC, with the mobile industry wondering where to grow next.

Proof of concept $25 smartphone, MWC 2014, Barcelona (source)

With our new affordable smartphones Firefox OS started to expand into Asia (India, Bangladesh), Latin America (El Salvador, Panama, Nicaragua, Guatamala) and Eastern Europe (Czech Republic).

Firefox OS bus, India

Unfortunately the execution was not so great. Firstly, the $25 smartphone eventually ended up costing more like $33 by the time it got to market. Also whilst Firefox OS “ran” on 128MB RAM you couldn’t really multi-task in the way you’d usually expect on a smartphone. Another serious problem was the lack of a key app, Whatsapp, which was essential for many of these markets. We failed to convince WhatsApp to make a web version, or even let us write one for them. These shortcomings, coupled with some hardware quality issues (particularly around the camera), meant that these affordable smartphones didn’t do very well in the market.

The problem with competing on price is that you soon get into a race to the bottom and whoever has the biggest economy of scale ends up winning. Google were quick to notice this chink in their armour and responded with Android One, affordable devices targeted at emerging markets. Android One arguably didn’t really do very well either, but it was enough to expose the fact that simply competing on price was not going to be a winning strategy.

Just because people in emerging markets may not have much disposable income, doesn’t mean they’ll settle for poor quality. They don’t want a cheap knock off of an iPhone, they want an iPhone. If they can’t have an iPhone they’d rather stick with their feature phone. It’s affordable, it works and it has a far superior battery life.

Firefox OS 2.0

Most of the work to create the $25 smartphone had been done by engineers in the Taipei office with a special release called 1.3t. Meanwhile, other teams had been thinking about what a version 2.0 might look like.

In April 2013 the UX team held a summit in London where they got together to discuss future directions for the user experience of Firefox OS. I was privileged to be invited to participate. We brainstormed about what was unique about the experience of the web and how we might create a unique user experience which played to those strengths.

UX Summit, London, April 2013

A big focus was on “flow”, the way that we can meander through the web by following hyperlinks. The web isn’t a world of monolithic apps with clear boundaries between them, it is an experience of surfing from one web page to another, flowing through content.

Haida

In the coming weeks the UX team would create some early designs for a concept (eventually code-named “Haida”) which would blur the lines between web apps and websites and create a unique user experience which would flow like the web does.

This would eventually include not only the universal “Rocketbar”, which would be accessible across the whole OS and seamlessly adapt to different types of web content, but also “sheets” which would split single page web apps into multiple pages which you could swipe through with intuitive edge gestures. It would also eventually include a content model based around live apps which you could surf to, use, and then bookmark if you chose to, rather than monolithic apps which you have to download and install from a central app store before you can use them.

In June 2013 a small group of designers and engineers met in Paris to develop a throwaway prototype of Haida, to rapidly iterate on some of the more radical concepts and put them through user testing.

Haida Team Meetup, Paris, June 2013

Below is a video Josh Carpenter created in October 2013 to communicate the Haida design concept./media/99095ebaf6616bbc1fbeb92d4430328a

This drastic change was too big to get out in one release, so Haida was split into different phases. Version 2.0 brought a visual refresh and the implementation of edge gestures for moving between windows. Version 2.1 included the integration of the browser into the main system UI to start to create the unique browser-based experience.

Firefox OS 2.x

But by version 2.2 the focus on the Haida initiative started to slip. Competing feature requests started coming in from partners to create greater feature parity with Android, improve performance and add support for right-to-left languages so that partners could ship devices in more countries.

The full Haida vision was never fully realised and people started talking about another change of direction for a version 3.0.

Firefox OS 3.0

After better than expected sales results reported by partners for the first device launches, the $25 smartphone initiative had been a disappointment. With no clear point of differentiation having yet fully materialised to continue the momentum of the initial launches, partners’ sales numbers were starting to look disappointing. A loss of confidence started to emerge and disagreements about which direction to take the product ultimately resulted in the departure of several key executives.

Li Gong left Mozilla to create a fork of Firefox OS through his startup Acadine Technologies, with $100m of funding from several Chinese government-backed organisations. When Li left he took a lot of engineers from Mozilla’s Taipei office with him, which caused a set back for Mozilla and some bad blood. This turned out to be a real waste because the $100m eventually failed to materialise and Acadine was wound down.

Andreas Gal also left to create Silk Labs, taking Chris Jones and other key members of the original B2G team with him. With Chris Lee, the head of Product, having also made a departure there was a real vacuum of leadership at the top of the Firefox OS team.

This was around the time that Chris Beard took over as CEO of Mozilla and it fell to him to temporarily take charge of the Firefox OS organisation while they tried to hire someone. Chris is a great CEO and as a long-time Mozillian has a deep intuitive sense of what Mozilla is, but as CEO he didn’t really have the time or capacity to actively lead Firefox OS from a product point of view.

3.0 Ideation Process

With a lack of any real product direction, the “v3 Ideation Process” was kicked off at a last minute whole company meetup in Portland in December 2014. The idea was to crowd-source ideas for a new direction for Firefox OS, from individual members of the Firefox OS team and the wider community.

v3 ideation process, Portland, December 2014

On the surface, for people like me who had well developed ideas about what direction I thought we should take, this seemed like a great opportunity. But as around 36 ad-hoc groups were set up all brainstorming different ideas, good ideas started to get lost in the noise. With no real constraints put on the ideation process and an insufficient process for evaluating them, people were coming up with all sorts of suggestions from smart watches to reinventing the concept of currency!

In the end no clear direction emerged and the 3.0 release was downgraded to a “2.5” release with some hurriedly put together features.

The Pivot

With an underwhelming 2.5 release and still suffering from a complete lack of product leadership, during 2015 Firefox OS started to stall.

Eventually, Ari Jaaksi was hired as the new head of “Connected Devices”. The Firefox OS team was renamed the Connected Devices team and at a whole company meetup in Orlando the “pivot” was announced.

Ari Jaaksi, Orlando All Hands, December 2015

Mozilla would stop our work to build and ship smartphones through carrier partners and we would instead start to prototype user experiences around connected devices and the Internet of Things. The technology created for Firefox OS would be used as a starting point and Firefox OS could live on with devices like Smart TVs (which had been showing some promise through a partnership with Panasonic), but we would no longer focus on smartphones.

At the end of Ari’s talk a motivating video was played on the big screen (embedded below)./media/40756ab8866005cb60c8093001f6e17eFirefox OS — The Next Chapter, played at Orlando All Hands December 2015

Nobody noticed. They were too busy chatting among themselves and trying to absorb this news and what it would mean.

The premise of Ari’s talk was that Firefox OS had set out to compete with Android and iOS and it had failed. Firefox OS was too late to market, the app store hadn’t taken off and the smartphone war had been won. It was time to move onto the next big thing — the Internet of Things.

This analysis was a little frustrating to me because I’d never felt that what we’d set out to do was to make Firefox OS the third mobile app platform, it was about pushing the envelope of the open web to make it a competitive platform for app development. It was true that the project was stalling, but we’d had some really good ideas with Haida, what we’d been lacking was focus.

However, I tried to embrace this new direction as I’d long suspected that tablets would have been a better form factor for Firefox OS than smartphones in the first place, and the Smart TV work was showing promise. These were both “connected devices” after all.

Some of the Connected Devices products I proposed

The “Product Innovation Process” was kicked off, another bottom-up ideation process to generate product ideas, but this time with much more structure (arguably too much). Connected Devices operated much like an internal startup incubator, teams were sent on “lean startup” training and we all had to become experts in the emerging field of the Internet of Things as we pitched product ideas to a “Product Innovation Board”.

The Transition

The announcement in Orlando was quickly jumped upon by some inside Mozilla as a signal that “Firefox OS is dead”. With all the resources that had been put into Firefox OS over the years, other teams at Mozilla had been feeling the pinch. The flagship Firefox team and supporting platform team had been complaining about a lack of resources for a while, and with Firefox market share slipping the finger of blame was pointed at Firefox OS.

I’d say some of this resentment was maybe justified but it started to spiral out of control and Firefox OS soon became a scapegoat for everything that wasn’t going well at Mozilla. There was a general feeling that Mozilla had “bet the farm” on Firefox OS and it hadn’t paid off. Significant political pressure started to grow inside Mozilla to remove all traces of B2G from the codebase and re-assign resources to our flagship product, Firefox.

The Connected Devices team was downsized, with around 40 people being made redundant. Meetings were held to evaluate what value the existing B2G codebase still had with our new direction, and how much of it could be removed. The argument was the B2G code was slowing down Firefox development and the cost of maintaining it couldn’t be justified.

With some Connected Devices projects (like the tablet and smart TV projects) still planning to use parts of the B2G code, we agreed on a plan to drastically slim down the B2G architecture. We’d completely remove the mozApps packaged app runtime in favour of new web standards, and remove around 30 device APIs we’d added to Gecko which were clearly never going to become web standards, in favour of a new web services based approach.

B2G OS Architecture Transition

The “B2G Transition Project” was started and the Mozilla community were involved in the process so that any smartphone-specific code could be transferred to community ownership if anyone wanted to continue to maintain it. The community really rose to this challenge and got involved in the process, ironically generating the greatest level of community involvement the B2G project had ever seen.

Although we successfully managed to remove the mozApps runtime and 10 of the 30 device APIs from Gecko very quickly, internal political pressure continued to grow to completely remove all traces of B2G from the Mozilla codebase. The tablet and smart TV projects were stopped and the Connected Devices team started to focus their efforts elsewhere.

The module ownership system of the Mozilla project is technically entirely independent of the Mozilla Corporation’s reporting structure. As a last ditch effort the module owner of B2G (then Fabrice Desré) disputed the removal of the B2G module from the Mozilla project and the decision was escalated all the way to the top of the tree, but ultimately the decision was to remove it.

Technically the new community-owned “B2G OS” could still continue as a fork, but with infrastructure being shut down and no Mozilla staff being paid to maintain the code, a fork was never really going to be practical. At its peak around 300 full time Mozilla staff were working on the Firefox OS project and the community didn’t have anywhere near that number of skilled full time resources.

Boot to Gecko was effectively dead.

Conclusions

Measuring Success

I’m incredibly proud of what we achieved with Firefox OS. If you measure its success against the original stated goals I think the project went way beyond its initial objectives. We went beyond a technical prototype to successfully ship 20 different commercial devices in over 30 countries, including smartphones and smart TVs. Apart from the incredible feats of engineering, prototyping 30 new APIs for the web platform and building possibly the most complex JavaScript codebase ever created, we built a mobile operating system from scratch and got it to market in less than two years. As far as I know no other team has ever done this.

Just some of the 20 Firefox OS products that went to market

I don’t actually know how many individual Firefox OS devices were sold in the end because our partners didn’t share their sales numbers with us and we didn’t ask them. As an educated guess I’d say it was probably around 5 million (give or take a million or so). To me that’s an incredible achievement, it’s a lot more than other “alternative” mobile operating systems have achieved and certainly the most successful project I’ve ever been involved in. But in an industry which ships over a billion units a year that’s not even half a percent of market share!

For me it was never about Firefox OS being the third mobile platform. It was always about pushing the limits of web technologies to make the web a more competitive platform for app development. I think we certainly achieved that, and I would argue our work contributed considerably to the trends we now see around Progressive Web Apps. I still believe the web will win in the end.

At some point along the way, the team lost sight of our original goals and somehow defaulted to trying to become the third smartphone platform alongside Android and iOS, with market share as the only metric of success. The B2G team grew from four co-founders to a hundred people in a very short space of time and it’s not uncommon for a startup which grows very fast to lose its mission and focus along the way. (That’s what Firefox OS felt like to me, it was a startup inside Mozilla).

A Matter of Timing

A common narrative is that Firefox OS was simply too late to market. Talking with experts from Shenzhen in China I’m actually no longer sure that’s true. They’ve suggested to me that if Firefox OS started today, the licensing issues which caused us so many problems and forced us to go through mobile carriers rather than ship software updates directly to users would no longer be a problem. As mobile hardware becomes more commoditised it would be trivial today to find white label hardware on which to run our software. There’s also a real desire from OEMs to loosen their dependence on Google and differentiate themselves. It’s possible that rather than being five years too late, Firefox OS was actually five years too early!

Those of us who work on the web like to think that what we do is really cutting edge. But the reality of web standardisation is that it takes a long time. New features will always come to native code first before they make it through the standardisation process to a cross-platform solution. I’d argue that the web is really more suited to more mature hardware platforms which have become more of a commodity, and that eventually it will win out on mobile in the same way it has on desktop. It could be that the time is quickly approaching when a web-oriented mobile OS could be successful.

The Right Decision?

It’s been over a year now since the announcement was made in Orlando and I’ve had plenty of time to process the various stages of grief associated with the end of Firefox OS: denial, anger, bargaining, depression and acceptance!

Now that the dust has settled I can honestly say that on balance I still think cancelling Firefox OS completely was the wrong decision. The project had lost momentum due to a lack of product leadership over an extended period of time, but I believe the decision to kill it was ultimately based more on internal political reasons than sound business or technical ones.

As the mobile market has matured and become more commoditised, web technologies have also matured. The opportunity is still there, in fact the timing may now be better than ever. Although I understand the reasons the project was stopped, I feel Firefox OS was ended prematurely, before it had the chance to reach its full potential. What it needed was a reboot and some ruthless and clear direction, which unfortunately it didn’t get.

Many will argue that I’m delusional and that it’s easy for me to say this, after all I wasn’t the one who had to sign the eye-watering cheques that needed signing to keep a project of that scale running. They’ll say that we had our chance and we blew it. Mozilla should now be focusing all of its efforts on its flagship product, Firefox. For me, that’s a little too inward looking. In many ways the web has now moved beyond the browser, it’s time to look to the future and all of the new challenges which face the Internet.

Lessons Learned

Sadly, it would be politically impossible to reboot B2G inside Mozilla today, but if it was possible there are a number of things I would do differently a second time around.

Design — I’d start with a very simple browser-based user interface with a focus on web content, rather than try to replicate all the features of other mobile operating systems.

Engineering —Have a clear split between “chrome” and web content rather than try to force the web to do things it isn’t suited to. Create device APIs using REST & WebSockets on the server side of the web stack rather than privileged JavaScript DOM APIs on the client side (JavaScript is not what makes the web the web, URLs are). Create a community curated directory of web apps on the web rather than an app store of developer-submitted packaged apps.

Product — Not try to create the cheapest smartphone. Create a mid-range tablet (and later possibly a TV stick) with a focus on web content, gaming and entertainment. Carve out a niche in developed markets first, rather than try to tackle emerging markets at scale.

Partnerships — Be a lot more forceful with partners about Mozilla leading the direction of the product roadmap and be willing to turn down deals if they don’t fit with our strategy. Provide software updates directly to end users and walk away from any chipset vendor who blocked us from distributing binaries of our own OS (this would have been very hard back then, but easier now).

Footnote

So that’s my story. It’s pretty long so if you managed to get this far without skipping at least some of the boring bits then I’m impressed!

My main hope in documenting all of this is that Firefox OS is remembered as more than just a footnote in tech history which says “a failed mobile OS from Mozilla”.

A lot of super smart and awesome people put an awful lot of love and hard work into the Boot to Gecko project. It’s something I’m incredibly proud of, and they should be too. It might not have matched up to the expectations imposed on it from the outside world, but from my point of view Firefox OS was a success and certainly the highlight of my career so far! (I was actually an intern at Google in 2008 when they shipped the first Android smartphone, but for me the buzz of Firefox OS was far bigger than that).

Some of the big brains behind Firefox OS (and me), Whistler, June 2015

I still believe deeply in Mozilla’s mission and I also think there’s an exciting new chapter coming to Mozilla soon, with some new emerging technologies which I’m itching to tell you about. But that’s a story for another day.

For now, please forgive me the indulgence of ending with a video my wife and I created in 2014, with our dodgy Bob Dylan parody and a collection of photos which capture the incredible journey that was Firefox OS. (See if you can spot the cameo by Sir Tim Berners-Lee, trying out Firefox OS over lunch!)

The Times They Are a Changin’, Open Web Remix by Ben and Siobhan

[Edit 2017–03–06]:

  • Clarified Brendan Eich’s role at Mozilla
  • Mentioned Telefónica’s demo on Qualcomm reference hardware at MWC 2012
  • Noted the lack of WhatsApp being a major problem in many markets
  • Credited B2G logo designer

Pinned Apps – An App Model for the Web

(re-posted from a page I created on the Mozilla wiki on 17th December 2014)

Problem Statement

The per-OS app store model has resulted in a market where a small number of OS companies have a large amount of control, limiting choice for users and app developers. In order to get things done on mobile devices users are restricted to using apps from a single app store which have to be downloaded and installed on a compatible device in order to be useful.

Design Concept

Concept Overview

The idea of pinned apps is to turn the apps model on its head by making apps something you discover simply by searching and browsing the web. Web apps do not have to be installed in order to be useful, “pinning” is an optional step where the user can choose to split an app off from the rest of the web to persist it on their device and use it separately from the browser.

Pinned_apps_overview

”If you think of the current app store experience as consumers going to a grocery store to buy packaged goods off a shelf, the web is more like a hunter-gatherer exploring a forest and discovering new tools and supplies along their journey.”

App Discovery

A Web App Manifest linked from a web page says “I am part of a web app you can use separately from the browser”. Users can discover web apps simply by searching or browsing the web, and use them instantly without needing to install them first.

Pinned_apps_discovery

”App discovery could be less like shopping, and more like discovering a new piece of inventory while exploring a new level in a computer game.”

App Pinning

If the user finds a web app useful they can choose to split it off from the rest of the web to persist it on their device and use it separately from the browser. Pinned apps can provide a more app-like experience for that part of the web with no browser chrome and get their own icon on the homescreen.

Pinned_apps_pinning

”For the user pinning apps becomes like collecting pin badges for all their favourite apps, rather than cluttering their device with apps from an app store that they tried once but turned out not to be useful.”

Deep Linking

Once a pinned app is registered as managing its own part of the web (defined by URL scope), any time the user navigates to a URL within that scope, it will open in the app. This allows deep linking to a particular page inside an app and seamlessly linking from one app to another.

Pinned_apps_linking

”The browser is like a catch-all app for pages which don’t belong to a particular pinned app.”

Going Offline

Pinning an app could download its contents to the device to make it work offline, by registering a Service Worker for the app’s URL scope.

Pinned_apps_offline

”Pinned apps take pinned tabs to the next level by actually persisting an app on the device. An app pin is like an anchor point to tether a collection of web pages to a device.”

Multiple Pages

A web app is a collection of web pages dedicated to a particular task. You should be able to have multiple pages of the app open at the same time. Each app could be represented in the task manager as a collection of sheets, pinned together by the app.

Pinned_app_pages

”Exploding apps out into multiple sheets could really differentiate the Firefox OS user experience from all other mobile app platforms which are limited to one window per app.”

Travel Guide

Even in a world without app stores there would still be a need for a curated collection of content. The Marketplace could become less of a grocery store, and more of a crowdsourced travel guide for the web.

Pinned_apps_guide

”If a user discovers an app which isn’t yet included in the guide, they could be given the opportunity to submit it. The guide could be curated by the community with descriptions, ratings and tags.”

3 Questions

Pinnged_apps_pinned

What value (the importance, worth or usefulness of something) does your idea deliver?

The pinned apps concept makes web apps instantly useful by making “installation” optional. It frees users from being tied to a single app store and gives them more choice and control. It makes apps searchable and discoverable like the rest of the web and gives developers the freedom of where to host their apps and how to monetise them. It allows Mozilla to grow a catalogue of apps so large and diverse that no walled garden can compete, by leveraging its user base to discover the apps and its community to curate them.

What technological advantage will your idea deliver and why is this important?

Pinned apps would be implemented with emerging web standards like Web App Manifests and Service Workers which add new layers of functionality to the web to make it a compelling platform for mobile apps. Not just for Firefox OS, but for any user agent which implements the standards.

Why would someone invest time or pay money for this idea?

Users would benefit from a unique new web experience whilst also freeing themselves from vendor lock-in. App developers can reduce their development costs by creating one searchable and discoverable web app for multiple platforms. For Mozilla, pinned apps could leverage the unique properties of the web to differentiate Firefox OS in a way that is difficult for incumbents to follow.

UI Mockups

App Search

Pinned_apps_search

Pin App

Pin_app

Pin Page

Pin_page

Multiple Pages

Multiple_pages

App Directory

App_directory

Implementation

Web App Manifest

A manifest is linked from a web page with a link relation:

<pre>
<link rel=”manifest” href=”/manifest.json”>
</pre>

A manifest can specify an app name, icon, display mode and orientation:

<pre>
{
"name": "GMail"
"icons": {...},
"display": "standalone",
"orientation": “portrait”,
...
}
</pre>

There is a proposal for a manifest to be able to specify an app scope:

<pre>
{
...
"scope": "/"
...
}
</pre>

Service Worker

There is also a proposal to be able to reference a Service Worker from within the manifest:

<pre>
{
...
service_worker: {
src: "app.js",
scope: "/"
...
}
</pre>

A Service Worker has an install method which can populate a cache with a web app’s resources when it is registered:

<pre>
this.addEventListener('install', function(event) {
event.waitUntil(
caches.create('v1').then(function(cache) {
return cache.add(
'/index.html',
'/style.css',
'/script.js',
'/favicon.ico'
);
}, function(error) {
console.error('error populating cache ' + error);
};
);
});
</pre>

So that the app can then respond to requests for resources when offline:

<pre>
this.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).catch(function() {
return event.default();
})
);
});
</pre>