Create Free APK

Device features

Native Folder Access

Use SAF-backed local folders from WebView and offline HTML apps

AppMintAppwrightBoth builders - the steps below are the same in each.

I am using

1What This Feature Does#

This feature gives your web app controlled access to one user-picked Android folder using the Storage Access Framework (SAF). It works well for offline HTML apps, editors, backup/restore flows, and import/export tools.

It does NOT give unrestricted device storage access. The user explicitly chooses one folder, and your app can only work inside that granted tree.

2Enable in the Generator#

In Step 4 of the generator, turn ON 'Native Folder Access (SAF)'. Then generate the app.

When enabled, your website gets a high-level helper at window.WebToApkFS in addition to the raw window.WebToApk bridge.

⚠️ Android 11+ Storage Note: On Android 11 and above, reading the shared storage requires the special 'All Files Access' permission. When your generated app launches for the first time and the storage permission is enabled, it automatically opens the Android Settings screen to let the user grant this permission. The user just taps the toggle in Settings and returns to the app - no manual navigation required.

3Browser-Safe Capability Check#

Always guard your code so it still runs in Chrome/Safari where the Android bridge does not exist:

function canUseNativeFiles() {
  return !!(window.WebToApkFS && window.WebToApkFS.isAvailable());
}

if (canUseNativeFiles()) {
  console.log('Android native folder access available');
}

4Ask User to Pick a Folder#

Call requestAccess() from a button click or other clear user action. It opens Android's folder picker and returns the chosen folder URI.

async function connectFolder() {
  const result = await window.WebToApkFS.requestAccess();
  if (!result.success) {
    alert('Folder access was not granted');
    return false;
  }
  console.log('Granted folder:', result.folderUri);
  return true;
}

5Basic File Operations#

Once access is granted, you can list folders, create directories, read text files, write text files, rename entries, and delete entries.

// Create folders
window.WebToApkFS.mkdir('notes');
window.WebToApkFS.mkdir('notes/2026');

// Write a file
window.WebToApkFS.writeText('notes/2026/today.txt', 'Hello from offline app');

// Read it back
const text = window.WebToApkFS.readText('notes/2026/today.txt');
console.log(text);

// List folder contents
const entries = window.WebToApkFS.list('notes/2026');
console.log(entries);

6Rename and Delete#

Rename changes only the final entry name. Delete supports both non-recursive and recursive directory deletion.

// Rename file or folder
window.WebToApkFS.rename('notes/2026/today.txt', 'journal.txt');

// Delete a single file
window.WebToApkFS.delete('notes/2026/journal.txt');

// Delete a folder tree
window.WebToApkFS.delete('notes/2026', { recursive: true });

7Good Use Cases#

✅ Offline note or journal apps
✅ CSV / JSON import-export tools
✅ Simple local backup and restore
✅ Static HTML editors that save user content
✅ Dashboard apps that export reports as text or CSV

8Limitations#

⚠️ This is Android-only. It will not exist in normal desktop/mobile browsers.

⚠️ Current helper is designed around folder listing and text files. Binary workflows need additional APIs.

⚠️ Access is scoped to the one folder the user granted.

⚠️ Call these APIs after the page is loaded so the helper has been injected.

9Full Working Example#

This example connects a folder, creates a workspace directory, writes a JSON file, and renders the folder listing:

async function setupWorkspace() {
  if (!window.WebToApkFS || !window.WebToApkFS.isAvailable()) {
    console.log('Native folder access not available in this browser');
    return;
  }

  if (!window.WebToApkFS.hasAccess()) {
    const granted = await window.WebToApkFS.requestAccess();
    if (!granted.success) return;
  }

  window.WebToApkFS.mkdir('workspace');
  window.WebToApkFS.writeText(
    'workspace/config.json',
    JSON.stringify({ updatedAt: new Date().toISOString(), mode: 'offline' }, null, 2)
  );

  const files = window.WebToApkFS.list('workspace');
  document.getElementById('output').textContent = JSON.stringify(files, null, 2);
}

This page is generated from the Integration Guide inside the app itself, so it says exactly what the current build says. Read it as Markdown.

Checked against the shipped guide on 2026-09-09.