<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Project Tofino - Medium]]></title>
        <description><![CDATA[Browser explorations by the Firefox team - Medium]]></description>
        <link>https://medium.com/project-tofino?source=rss----b6989d965a26---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Project Tofino - Medium</title>
            <link>https://medium.com/project-tofino?source=rss----b6989d965a26---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 17 Sep 2026 00:56:44 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/project-tofino" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Introducing Project Mentat, a flexible embedded knowledge store]]></title>
            <link>https://medium.com/project-tofino/introducing-datomish-a-flexible-embedded-knowledge-store-1d7976bff344?source=rss----b6989d965a26---4</link>
            <guid isPermaLink="false">https://medium.com/p/1d7976bff344</guid>
            <category><![CDATA[datomic]]></category>
            <category><![CDATA[mozilla]]></category>
            <category><![CDATA[database]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Richard Newman]]></dc:creator>
            <pubDate>Tue, 15 Nov 2016 20:58:43 GMT</pubDate>
            <atom:updated>2021-02-14T04:42:38.316Z</atom:updated>
            <content:encoded><![CDATA[<p><em>Edit, January 2017: to avoid confusion and to better follow Mozilla’s early-stage project naming guidelines, we’ve renamed Datomish to </em><strong><em>Project Mentat</em></strong><em>. This post has been altered to match.</em></p><p>For several months now, a small team at Mozilla has been exploring new ways of building a browser. We called that effort <a href="https://medium.com/project-tofino/">Tofino</a>, and it’s now morphed into the <a href="https://medium.com/project-tofino/re-defining-the-tofino-project-6d3c98521cc8">Browser Futures Group</a>.</p><p>As part of that, Nick Alexander and I have been working on a persistent embedded knowledge store called <a href="https://github.com/mozilla/mentat">Project Mentat</a>. Mentat is designed to ship in client applications, storing relational data on disk with a flexible schema.</p><p>It’s a little different to most of the storage systems you’re used to, so let’s start at the beginning and explain <em>why</em>. If you’re only interested in the <em>what</em>, skip down to just above the example code.</p><p>As we began building Tofino’s data layer, we observed a few things:</p><ul><li>We knew we’d need to store new types of data as our product goals shifted: page metadata, saved content, browsing activity, location. The set of actions the user can take, and the data they generate, is bound to grow over time. We didn’t (don’t!) know what these were in advance.</li><li>We wanted to support front-end innovation without being gated on some storage developer writing a complicated migration. We’ve seen database evolution become a locus of significant complexity and risk — “here be dragons” — in several other applications. Ultimately it becomes easier to store data elsewhere (a new database, simple prefs files, a key-value table, or JSON on disk) than to properly integrate it into the existing database schema.</li><li>As part of that front-end innovation, sometimes we’d have two different ‘forks’ both growing the data model in two directions at once. That’s a difficult problem to address with a tool like SQLite.</li><li>Front-end developers were interested in looser approaches to accessing stored data than specialized query endpoints: <em>e.g.</em>, <a href="https://medium.com/u/d3391efe481a">Lin Clark</a> suggested that <a href="http://graphql.org/">GraphQL</a> might be a better fit. Only a month or two into building Tofino we already saw the number of API endpoints, parameters, and fields growing as we added features. Specialized API endpoints turn into <em>ad hoc</em> query languages.</li><li>Syncability was a constant specter hovering at the back of our minds: <a href="https://160.twinql.com/syncing-and-storage-on-three-platforms/">getting the data model right</a> for future syncing (or partial hosting on a service) was important.</li></ul><p>Many of these concerns happen to be shared across other projects at Mozilla: <a href="https://wiki.mozilla.org/Firefox/Activity_Stream">Activity Stream</a>, for example, also needs to store a growing set of page summary attributes for visited pages, and join those attributes against your main browsing history.</p><p>Nick and I started out supporting Tofino with a simple store in SQLite. We knew it had to adapt to an unknown set of use cases, so we decided to follow the principles of <a href="http://www.baeldung.com/cqrs-event-sourced-architecture-resources">CQRS</a>.</p><p>CQRS — Command Query Responsibility Segregation — recognizes that it’s hard to pick a single data storage model that works for all of your readers and writers… particularly the ones you don’t know about yet.</p><p>As you begin building an application, it’s easy to dive head-first into storing data to directly support your first user experience. As the experience changes, and new experiences are added, your single data model is pulled in diverging directions.</p><p>A common <em>second system syndrome </em>for this is to reactively aim for maximum generality. You build a single normalized super-flexible data model (or key-value store, or document store)… and soon you find that it’s expensive to query, complex to maintain, has designed-in capabilities that will never be used, and you <em>still</em> have tensions between different consumers.</p><p>The CQRS approach, at its root, is to separate the ‘command’ from the ‘query’: store a data model that’s very close to what the writer knows (typically a stream of events), and then materialize as many query-side data stores as you need to support your readers. When you need to support a new kind of fast read, you only need to do two things: figure out how to materialize a view from history, and figure out how to incrementally update it as new events arrive. You shouldn’t need to touch the base storage schema at all. When a consumer is ripped out of the product, you just throw away their materialized views.</p><p>Viewed through that lens, everything you do in a browser is an event with a context and a timestamp: “the user bookmarked page X at time T in session S”, “the user visited URL X at time T in session S for reason R, coming from visit V1”. <strong>Store everything you know, materialize everything you need</strong>.</p><p>We built that with SQLite.</p><p>This was a clear and flexible concept, and it allowed us to adapt, but the implementation in JS involved lots of boilerplate and was somewhat cumbersome to maintain manually: the programmer does the work of defining how events are stored, how they map to more efficient views for querying, and how tables are migrated when the schema changes. You can <a href="https://github.com/mozilla/tofino/blob/4962a5411f915c1c0369fd10a65d51b7064d2d58/app/services/user-agent-service/sqlstorage.js">see this starting to get painful even early in Tofino’s evolution</a>, even <a href="https://github.com/mozilla/tofino/blob/4962a5411f915c1c0369fd10a65d51b7064d2d58/app/services/user-agent-service/profile-schema.js">without data migrations</a>.</p><p>Quite soon it became clear that a conventional embedded SQL database wasn’t a direct fit for a problem in which the schema grows organically — particularly not one in which multiple experimental interfaces might be sharing a database. Furthermore, being elbow-deep in SQL wasn’t second-nature for Tofino’s webby team, so the work of evolving storage fell to just a few of us. (Does any project ever have enough people to work on storage?) We began to look for alternatives.</p><p>We explored a range of existing solutions: key-value stores, graph databases, and document stores, as well as the usual relational databases. Each seemed to be missing some key feature.</p><p><strong>Most good storage systems simply aren’t suitable for embedding in a client application</strong>. There are lots of great storage systems that run on the JVM and scale across clusters, but we need to run on your Windows tablet! At the other end of the spectrum, most webby storage libraries aren’t intended to scale to the amount of data we need to store. Most graph and key-value stores are missing one or more of full-text indexing (crucial for the content we handle), expressive querying, <a href="http://martinfowler.com/articles/schemaless/">defined schemas</a>, or the kinds of indexing we need (<em>e.g.</em>, fast range queries over visit timestamps). ‘Easy’ storage systems of all stripes often neglect concurrency, or transactionality, or multiple consumers. And most don’t give much thought to how materialized views and caches would be built on top to address the tension between flexibility and speed.</p><p>We found a couple of solutions that seemed to have the right shape (which I’ll discuss below), but weren’t quite something we could ship. <a href="http://www.datomic.com"><strong>Datomic</strong></a> is a production-grade JVM-based clustered relational knowledge store. It’s great, as you’d expect from Cognitect, but it’s not open-source and we couldn’t feasibly embed it in a Mozilla product. <a href="https://github.com/tonsky/datascript"><strong>DataScript</strong></a> is a ClojureScript implementation of Datomic’s ideas, but it’s intended for in-memory use, and we need persistent storage for our datoms.</p><p>Nick and I try to be responsible engineers, so we explored the cheap solution first: adding persistence to DataScript. We thought we might be able to leverage all of the work that went into DataScript, and just flush data to disk. It soon became apparent that we couldn’t resolve the impedance mismatch between a synchronous in-memory store and asynchronous persistence, and we had concerns about memory usage with large datasets. Project Mentat was born.</p><p><strong>Mentat is built on top of SQLite</strong>, so it gets all of SQLite’s reliability and features: full-text search, transactionality, durable storage, and a small memory footprint.</p><p>On top of that we’ve layered ideas from DataScript and Datomic: a <strong>transaction log</strong> with first-class transactions so we can see and annotate a history of events without boilerplate; a first-class <strong>mutable schema</strong>, so we can easily grow the knowledge store in new directions and introspect it at runtime; Datalog for storage-agnostic querying; and an expressive strongly typed schema language.</p><p>Datalog queries are translated into SQL for execution, taking full advantage of both the application’s rich schema and SQLite’s fast indices and mature SQL query planner.</p><p>You can see more comparisons between Project Mentat and those storage systems <a href="https://github.com/mozilla/mentat/blob/master/README.md">in the README</a>.</p><p>A proper tutorial will take more space than this blog post allows, but <a href="https://github.com/mozilla/mentat/blob/ce67644fd5a62af0efbff5a82558c67a3f12ffcd/test/js/tests.js">you can see a brief example in JS</a>. It looks a little like this:</p><pre>// Open a database.<br>let db = await datomish.open(&quot;/tmp/testing.db&quot;);</pre><pre>// Make sure we have our current schema.<br>await db.ensureSchema(schema);</pre><pre>// Add some data. Note that we use a temporary ID (the real ID<br>// will be assigned by Mentat).<br>let txResult = await db.transact([<br>  {&quot;db/id&quot;: datomish.tempid(),<br>   &quot;page/url&quot;: &quot;<a href="https://mozilla.org/">https://mozilla.org/</a>&quot;,<br>   &quot;page/title&quot;: &quot;Mozilla&quot;}<br>]);</pre><pre>// Let&#39;s extend our schema. In the real world this would<br>// typically happen across releases.<br>schema.attributes.push({&quot;name&quot;:        &quot;page/visitedAt&quot;,<br>                        &quot;type&quot;:        &quot;instant&quot;,<br>                        &quot;cardinality&quot;: &quot;many&quot;,<br>                        &quot;doc&quot;:         &quot;A visit to the page.&quot;});<br>await db.ensureSchema(schema);</pre><pre>// Now we can make assertions with the new vocabulary<br>// about existing entities.<br>// Note that we simply let Mentat find which page<br>// we&#39;re talking about by URL -- the URL is a unique property<br>// -- so we just use a tempid again.<br>await db.transact([<br>  {&quot;db/id&quot;: datomish.tempid(),<br>   &quot;page/url&quot;: &quot;<a href="https://mozilla.org/">https://mozilla.org/</a>&quot;,<br>   &quot;page/visitedAt&quot;: (new Date())}<br>]);</pre><pre>// When did we most recently visit this page?<br>let date = (await db.q(<br>  `[:find (max ?date) .<br>    :in $ ?url<br>    :where<br>    [?page :page/url ?url]<br>    [?page :page/visitedAt ?date]]`,<br>  {&quot;inputs&quot;: {&quot;url&quot;: &quot;<a href="https://mozilla.org/">https://mozilla.org/</a>&quot;}}));</pre><pre>console.log(&quot;Most recent visit: &quot; + date);</pre><p>Project Mentat is implemented in ClojureScript, and currently runs on three platforms: <strong>Node</strong>, <strong>Firefox</strong> (using Sqlite.jsm), and the <strong>JVM</strong>. We use DataScript’s excellent parser (thanks to <strong>Nikita Prokopov</strong>, principal author of DataScript!).</p><p><em>Addition, January 2017: we are in the process of rewriting Mentat in Rust. More blog posts to follow!</em></p><p>Nick has just finished porting Tofino’s <a href="https://github.com/mozilla/datomish-user-agent-service">User Agent Service</a> to use Mentat for storage, which is an important milestone for us, and a bigger example of Mentat in use if you’re looking for one.</p><p>What’s next?</p><p>We’re hoping to learn some lessons. We think we’ve built a system that makes good tradeoffs: Mentat delivers schema flexibility with minimal boilerplate, and achieves similar query speeds to an application-specific normalized schema. Even the storage space overhead is acceptable.</p><p>I’m sure Tofino will push our performance boundaries, and we have a few ideas about how to exploit Mentat’s schema flexibility to help the rest of the Tofino team continue to move quickly. It’s exciting to have a solution that we feel strikes a good balance between storage rigor and real-world flexibility, and I can’t wait to see where else it’ll be a good fit.</p><p>If you’d like to come along on this journey with us, feel free to take a look at <a href="https://github.com/mozilla/mentat">the GitHub repo</a>, come <a href="http://tofino-slack-invite.mozilla.io/">find us on Slack</a> in <em>#mentat</em>, or drop me an email with any questions. Mentat isn’t yet complete, but the API is quite stable. If you’re adventurous, consider using it for your next Electron app or Firefox add-on (there’s an example in the GitHub repository)… and please do send us feedback and file issues!</p><h3>Acknowledgements</h3><p>Many thanks to Lina Cambridge, Grisha Kruglov, Joe Walker, Erik Rose, and Nicholas Alexander for reviewing drafts of this post.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1d7976bff344" width="1" height="1" alt=""><hr><p><a href="https://medium.com/project-tofino/introducing-datomish-a-flexible-embedded-knowledge-store-1d7976bff344">Introducing Project Mentat, a flexible embedded knowledge store</a> was originally published in <a href="https://medium.com/project-tofino">Project Tofino</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Engineering update on Tofino]]></title>
            <link>https://medium.com/project-tofino/engineering-update-on-tofino-8381d82398e8?source=rss----b6989d965a26---4</link>
            <guid isPermaLink="false">https://medium.com/p/8381d82398e8</guid>
            <category><![CDATA[firefox]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Joe Walker]]></dc:creator>
            <pubDate>Tue, 15 Nov 2016 20:31:47 GMT</pubDate>
            <atom:updated>2016-11-16T17:43:47.299Z</atom:updated>
            <content:encoded><![CDATA[<p>We’ve spent several months testing UI concepts, understanding Electron’s relationship with the web, testing some architectural ideas, like a separate user agent service to handle browser data, and the best way to create a browser UI using web technology. During the Tofino project timeline, the Firefox/Gecko team has also outlined an ambitious effort to really push the web platform itself forward with <a href="https://medium.com/mozilla-tech/a-quantum-leap-for-the-web-a3b7174b3c12#.fas2nkric">Project Quantum</a>! Given all that, it’s probably time for a quick update on what we’ve learned building browser concepts outside the constraints of the current Firefox implementation.</p><p>Any list of learnings has the potential to sound very negative (as a list of battles it’s likely to focus on imperfections); but if this was just a list of the obvious things that we tried and which turned out to work fine, there would be little point in reading or writing it.</p><p>With that in mind, here’s what we’ve learned so far.</p><h4><strong>Electron</strong></h4><p>As an application platform, <a href="http://electron.atom.io/">Electron</a> is fantastic for building small simple client applications that involve a single main window. For larger applications it’s likely that you will need to fork Electron in order to get what you need. Project Tofino runs on a fork of Electron already and <a href="https://brave.com/">Brave</a> does too.</p><p>A few examples of issues that we have run into:</p><ul><li>By default Electron ships with <a href="https://github.com/electron/libchromiumcontent/issues/174">video and audio codecs that require licenses for use</a>. We’re not lawyers, but it might make sense to consult one depending on your use-case.</li><li>Electron is not designed to build browsers. There are some cases where web behaviours are broken and can’t be fixed without breaking Electron functionality (e.g. <a href="https://github.com/electron/electron/issues/1865">window.open() not returning values that web content would expect</a>).</li><li>The Electron process model uses one process per window and another process per tab. This leads to many processes when used at the sorts of scale we’ve seen from Firefox users. Since each process requires significant OS-level resources a browser is forced to do non-trivial process management (like clever shared forking) to keep overhead low. That’s likely to be hard with Electron.</li><li>The main test harness for Electron, <a href="http://electron.atom.io/spectron/">Spectron</a>, has proven to be unreliable for us. On OSX we had to disable our minimal application tests since they were failing intermittently far too often to be useful.</li><li>Because Electron uses a <a href="https://github.com/electron/node">fork of Node</a>, any native addon modules have to be recompiled to run correctly. This causes problems when running unit tests outside of Electron.</li></ul><p>We’ve also found a couple of issues with the Node ecosystem, which are more obvious when delivering client applications:</p><ul><li>If you’re shipping code built with npm, you should really check that you are OK with shipping your code in a bundle that could be considered to have been “compiled” with GPL code. <a href="https://github.com/davglass/license-checker">License checker</a> can help.</li><li>The problems of fragile transient dependencies and difficulties with npm-shrinkwrap are well known.</li></ul><p>Electron is excellent for porting websites to the desktop, and is also great for for prototyping a new browser. It’s clearly also possible to <a href="https://brave.com/">ship a browser</a> to many people using Electron, but at heart Electron is designed around use-cases like <a href="https://atom.io/">Atom</a> (obviously), <a href="https://code.visualstudio.com/">VS Code</a>, <a href="https://slack.com/downloads/">Slack</a>, etc, so it might not be the correct platform for a long term future-browser.</p><h4><strong>User Agent Service</strong></h4><p>Firefox, like the Mozilla suite before it, is component-oriented. Chunks of code like the history store, the cookie manager, and the network library are each wrapped up in a classic COM-style interface and made available to the rest of the system in a language-agnostic way. Each of these parts — UI-centric or not — is connected in a dependency web. For example, the “new tab” page, the history view, the preferences window, and Firefox Sync all talk to the same read-write history API… and classic Firefox add-ons can talk to all of these components, from the clipboard through to preferences.</p><p>Tofino evolved into a different kind of architecture, one that reflects the different challenges we face around managing change and complexity. This architecture is <em>layered</em>. The web rendering engine itself is self-contained, with narrow, well-defined points of integration for the rest of the application to see what’s happening — page title changes, for example.</p><p>Similarly, storage and exploration of the user’s data is contained within a <em>user agent service</em> — a separate chunk of code that exposes a profile data storage service over https and websockets.</p><p>This layering gives us flexibility to explore new interfaces without tying ourselves in knots. It might enable add-ons that look more like vanilla web properties which use the user agent service instead of privileged JavaScript APIs. It also enables us to work on new kinds of data storage without the complexity of multiple direct consumers.</p><h4>Creating a Browser UI using Web Technology</h4><p>From a UI standpoint, we’re using modern techniques for frontend development. We’re not the first to do this by any means. <a href="https://github.com/browserhtml/browserhtml">Browser.html</a>, <a href="https://vivaldi.com/">Vivaldi</a>, <a href="https://minbrowser.github.io/min/">Min</a> and <a href="https://github.com/k88hudson/browser">many</a> <a href="https://github.com/vingtetun/planula">others</a> have beaten this path. In many ways Firefox itself is a precursor to this way of doing things if you squint and pretend that XUL is a widget library for HTML.</p><p>JavaScript modules and Webpack’s filesystem watching have made for quick iteration cycles, and it means we can use ES.next through Babel. This led to a world where we could write very maintainable code thanks to async/await, classes, standard imports/exports etc, all while just using F5 to reload the whole browser just like one would in a normal webpage. Hot module reloading was also useful while writing state-dependent code, like our “overview page summaries”.</p><p>We’ve chosen <a href="https://facebook.github.io/react/">React</a> and <a href="https://github.com/reactjs/redux">Redux</a> for writing our UI and managing our application state. We found it good for easily writing maintainable code and quickly prototyping different views and the interactions between them. Compared to the XUL code that much of Firefox uses we think that React+Redux strongly encourages multiple developers to code with a unified style and means that our views, stores and actions are immediately alterable by someone unfamiliar with the codebase.</p><p>We discovered that we needed to be proactive about <a href="https://www.youtube.com/watch?v=-t8eOoRsJ7M">performance</a> by automatic testing and/or careful reviews.</p><p>Furthermore, developing with React outside of the standard predefined and essentially carefully tailored environment of a web page was difficult at times. Managing non-standard DOM nodes that required non-standard attributes was unfriendly, and required either us writing custom wrappers, special prefixing with “data-”, or hacking our way through using the magical “is” component property. Subsequently this led to potential confusion due to component properties not being magically massaged anymore when they were mapped to DOM attributes: for example “className” had to be written as “class” instead, leading to easily fixable but frustrating bugs. Therefore the biggest problems in this department arose when having to deal with &lt;webview&gt; nodes in Electron.</p><p>Strictly adhering to the Redux model in Electron was also difficult. Single-store application state assumes a single process per application. When writing a web browser (in Electron or otherwise), dealing with multiple processes is a necessity, so the easy abstractions and “best practices” that worked in webpages were, in practice, much harder to respect. This led to an initial architecture where there were multiple application states, one for each process, with communication happening over IPC. Our final approach was to try and mimic the web and use web sockets in order to synchronize the multiple application states: after all, synchronizing multiple instances of the same application written in React and Redux is a known problem on the web and multiple solutions exist. However, it is still not clear which is the best way to handle this issue.</p><h4><strong>Next Steps</strong></h4><p>We’re currently working on two things. Having spent several months hacking on several different UI ideas, we’re changing focus slightly to investigate some more foundational problems like “remaining performant with many tabs open”, and so on. Once we have something that we feel covers the bases of at least a subset of users then we’ll return to UI experiments, so we’re shooting for a v0.1 which we’re all committed to using as our daily driver.</p><p>While we’re working on that we’re also evolving our <a href="https://mozilla.invisionapp.com/share/VF8B6R87T#/screens/182223037_A_01_Overview">next generation UI</a>. It has an overview tab, allows collections of pages and shortcuts as better version of bookmarks, and allows for smarter searching in your personal history.</p><p>Often posts say things like “I’d like to thank X, Y and Z for reviewing this post”. In this case I’d like to thank Dave Townsend, Richard Newman and Victor Porof for actually writing it. The rest of the Tofino team did the reviewing. I just ran it together and tweaked.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8381d82398e8" width="1" height="1" alt=""><hr><p><a href="https://medium.com/project-tofino/engineering-update-on-tofino-8381d82398e8">Engineering update on Tofino</a> was originally published in <a href="https://medium.com/project-tofino">Project Tofino</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[(Re)defining the Tofino Project]]></title>
            <link>https://medium.com/project-tofino/re-defining-the-tofino-project-6d3c98521cc8?source=rss----b6989d965a26---4</link>
            <guid isPermaLink="false">https://medium.com/p/6d3c98521cc8</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[firefox]]></category>
            <dc:creator><![CDATA[Mark Mayo]]></dc:creator>
            <pubDate>Tue, 15 Nov 2016 20:10:32 GMT</pubDate>
            <atom:updated>2016-11-16T18:57:05.715Z</atom:updated>
            <content:encoded><![CDATA[<p>TL;DR: s/Tofino/Browser Futures Group/</p><p>Our original 3-month goal was to investigate what a browser designed in 2016 would look like.</p><p><em>(Of note, this is different than exploring what an implementation of the web’s platform should look like — see </em><a href="https://medium.com/mozilla-tech/a-quantum-leap-for-the-web-a3b7174b3c12#.fas2nkric"><em>Project Quantum</em></a><em> and </em><a href="https://servo.org/"><em>Servo</em></a><em> for that.)</em></p><p>In those three months, we experimented with lots of different parts of the browser: from the way you navigate, to the way you save things from the web, to the very way in which the front-end for a web browser is built.</p><p>Now that the initial project is over (in fact,was over a few months ago…), it is time to look at if and how we move forward. The <a href="https://medium.com/project-tofino/engineering-update-on-tofino-8381d82398e8#.h5nj5hsv8">Engineering Update for Tofino</a> post by Joe Walker is live, and posts from the product and UX teams will follow, but at the high level this is what we learned:</p><ul><li>User testing our concepts ahead of even completing a prototype was extremely valuable.</li><li>Boy howdy do normal users have hard time with non-conventional browser interfaces!</li><li>A User Agent Service is a good idea. We want one in Firefox, like, yesterday.</li><li>Writing a new browser UI in React is flexible and easier to develop in than XUL. Mixing XUL and HTML in a single product/interface was harder than we thought.</li><li>Electron is great for prototyping, but some work is needed if you want to build a full browser.</li><li>Getting out of our Firefox developer bubble and engaging with new open source teams and projects was great. So much awesome feedback and energy!</li></ul><p>So what is next?</p><p>The ideas behind the user-agent service and a React UI sound good on paper, but do they work in practice, and are they useful to Mozilla? The <a href="https://github.com/mozilla/tofino/blob/master/docs/UA-service.md">User Agent Service</a> is designed to store a broader set of data than Firefox Sync can currently handle, but we’re not sure if can it scale up with large volumes of data or if it’s as flexible as we need.</p><p>There could be lessons from our React based UI that we can take into mainline Firefox. To that end Dave Townsend is going to be starting with <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/tabbrowser">TabBrowser</a> and seeing if there are things that Firefox can learn and we’re going to continue to evolve what we’ve got to be more workable.</p><p>We’re going to continue using an environment that makes it easy to prototype fast. We’re not wedded to Electron (far from it) but the fast prototyping aspects of that have been really nice.</p><p>It’s also becoming clear that the name Tofino doesn’t really work with what we’re doing now; What we’re working on now is less of a product or user experience exploration, and more of a set of technologies that need testing out, so we’re renaming the group to the Browser Futures Group.</p><p>We’re working on a roadmap.</p><p>Tofino is dead — Long live the Browser Futures Group.</p><p><em>A brief aside: We briefly called this team the Browser Research Group, and asked for help picking a new name. The internet provided! Background: Naming things is always hard.. so a brief clarification is required because I agonized over using the word Research. The timescale of our ‘research’ is short (months rather than years) and what we’re doing is closely aligned to the goals of the Firefox product organization — i.e. building and shipping a popular browser. The team does not do the kinds of research Mozilla Research in our Emerging Technologies group does, things looking years ahead like </em><a href="https://www.rust-lang.org/en-US/"><em>Rust</em></a><em> and </em><a href="https://servo.org/"><em>Servo</em></a><em> and </em><a href="https://hacks.mozilla.org/2016/10/webassembly-browser-preview/"><em>WebAssembly</em></a><em>. Calling the team the “Browser Innovation Group” felt even more awkward. Got a better name suggestion? Comment below!</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6d3c98521cc8" width="1" height="1" alt=""><hr><p><a href="https://medium.com/project-tofino/re-defining-the-tofino-project-6d3c98521cc8">(Re)defining the Tofino Project</a> was originally published in <a href="https://medium.com/project-tofino">Project Tofino</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Iterations]]></title>
            <link>https://medium.com/project-tofino/iterations-af5ad7d54497?source=rss----b6989d965a26---4</link>
            <guid isPermaLink="false">https://medium.com/p/af5ad7d54497</guid>
            <category><![CDATA[lean]]></category>
            <category><![CDATA[user-research]]></category>
            <category><![CDATA[design-process]]></category>
            <category><![CDATA[ux]]></category>
            <category><![CDATA[design]]></category>
            <dc:creator><![CDATA[Philipp Sackl-O’Neill]]></dc:creator>
            <pubDate>Thu, 14 Jul 2016 17:57:13 GMT</pubDate>
            <atom:updated>2016-08-02T15:42:26.635Z</atom:updated>
            <content:encoded><![CDATA[<p>Working in a completely open problem space is, among other things, an exercise in self control. When you’re a designer and you get the chance to invent freely, it is natural to jump onto the most interesting problems first, which are often the ones that can be solved through clever design. Whether or not these solutions would actually benefit users is a different matter altogether. Since the problem space for Project Tofino is as open as can be, we were working very hard on not making that mistake — on not jumping to conclusions too early. Instead, we wanted to start with the problems and desires that actual people had (read: people who don’t work in the technology industry).</p><p>Conveniently, our research team was way ahead of the task and had gathered a wide variety of insights into people’s online behavior over the past years. The most recent of those efforts was also one of the most significant ones: we call it the Workflows Research and we’ll publish more on the results soon. This research provided us with insights about usage patterns, frustrations and problem solving strategies that real people use to solve real issues.</p><p>Among the workflows we picked to investigate first were comparison shopping, saving for later (and contextual recovery), and improving recurring navigational patterns (a.k.a. making it more convenient to visit the sites you go to frequently). We’ll talk more about each of the problems and solutions in another blog post. For now, let’s dive into the methodology we used to work on these problems.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*N_WU2ODcEw6OSpCs7TL0wg.png" /><figcaption>It all starts with good old-fashioned drawing</figcaption></figure><p>After discussing what we learned through research on a topic, we started concepting with pen and paper, going broad and exploring different angles on a given problem. The big question for the design process was how we could get solutions in front of users as quickly as possible while still making sure that we got genuine reactions. I am personally not a fan of paper prototypes for two reasons: first, we can’t test them remotely, and second, they immediately move people from the role of the user into the role of the critiquer. While that would still be valuable, we were sure that we could get more value out of testing by evolving our concepts into low fidelity mockups right away. In addition, the step of turning our paper sketches into something that looks like software forced us to do one more iteration on each design, often sparking new ideas.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rmzmDjdBsPLTzvhu1TRfVA.png" /><figcaption>Our prototypes aren’t pretty, but they are effective tools for learning</figcaption></figure><p>Since we wanted to move quickly, we couldn’t build an entire browser experience for each feature or test. All our prototypes were <em>vertical</em>, meaning that they allowed users to take one very specific navigation path through them. In order to prevent people from anchoring too much on their current opinions on particular browsers, we also made sure that the prototypes didn’t resemble any major browser too closely.</p><p>Each prototype explored a small domain of ideas and over the past weeks we have developed, tested and iterated in a number of areas. Focusing on qualitative testing of rough prototypes allowed us to move faster, broadening our understanding of both the problem and the solution we’re designing.</p><p>The other approach we used was to test other products with users. When we found that some other software already had implemented a concept similar to what we were exploring, we skipped creating prototypes altogether and instead tested that product with users. This allowed us to gather valuable insights from actual users even faster.</p><p>Using this process, we have learned among other things about the kinds of information that people need the most when making a buying decision, what attitudes to expect towards contextually surfaced content and the different mental models that users had towards saving information.</p><p>We are now at the stage of combining those concepts into something that’s more of a coherent product. This is also the point in the process where we can start exploring some of the interesting interaction ideas that we have been holding back on so far, along with the ones that many of you have been proposing through our various channels.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=af5ad7d54497" width="1" height="1" alt=""><hr><p><a href="https://medium.com/project-tofino/iterations-af5ad7d54497">Iterations</a> was originally published in <a href="https://medium.com/project-tofino">Project Tofino</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Designing a Browser that isn’t a Browser]]></title>
            <link>https://medium.com/project-tofino/designing-a-browser-that-isn-t-a-browser-685b63c4b6f1?source=rss----b6989d965a26---4</link>
            <guid isPermaLink="false">https://medium.com/p/685b63c4b6f1</guid>
            <category><![CDATA[browsers]]></category>
            <category><![CDATA[apps]]></category>
            <category><![CDATA[design]]></category>
            <dc:creator><![CDATA[Philipp Sackl-O’Neill]]></dc:creator>
            <pubDate>Fri, 08 Apr 2016 15:56:40 GMT</pubDate>
            <atom:updated>2016-04-08T16:15:05.259Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*xAVp6Y6OLxrQVtos." /></figure><p>The web is central to our lives — we probably spend more time in our browsers than in our beds. It has changed the way we do so many things — how we communicate, plan, shop, learn, work, and watch movies. At first, browsing, surfing, or going online was a particular activity; now, the web has melted into everyday life. It has evolved, and the web is now simply part of how we live.</p><p>Our behaviours have changed as well. We have moved significant portions of our lives into the cloud, mobile phones have become our most important touch point with technology, and social media and messaging apps have risen to ubiquity.</p><p>On desktop computers and laptops, browsers have changed their role from being one application among many to acting as a meta operating system (and in some cases, as the actual operating system). For many users, it is the only app they are ever starting on their computers, where it will then keep running for days or even weeks. They are home to everything from quick ephemeral interactions, all the way to long running full-blown applications.</p><p>Meanwhile, the fundamental interaction principles of web browsers haven’t changed in the past 20 years. On the one hand, this is remarkable proof of the quality of those UI concepts and the power of incremental improvement. But there is every reason to believe that a tool originally shaped for reading documents isn’t where you would want to start to support today’s workflows and enable new kinds of interactions with the web.</p><p>When you think of a browser today, you’re probably thinking of tabs, a location bar and perhaps a bookmarking system. But are those still the best tools for the jobs we are aiming to accomplish on the web? Maybe they are. Maybe they are not. We want to find out.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*evloYqp3MjWO42cHXsxEyw.png" /><figcaption><em>Some of the earliest sketches for Project Tofino</em></figcaption></figure><p>That’s why we are starting Project Tofino. It is our name for a series of experiments and explorations on what a browser could look like when its fundamental paradigms are invented in 2016 instead of 1996. It is about taking a fresh look at where people struggle on the web, but not being bound to 20 years of legacy when we look for solutions.</p><p>What is it going to look like? We don’t know yet! That’s why we see Project Tofino not as a single product, but rather as a series of experiments. We will use it as a platform to explore radical new ideas that go beyond any existing browser.</p><p>You can follow along on <a href="https://medium.com/project-tofino">Medium</a>, <a href="https://project-tofino.slack.com">Slack </a>(get access <a href="http://tofino-slack-invite.mozilla.io">here</a>) and <a href="https://twitter.com/projecttofino">Twitter</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=685b63c4b6f1" width="1" height="1" alt=""><hr><p><a href="https://medium.com/project-tofino/designing-a-browser-that-isn-t-a-browser-685b63c4b6f1">Designing a Browser that isn’t a Browser</a> was originally published in <a href="https://medium.com/project-tofino">Project Tofino</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Browsers, Innovators Dilemma, and Project Tofino]]></title>
            <link>https://medium.com/project-tofino/browsers-innovators-dilemma-and-project-tofino-ef634c6164f0?source=rss----b6989d965a26---4</link>
            <guid isPermaLink="false">https://medium.com/p/ef634c6164f0</guid>
            <category><![CDATA[firefox]]></category>
            <category><![CDATA[startup]]></category>
            <category><![CDATA[design]]></category>
            <dc:creator><![CDATA[Mark Mayo]]></dc:creator>
            <pubDate>Fri, 08 Apr 2016 00:32:42 GMT</pubDate>
            <atom:updated>2016-04-08T20:49:24.710Z</atom:updated>
            <content:encoded><![CDATA[<p><em>update 08/04: I should have been clearer that Project Tofino is wholly focused on UX explorations and not the technology platform. We are working with the Platform team on technology platform futures too, and we’re excited about the Gecko and Servo-based futures being discussed! Also, don’t forget to check out the companion post from Philipp: </em><a href="https://medium.com/project-tofino/designing-a-browser-that-isn-t-a-browser-685b63c4b6f1#.bagvb8q4x"><em>Designing a Browser that isn’t a Browser</em></a><em>. Finally, go straight to the </em><a href="https://github.com/mozilla/tofino"><em>GitHub repo</em></a><em> for actual project details. Thx!</em></p><p><a href="https://medium.com/art-marketing/content-blocking-is-the-web-at-its-best-71c7eef309bd#.sdhka1w1s">Last time I posted</a>, I talked about Content Blockers. We <a href="https://blog.mozilla.org/futurereleases/2015/12/08/announcing-focus-by-firefox-a-content-blocker-for-ios/">ended up making one</a>, and the world didn’t end. Yay! Blogging helped me sort it out in my own head, and that helped identify a path forward at <a href="https://www.mozilla.com">work</a>. So I’m going to do some more blogging, because I’m kicking off a new project which triggered a bunch of soul searching about products, innovator’s dilemma in particular, and what taking risk feels like. Maybe talking about it will help me sort some of this out. So, here we go.</p><p>Let’s jump right in and say yes, the rumors are true, we’re <a href="https://github.com/mozilla/tofino">working on browser prototypes</a> that look and feel almost nothing like the current Firefox. The premise for these experiments couldn’t be simpler: what we need a browser to do for us —both on PCs and mobile devices — has changed a lot since Firefox 1.0, and we’re long overdue for some fresh approaches. It’s worth noting that we have a <a href="https://wiki.mozilla.org/Firefox/Go_Faster">ton</a> <a href="https://wiki.mozilla.org/Test_Pilot">of</a> <a href="https://wiki.mozilla.org/Firefox/Recipe_Server">work</a> underway on our flagship product, Firefox, that’s all about evolving the browser experience. Not to mention the huge bet we’re making this year that we can get the biggest changes to Gecko we’ve ever attempted (<a href="https://wiki.mozilla.org/E10s">e10s</a>) to land so that Firefox is on a healthy, competitive footing for years to come. But it’s not enough, when someone has a totally different idea they want to explore.</p><p>We’ll blog on the P<a href="https://medium.com/project-tofino">roject Tofino Medium channel</a> about the project itself, but what this and subsequent posts are mostly about is thoughts on what the business of doing “innovation” at an organization that has a lot to lose feels like. It feels hard. Up to this point in my 20 year career (20 years? right?!), I’ve never experienced anything quite so “textbook innovator’s dilemma” as my last year at Mozilla. Let me explain. What’s probably not surprising is that the team that builds our browser has a lot of great insights and ideas about how people actually use browsers and the kinds of problems people have that aren’t currently solved by<em> anybody’s</em> browser product. Also likely not surprising is that said team would be stoked to build an entirely different kind of browser focused on solving those problems. Focus. Freedom. Yes! What’s not intuitive to anybody that hasn’t experienced the backside of a very successful product run is that creating something new and different is incredibly difficult. Every little decision can bring crushing stop energy. At an academic level, this is fascinating. Everyone’s read about this in books. When you live it, it’s very personal. The reason new things at old shops is difficult, mostly, I think, isn’t because people are bad, or stupid, or actively sabotage new projects or any nonsense like that. It’s largely because doing anything that might conceivably impact the current product creates unavoidable tension. Nobody likes tension, so you replace it with that self-created stop energy. <a href="http://www.newyorker.com/magazine/2014/06/23/the-disruption-machine">Innovator’s dilemma is a real thing</a>.</p><p>For example, the prototype we’re feeling good about right now is built with <a href="http://electron.atom.io/">Electron</a> and <a href="https://facebook.github.io/react/">React</a>, not <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Gecko">Gecko</a> and <a href="https://en.wikipedia.org/wiki/XUL">XUL</a> (our go-to technologies for building browsers). For a small team starting out pursuing a new product concept it’s a great choice — Electron is a wonderful tool for us to do prototyping with — but a simple decision like picking the right tool for the job becomes an epic FUD generator when it could be perceived as threatening to the existing product. Immediately, you worry. Does it signal we don’t believe in Gecko? What will the platform team think? Will they believe us that the project has nothing to do with technology selection, that’s what <a href="https://github.com/browserhtml/browserhtml">browser.html</a> is for? What if web developers think we’re abandoning Firefox, and Gecko? We’ll lose on web compat, and nothing will work in Firefox! Consumers will abandon Firefox in droves! We’ll lose our influence at the W3C! OMG the web is dead! I’m not making fun of that. I’ve had all of those thoughts. And spent countless hours thinking about how to deal with the others that will inevitably have them too. Before you know it <em>everybody involved </em>is spending countless hours worrying about about outcomes that we aren’t in control of anyway. Not having an awesome Firefox will kill Firefox. End of story.</p><p>There’s a great deal we don’t know about creativity and innovation. But the research does suggest some patterns are more common than others. You can expect tension. No amount of “messaging” can work your way out of that. The tension will be there, you have to accept it, or you never move. There will be risk. Again, accept it or you never move. You should trust in small, cohesive teams. You should support them, and encourage risk taking. That’s often referred to as “creating space”. My personal experience has been that all these things are true, but I’ve also seen that if you make the innovation process “easy” whatever is being built ends up sucking. Especially at the front end of the process. Maybe it’s because ideas are free to create and valueless on their own. I don’t know.</p><p>In that spirit, today I’m placing a bet on a small, cohesive team that for the last 6 weeks spent hours I know for a fact they didn’t have, hacking on an idea they simply refused to let die. God knows the last month of stop energy should have killed it. Years of fear of hurting Firefox, by rights, should have never even let the idea germinate. But somehow they held on and fought for it.</p><p>We’re setting up the project a little differently too. The team is not open for internal transfer. The team no longer has access to their own calendars. They’re being unsubscribed from all email lists. They’re not going to attend even a single Mozilla meeting. We’re kicking off in person, everyone in a room, in Tofino on Vancouver Island where the idea for this UX direction originated last summer, and from there we’re going to co-locate the core team in Vancouver for 3 months. That’s how much time I’m giving the team to prove there’s something here that we could turn into a product. If not, we kill it. We’re not going to expect help from anyone at Mozilla and we’re not going to distract the other 95% of our team that’s doing hero work on Firefox.</p><p><a href="https://www.youtube.com/watch?v=4Q7FTjhvZ7Y">Origin stories</a> have always fascinated me, and when I look back, a great deal of Firefox’s origin story is not well known. Whether a successful product or feature set comes from this project or not, I can’t say, but I’ll at least document the story of how we’re building new browser experiences inside one of the world’s most experienced browser teams. I’m looking forward to being their story teller!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ef634c6164f0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/project-tofino/browsers-innovators-dilemma-and-project-tofino-ef634c6164f0">Browsers, Innovators Dilemma, and Project Tofino</a> was originally published in <a href="https://medium.com/project-tofino">Project Tofino</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>