- file:/// allows you to navigate the local file system from the browser in Windows y Android.
- The File System Access API offers advanced read and write capabilities to local files and directories.
- Security is based on explicit user permissions and clear control over which routes are exposed.
- There are polyfills and libraries that combine this API with classic methods when there is no native support.

Using the browser as if it were a small file explorer is possible and, if used properly, can be extremely useful. From opening a simple local document with file:/// to working with the powerful File System Access APINowadays, modern browsers offer many more possibilities than we usually use.
Throughout this guide we will see, step by step, how to open local files in the Web navigator using file:/// in Chrome, Edge and FirefoxHow to turn your browser into a basic file explorer on Windows and Android, and how developers can go a step further using the File System Access API to read, write, and manage local files and folders from a web application.
What does it really mean to open local files with file:///
When you write a route that starts with file:/// in the browser's address bar, You're telling the browser to access the local file system instead of the internet.That is, to open something that is on your own device: a hard drive, internal memory, or an SD card.
This special URL scheme (file:///) It works similarly to typing C: in Windows or / in Linux and macOSIt's just adapted to the browser's logic. From there, what you'll see is a kind of list of folders and files, without any frills: names, sizes, modification date, and little else.
Of course, it must be borne in mind that Browsers treat these local routes with many security restrictions.For example, a website you visit from the internet cannot, by default, freely read your local files just because you open a URL with file:///An explicit gesture or permission from the user is always required.
Using the browser as a file explorer on Android
Many Android phones don't include a decent file manager from the manufacturer, or the one that comes pre-installed is rather limited. In those cases, Using Chrome, Edge, or another Chromium-based browser as a makeshift browser can get you out of a bind..
The trick is very simple: Open your Chromium-based browser (Chrome, Edge, Brave, etc.) and type in the address bar file: /// sdcard /Android identifies the storage main internal as sdcard, in a very similar way to how Windows uses C: for the main drive.
When you launch that address, the browser will usually ask for permission to read the internal storage. Once you grant that permission, an index will appear showing the root folders of your internal memory.From there you can enter and exit folders exactly as if you were browsing a website with links.
In each folder you will see both subfolders and files. Files are displayed with their full name, including the extension, their size, and the last modification date.The following are also listed: hidden folders, which in Android usually begin with a period, like .nomedia or other similar ones.
Although the list is very spartan, Most modern browsers are able to directly open many types of files by tapping them.Images, videos, audio, text documents, etc. There are no thumbnails or previews, but simply clicking on the file name will cause the browser to attempt to display or play it.
Turn Chrome and Edge into a small file explorer on your PC
On desktop computers, both on Windows and other systems, You can also use Chrome, Edge, and other Chromium-based browsers to navigate your local drives with file:///The principle is the same as in Android, but the path is different.
If you use Windows, the primary drive is most commonly C:. In that case, type in the address bar file:///C: and press EnterThe browser will show you the contents of the root of that drive: folders such as Windows, Program Files, Usuarios, etc.
If you have more drives or partitions, You can replace the letter in the URL with the corresponding one.. For example, file:///D: for another album or file:///E: for a memory USB that it was mounted with that letter. From there, click on the folders to move forward and use the browser's back button to go back.
Just like on Android, In each folder you will see files and subfolders with size, modification date and extension visibleIt doesn't generate thumbnails or pretty icons, but it's sufficient for locating a specific file or getting a quick overview of a directory structure.
Most Chromium browsers They allow you to directly open multimedia files and even some document formats. Simply by clicking on them. Images, videos, audio, or plain text files are displayed quite naturally within the tab.
Open local files in Chrome and Firefox without manually typing file:///
In addition to typing routes with file:///Browsers include shortcuts designed specifically to quickly open local files. In Chrome, for example, you can use the keyboard shortcut Ctrl + O (Control + O) when the browser window is active.
By pressing that shortcut, The operating system's typical "Open File" dialog box opensSimply find the file you want, select it, and confirm. Chrome will load it in the current tab or a new one, depending on the file type and your preferences.
Firefox offers several options. On the one hand, You can go to the main menu and choose the "Open file..." optionwhich does exactly the same thing: display the system's file selection window. Alternatively, you can directly type a path like this into the address bar: file:///// so that the browser starts by displaying the contents of drive C: in Windows.
With any of these methods, The practical result is that the browser becomes a local file viewer.It can help you when the Windows Explorer It freezes when you have problems with the usual file manager or simply when you want to open a type of document that the browser handles particularly well.
The File System Access API: the leap from viewer to editor
Everything we have seen so far is based on the "manual" use of file:/// and the open file dialog boxes, that is, things that the user does manually. But for some time now, Chromium-based browsers have incorporated the File System Access API, which gives web applications the ability to work with local files in a much more advanced way.
This API allows a website, after requesting your permission, Read and save changes directly to files and folders on your deviceThanks to this, serious text editors and IDEs can be created directly from the browser. programming, photo and video editors, project managers and many other tools that previously only made sense to develop as desktop applications.
It is important not to confuse this modern API with older or obsolete ones. It's not the same as the interface FileSystem nor the File and Directory Entries API nor the old “File API: Directories and System” specification, which proposed other mechanisms for handling file hierarchies and sandbox storage areas.
The current File System Access API It has been designed with special care in terms of security, permissions and user experience.It always requires explicit actions (such as clicking a button) to open the file or directory selector, and the user is always clear about the exact paths they are granting access to.
As for compatibility, The API works in most Chromium-based browsers on Windows, macOS, Linux, ChromeOS, and AndroidA notable exception is Brave, where it's still necessary to activate a flag to use it. Other non-Chromium browsers may not implement it or may do so only partially.
Check if the browser supports the File System Access API
As a developer, the first thing you want to know is whether the user's browser supports this API before attempting to use it. The simplest way is to check if the corresponding file selection methods exist in the global object.for example, by checking if showOpenFilePicker is available from window (o self in a worker).
The typical pattern consists of something like this: “If 'showOpenFilePicker' is set to self, then I can use the API; otherwise, I must resort to an alternative method.”This allows for the implementation of hybrid solutions where, if there is support, the advantages of the API are leveraged, and if there is no support, traditional techniques such as file upload forms are used.
It's also a good idea Test on the target browsers and on different OSBecause even though the base is Chromium, some manufacturers may enable or disable specific features for security, policy, or performance reasons.
First example: opening a local file from a web app
One of the canonical examples for understanding this API is building a a single-file text editor that allows you to open, modify, and save a documentIt doesn't need to be spectacular: as long as it reads and writes plain text, it already illustrates how it works.
The entry point here is the method window.showOpenFilePicker(). This method, which can only be called in a secure context (HTTPS) and in response to a user gestureIt displays a native dialog for the user to choose a file. Once selected, it returns an array of handles, typically with a single FileSystemFileHandle.
That handle stores all the information and methods necessary to work with the chosen file. It's a good idea to save a reference to the handle, because that's what you'll use later to read the file, save changes, or perform any other operation.As long as you maintain that handle and the user hasn't revoked permissions, your app will be able to interact with the file.
Once you have the FileSystemFileHandle, you can obtain the object File real calling handle.getFile()This object File It contains the file's data as a blob, and you can access its contents using methods such as text(), arrayBuffer(), stream() o slice() if you need random access.
In practice, for a simple text editor, the usual thing is to use file.text() to obtain the complete content as a stringand put that text into a <textarea> so that the user can edit it. It's important to note that the object File It ceases to be valid if the file is modified on disk by another means, in which case it is advisable to call again. getFile().
Save changes: write to the local file system
To save what the user has edited, the API offers two typical paths: a "simple" save that overwrites the original file and a "Save As" that creates a new fileThe fundamental difference is whether you already have a handle to the destination file or if you need the user to choose a new path and name.
When you want to create a new file or save a copy with a different name, you should use showSaveFilePicker()This method opens the file selector in saved mode, allowing the user to specify the name, folder, and extension. You can provide options to suggest file types, for example, indicating that it's a text document and that the preferred extension is . .txt.
An important detail is that You should call showSaveFilePicker() directly in response to the user's gesture (for example, clicking the "Save" button) and don't delay it while you're doing heavy processing. If you do all the preliminary work and then, with a delay, try to open the dialog, the browser might throw a security error because it no longer considers that you're "handling a user gesture."
Once you have a FileSystemFileHandle pointing to the file where you want to save, The next step is to create a FileSystemWritableFileStream using fileHandle.createWritable()This stream is the one you'll use to write the data. If the browser detects that you don't yet have write permission, it will display a permissions dialog; if the user denies it, the call will throw an exception.
With the stream in hand, You simply call writable.write(contenido) with a string, a Blob, or a BufferSourceYou can even directly pipe the body of an HTTP response into the stream with response.body.pipeTo(writable)When you finish typing, you close the transmission with writable.close(), which is the moment when the changes are consolidated on disk.
While the stream is open, you can also use methods such as seek() o truncate() to move the write pointer to a specific position or change the file sizeBut it's important to remember that the changes aren't permanently applied until the stream is closed.
Suggest filename and home folder to the user
The API also takes care of the user experience in system dialog boxes. For example, You can specify a suggested filename when you call showSaveFilePicker()This allows the user to see something more descriptive, such as "New Document.txt," instead of a generic "No Title".
Similarly, It is possible to suggest an initial folder where the file picker starts.This is done by passing a property startIn when you call showSaveFilePicker(), showOpenFilePicker() o showDirectoryPicker()The values can be strings like desktop, documents, downloads, music, pictures o videos, which correspond to standard system locations.
Also, you have the option of use as a value of startIn a file or directory manager that you already haveIn that case, the dialog box opens directly in the folder where that handle resides, which is very convenient for resuming the working context of the last session.
If your application handles different types of files (for example, text documents and embedded images), You can define different IDs for each type of dialog boxThis way, the browser will remember the last used folder independently for each ID, and you won't mix up document paths with image paths.
Remember recent files and folders with IndexedDB
One of the strengths of File System Access is that its handlers are serializable. This means you can store FileSystemFileHandle y FileSystemDirectoryHandle in IndexedDB and retrieve them in subsequent sessions, always respecting the permissions policy.
Thanks to this, web applications can offer typical desktop functionalities such as lists of recent files, reopening the last project, or recovering the previous working folderYou just need to save the handles in the browser's database and read them when the app starts.
When you retrieve a stored handle, Don't assume that the permits will remain in place.The browser may decide that authorization needs to be requested again, for example, because time has passed or the last tab from that source has been closed. Therefore, it's recommended that your code checks for this.
For this check, The API includes the methods queryPermission() y requestPermission() both in file and directory handlersFirst, you ask what status the permission is in, and if it is not "granted", you can request it again from the user, indicating in the options whether you need read only or read and write.
A good practice is combine both steps into one help function Given a handle and a mode (read-only or read/write), it should check if permission is already granted and, if not, display the corresponding prompt. This reduces the number of dialogs and makes the experience smoother.
Open and browse entire directories from the browser
In addition to individual files, the API allows working with entire folders. With showDirectoryPicker() the user can select a complete directoryand the application receives a FileSystemDirectoryHandle which gives access to all its elements.
By default you will have read permission on the files in that directory, although if you need to write to them as well You can request read and write access by passing { mode: 'readwrite' } when calling showDirectoryPicker()From that moment on, your app can list and manipulate the content according to the permission granted.
To navigate through the folder, You can iterate asynchronously over dirHandle.values()which returns, one by one, the elements it contains: files and subdirectories. Each entry has a property kind which tells you if it is a "file" or "directory".
If you need to access information about each file, such as its size, you can call entry.getFile(). In these cases, it is recommended to run the readings in parallel using Promise.all() or similar techniques, instead of going one by one in a strictly sequential manner, which can be slower.
You can also do this from a directory create new folders or files with getDirectoryHandle() y getFileHandle()You can specify in the options whether you want them to be created if they don't already exist. For example, you can set up a project structure like "My Project / Code / Notes.txt" directly from the web application.
Manage files: delete, rename, and move
The API is not limited to reading and writing. It also allows you to delete files and folders from a directory using removeEntry() over a FileSystemDirectoryHandleIf it's a folder, you can make the deletion recursive, so that it includes all its subfolders and files.
If instead of going through the directory you want to act directly on a file or folder handle, Some browsers offer this method remove() en FileSystemFileHandle y FileSystemDirectoryHandleThis way you remove that element without needing to refer to its name within the parent directory.
For organizational operations such as renaming or moving items to another folder, There is a method move() in the interface FileSystemHandleYou can directly pass it a new name, a destination directory, or a directory plus the new name to move and rename at the same time.
However, there are nuances to compatibility: the support of move() It is more mature for files within the source private file system (OPFS)and may still be behind flags or not implemented for all scenarios or for directories in certain browsers.
Drag and drop files and folders to the web
The File System Access API integrates very well with HTML's drag-and-drop system. When the user drags files or folders from the operating system to a web pagethe browser creates elements DataTransferItem associates.
Through the method DataTransferItem.getAsFileSystemHandle(), you can get a FileSystemFileHandle whether the element is a file or a FileSystemDirectoryHandle if it's a directoryThus, an app can allow the user to drag and drop an entire folder of photos and work directly on its contents.
You should keep in mind that, in the context of drag and drop, DataTransferItem.kind It will always be "file" for both files and foldersYou will obtain the distinction between file and directory by consulting the property kind of the FileSystemHandle that gives you back getAsFileSystemHandle()which will differentiate between "file" y "directory".
Private Source File System (OPFS) and optimized access
In addition to access to the user's files and folders, Chromium browsers offer a origin private file system (OPFS)This is a storage space dedicated to each website, not directly accessible by the user from the operating system.
In practice, this means that Although the browser internally stores this data on disk, the user will not find it as "normal" files in any old folder.This could be a database, packaged files, or any internal structure that the browser deems appropriate.
From the API you can access the root of this private system using navigator.storage.getDirectory(), which returns a FileSystemDirectoryHandle. From there you can create files and directories, read them, write to them, rename them or delete them just as if they were elements of the local file systemBut knowing that they are isolated and dedicated exclusively to your web application.
For more advanced performance needs, Chromium incorporates a special type of file with optimized synchronous access. Through fileHandle.createSyncAccessHandle() (available in workers), you can get a handle that allows synchronous and exclusive reading and writing, which is useful for very intensive or latency-sensitive use cases.
Obtaining the handle is still asynchronous, but once you have it, Read and write operations are performed as direct calls, manipulating byte buffers.This comes very close to the performance of a native application, but without leaving the web environment and maintaining isolation from the private source system.
Polyfills and alternatives when there is no native support
Although the File System Access API offers many possibilities, Not all browsers support it yetIt is not possible to create a complete polyfill that replicates all of its capabilities, mainly because there is no way to reliably simulate native file system access without the cooperation of the browser itself.
However, some parts can be approximated. To emulate showOpenFilePicker() a simple <input type="file">, which displays the file selection box and allows the user to choose one or more files.
Something similar happens with saving. To imitate showSaveFilePicker() a link is often used <a download="nombre"> Clicking it initiates the download of a Blob generated from JavaScript. This allows you to "save" data generated by the website, although it doesn't offer the option to overwrite existing files.
Regarding selecting entire directories, the non-standard attribute has traditionally been used webkitdirectory en <input type="file">which allows you to choose a folder and receive a list of the files it contains. It is not a universal solution nor as powerful as showDirectoryPicker()but it covers some cases.
To unify these approaches, There are bookstores like browser-fs-access They try to use the modern API whenever it's available, and if not, they automatically fall back to these better alternatives.In this way, the developer writes relatively uniform code and the library takes care of adapting to the environment.
Security, permissions and user control
All this power comes with responsibilities, and browser teams are very aware of this. The design of the File System Access API revolves around two principles: user control and transparency.There's no way a website can secretly read half a hard drive.
When the user opens a file using the selection boxes (either to read or to save a new one), It is that gesture that grants read or write permission on the specific file or folderIf the user changes their mind and cancels the dialogue, the website receives nothing and therefore does not gain any access.
To save a new file, click the “Save” box It not only allows you to choose a name and path, but also serves as a grant of write permission on that newly created file.The logic is the same as that used for years in elements such as <input type="file">but extended with more capabilities.
When a web application wants to modify a file that already exists, It cannot simply do so; the browser may display a specific notice asking for permission to write to it.This dialog can only be opened in response to a user action, such as pressing a "Save changes" button.
If the user decides not to grant that write permission, The website must offer some alternative: downloading a copy, saving to the cloud, working in OPFS, or another similar mechanism.The idea is that the user always has the final say on what is touched on their local system.
In terms of transparency, Browsers display an icon in the address bar when a website has access to local filesIf the user clicks on that icon, they will see a list of the files or folders that the page has access to at that moment and can revoke permissions whenever they want.
Permits are not permanent. Generally, a page retains the ability to continue saving files only as long as at least one tab from that source is open.Once all of them are closed, the browser may consider that the session is over and, on the next use, it will be necessary to request permission again for those files or directories.
Combining the file:/// scheme to open specific resources, the keyboard shortcuts to upload local files and the File System Access API for deep integrations This makes the browser a much more versatile tool for both users and developers.allowing you to quickly view a video saved on disk or edit entire projects without leaving the web environment.
Passionate writer about the world of bytes and technology in general. I love sharing my knowledge through writing, and that's what I'll do on this blog, show you all the most interesting things about gadgets, software, hardware, tech trends, and more. My goal is to help you navigate the digital world in a simple and entertaining way.