The Native File System API is a new browser API that allows the browser to read and write files and folders on your local computer. The functionality differs from regular uploads and downloads, because the application (site) retains read/write access for as long as you use the application.
This opens up new possibilities: you can now do things in web applications that were previously kludgy, at best. It’s also an important step towards replacing local (native) applications with web-based ones.
The API is not yet finalized. It is currently in the “origin trial” phase in Chrome. You can find a longer introduction to the API at web.dev.
What is an “origin trial”?
Good APIs are hard to design! When the audience is the whole internet, the stakes are even higher. In addition to making the API secure, robust, and easy to use from a developer perspective, it is also important that the end-user understands exactly what’s going on. In this case, the end user is all browser users – you, me, and everyone we know - and they need to appreciate what they are giving the web application permission to do.
To meet the end-user’s needs, real-world use cases are considered and tested. This is exactly what an “origin trial” aims to do; it allows developers to enable the API in their application, before it actually becomes available as a standardized API. During this phase, everyone knows the API is likely to change, while the rough edges are smoothed out.
During the origin trial, developers can get a special key to add to their HTML. The key identifies the site as part of the origin trial, and the API is automatically enabled for site visitors. This allows developers to do real-world tests, potentially with real users, but in a more controlled way. The key will eventually expire and can be revoked by Chrome at any time, should the need arise.
Read Origin Trials Guide for Web Developers to learn more.
Permission dialog headaches
At Vaadin Labs, we’re running an experimental application that uses the Native File System API. You can use this to share and collaborate on projects directly in the browser, without installing anything. You can read more about the project and then try it out.
The experimental application is not a production-grade service. It’s intended to provide insight into how well the API works, for both developers and users.
So far, we have two main findings that are outlined below.
When it comes to dialogs, more is not necessarily better
The first main problem we encountered is the fact that you need to ask for read and write permissions separately.
During our first quick test of the API, we asked for read and write permissions in direct succession, but ran into a strange "auto-denial" problem. This is certainly not the ideal way to ask for permissions from a usability perspective, and it is also a bit of a developer “gotcha”. Simply put, don't do this.
Asking for permission only when you need it (as opposed to asking upfront, just in case) is a very good principle. Making it obvious to the user that “I clicked the button to do X, and now the browser asking for permission to do X”, typically improves the user experience.
However, in some cases, it’s immediately obvious that the application needs multiple permissions in order to fulfill its intended purpose. To design a natural user flow that involves the user clicking a separate button for each permission, can be challenging.
In our opinion, the read+write permission scenario is one of these challenging cases. In fact, we received immediate feedback along the lines of “two permission popups, huh?” There is a GitHub issue for the spec regarding this.
We’ve also been struggling to come up with scenarios that need only write permissions. We have come to the conclusion that read-only and read+write are way more common.
But why not ask for permissions separately, just in case?
First, it may be more complicated than it seems. What if your application needs to ask for the same permission in multiple places? If not granted in advance, you may need to consider usability separately for each instance. You also need to make it clear to the user why the permission is needed for each particular instance
Our example application only needs to ask for write permissions in three places, “Add file”, “Save” and “Share”. We did not make the effort to explain why, even though “Share” is likely to make you pause for thought.
The second reason is “dialog desensitization”, and it is far more important than the first.
With the explosion of permission dialogs on the web, users have become desensitized. When a second, similar-looking popup appears, the user is likely to accept or deny permission prompts, without carefully reading the dialog content. Which way the user sways, depends, among other things, on whether the popup appeared unexpectedly or while they are trying to perform a specific task.
Our argument in this regard is this: Even though read access is very different from write access, the correct solution is not more popups, but rather, better popups.
Better dialogs are better
Popup permission dialogs as implemented today in the origin trial in Chrome are very similar. To illustrate the problem, compare the dialogs below; the first asks for read permissions and the second for write permissions. These appear every now and then in the example application when you click “Open folder”. Would you notice the difference?
A malicious developer could use this to increase the chances of users giving more permissions than they intended. A browser API must take into account that not all developers are ethical.
While this may not be the final dialog design, our argument is, nonetheless, that when it makes sense, one should be able to ask for the two related permissions at the same time. The dialog should make it perfectly clear what is being asked for.
However, this does not mean we can forget about usability patterns when asking for permission; we should still ask for read and write permissions separately when that makes more sense.
In both cases, the dialog displayed should make it clear, at a glance, exactly what the user is consenting to. This can, for instance, be achieved by using iconography and separate descriptions for each permission.
How we think the Native FileSystem API can be improved
Based on our user testing and expert review, here is a summary of our opinions and recommendations:
- We think that the Native File System API should offer the option to ask for read+write permissions.
- It is the browser’s responsibility to make it clear what the user is consenting to; using multiple dialogs has the opposite effect in many instances.
- The dialog displayed should make it clear, at a glance, exactly what the user is allowing. This can, for instance, be achieved by using iconography and separate descriptions for each permission.
- The full path of the file/folder being shared should be indicated.
- The option to ask for permissions separately should remain, but the dialog should display iconography and information similar to that in the “view and modify” dialog above.
- Usability guidelines describing the best approach in each use case should be made available to developers.
We also found in our case that the application needs a way to listen for file system changes. We expect this may be a fairly common need, especially when accessing whole folder structures, and integrating with other tools and workflows.
Still missing: permission persistence
The current implementation in Chrome does not yet have all the features defined in the spec. One major missing feature that needs to be considered when thinking about this API, is the ability to persist permissions.
In the future, web applications should be able to access files or folders the user has given access to, without asking for permission a second time, and regardless of whenever the user visits the application again.
While this makes sense in many cases, it also comes with usability considerations; the user needs to be made aware that the permissions are “persistent”, and they must be able to easily revoke their permission. Maybe a “do not remember” option in the dialog, or even a timeout setting, could make sense?
Please join the discussion, and let’s make the web better, together!