I’m trying to run a trivial Capacitor app that includes the Filesystem plugin, and it seems to build OK but when I run it in Android Studio I see this warning in AS’s logcat:
D Registering plugin instance: Filesystem
W Unable to read file at path public/plugins
… and then, the index.html loads correctly but the JavaScript fails on:
import { Filesystem, Directory, Encoding } from "@capacitor/filesystem"
… generating the logcat message:
File: - Line 827 - Msg: TypeError: Failed to resolve module specifier "@capacitor/filesystem".
So it looks like public/plugins is never created, leading to the failure. I have installed @cordova/filesystem multiple times, and it appears in my package.json (see below). There is indeed no public/plugins anywhere under my app’s root directory, from a find . -name public. If public/plugins is supposed to be created, what normally creates it?
I’m using the latest Vite for bundling (my understanding is that Capacitor requires a bundler, right?). This app was “converted” from the demo Cordova app (as creating a new Capacitor app with npm init @capacitor/app@latestfails as reported here).
My webDir is set to "www" in capacitor.config.json. When I build and run from the command line with npx cap run android, the same thing happens-- index.html loads but the JS doesn’t run.
Before I build and run in Android Studio, I run npx vite build www && npx cap sync. Is this right?
This is all using the latest versions of almost everything, I believe (updated from previous thread):
- MacOS 26.5.2 (M1 on Apple Silicon)
- Android Studio Quail 3 | 2026.1.3
- Android emulator for Pixel 7, API 36.1 (not the latest)
- Gradle 9.6.1
- JVM 21, set everywhere I can find (not the latest)
- Capacitor 8.5.0
- Vite 8.2.0
Relevant files are shown below. Note that some still include artifacts from Cordova.
Thank you for any help!
[This post is a continuation of this thread, put here with newly-found and clearer info because I can’t edit the original.]
Here’s www/index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover">
<meta name="color-scheme" content="light dark">
<link rel="stylesheet" href="css/index.css">
<title>Capacitor + Vite test</title>
<script type="module" src="js/index.js"></script>
</head>
<body>
Capacitor + Vite test
</body>
</html>
Here’s www/js/index.js:
import { Filesystem, Directory, Encoding } from "@capacitor/filesystem";
alert('starting Capacitor app') ;
let lib= await Filesystem.stat({
directory: Directory.Library,
path: '.',
}) ;
alert(lib) ;
Here’s capacitor.config.json:
{
"appId": "com.jmarshall.testcapvite",
"appName": "TestCapacitorVite",
"webDir": "www"
}
Here’s package.json:
"name": "com.jmarshall.testcapvite",
"displayName": "TestCapacitorVite",
"version": "1.0.0",
"description": "A sample Apache Cordova application that responds to the deviceready event.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"ecosystem:cordova"
],
"author": "Apache Cordova Team",
"license": "Apache-2.0",
"devDependencies": {
"@capacitor/cli": "^8.5.0",
"cordova-android": "^15.1.0",
"vite": "^8.1.5"
},
"cordova": {
"platforms": [
"android"
]
},
"dependencies": {
"@capacitor/android": "^8.5.0",
"@capacitor/core": "^8.5.0",
"@capacitor/filesystem": "^8.1.2"
}
}