Capacitor 4 plugin in upgraded app fails build, no such module Capacitor

I built a new Capacitor plugin, using the V4 model. (on Sunday)
is compiles and checks out fine. no errors

now I want to incorporate into my app, which previously used capacitor 3.

I did the capacitor upgrade from 3 to 4,

and the doctor says I am at the right levels

💊   Capacitor Doctor  💊 

Latest Dependencies:

  @capacitor/cli: 4.4.0
  @capacitor/core: 4.4.0
  @capacitor/android: 4.4.0
  @capacitor/ios: 4.4.0

Installed Dependencies:

  @capacitor/cli: 4.4.0
  @capacitor/android: 4.4.0
  @capacitor/core: 4.4.0
  @capacitor/ios: 4.4.0

[success] iOS looking great! 👌
[success] Android looking great!

the plugin and the app match

i did the ionic build of my project, with no errors
and then the npx cap sync, no errors

then i open the xcode project and build

and the import Capacitor of the little stub swift file fails,

import Foundation
import Capacitor

@objc public class sdxxx: NSObject {
    @objc public func echo(_ value: String) -> String {
        return value

no such module Capacitor

if I comment that out, it fails on the Plugin swift

I haven’t seen any issues like this posted

@jcesarmobile as you mentioned in the issue, I did the npx cap migrate

npm i -D @capacitor/cli@latest
npx cap migrate

all were successful

and it changed all the items listed in the ios section of the upgrade instructions.
ios version, podfile changes pre and post the pod list

I only did this on the app, as the plugin was created in Cap 4 already.

i had just finished migrating the app from Ionic 4 with cap 3 plugins (I had created my own for udp broadcast client) . (late 2021) to 6. and the app builds and runs if I remove the plugin

You’ll have to provide more information if you want to get help.

When creating a plugin, make sure you use @latest on the init command like this npm init @capacitor/plugin@latest, otherwise it can use a cached versions of the plugin creator and create the plugin for Capacitor 3.

yes, used @ latest… trying to build testcase…

dummy app and plugin work, altho get error for import Capacitor in the classnamePlugin file… then xcode says, OH part of Capacitor, ignored… but if u remove it, compile fails.

the import Capacitor is NOT in the generated stub. (classname.swift)… so I think this is different than the doc, creating the screen… plugin)

when I add a plugin that includes a vendor framework, then trouble starts

Can you at least provide how your plugin podspec file looks like?

this is in the root of the ionic capacitor folder for the plugin

require 'json'

package = JSON.parse(, 'package.json'))) do |s| = 'EstimoteUwb'
  s.version = package['version']
  s.summary = package['description']
  s.license = package['license']
  s.homepage = package['repository']['url'] = package['author']
  s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
  s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
  s.ios.deployment_target  = '13.0'
  s.frameworks = "EstimoteProximitySDK", "EstimoteBluetoothScanning"
  s.xcconfig = { "FRAMEWORK_SEARCH_PATHS" => "ios/Plugin/Pods" }
  s.dependency 'Capacitor'
  s.swift_version = '5.1'
  s.vendored_frameworks= "EstimoteProximitySDK.framework"
  s.dependencies= {  "EstimoteBluetoothScanning": [ "~> 1.0.8" ], "EstimoteProximitySDK": [ "~> 1.7.1" ]   }

adding the Estimote sdk

have mercy, I am a neophyte at all things IOS and plugins.

the frameworks were not added by using the sdk pod install instructions.
this was the only setup that made the frameworks appear in the app after inclusion (npm install) of the plugin (IMHO the plugins dependencies should be dragged along, so that the app doesn’t need additional config… nm install should solve that as it does for other libs)

another plugin construction question

what is the stub class (referenced) as implementation ins the classPlugin,
and what is the intended separation between the two?

the stub class doesn’t live in Capacitor, but the xxxPlugin does?

I can’t find documentation about s.dependencies, but looks like if you add it then the existing s.dependency 'Capacitor' gets ignored.

Instead of using s.dependencies, you can use multiple s.dependency entries

s.dependency 'Capacitor'
s.dependency 'EstimoteBluetoothScanning', '~> 1.0.8'
s.dependency 'EstimoteProximitySDK', '~> 1.7.1'

If you are using CocoaPods dependencies, then you don’t have to add the .framework files, so you should remove s.vendored_frameworks= "EstimoteProximitySDK.framework", s.xcconfig = { "FRAMEWORK_SEARCH_PATHS" => "ios/Plugin/Pods" } and s.frameworks = "EstimoteProximitySDK", "EstimoteBluetoothScanning" (also, this last one is for system frameworks, not custom frameworks).
You won’t see the .framework files in your project, but you can still use them.

The implementation class is to move reusable code so it can used from native projects too, but there is no need to use it if you don’t want/need to, you can remove the whole implementation class and just use the plugin class.


if I remove the implementation = …(just comment it out) . line then the xcode builder complains no implementation

as I said for the frameworks, I get EstimoteProxitiySDK not found. (in the plugin and stub class) if I don’t add the frameworks lines… but I’ll try anything…

If you remove/comment the implementation, then you have to remove all the usages of the implementation class from the plugin class, the idea is to have all the needed code in the plugin class, so not call the implementation class that you are going to delete.

I didn’t try to use any of the EstimoteProximitySDK features, but I added import EstimoteProximitySDK to my plugin class and the app compiled with it after doing the changes I mentioned.

ok, I moved everything back to xxxPlugin…
something is looking for the stub file… (can’t delele it , build fails)…

so, NOW, move to the app.

npm install …/plugin project


back to my normal build process

ionic capacitor sync ios

which now fails

../estimote-uwb/package.json » @ionic/eslint-config/recommended » ./index:
	Configuration for rule "@typescript-eslint/explicit-module-boundary-types" is invalid:
	Value {"allowArgumentsExplicitlyTypedAsAny":true} should NOT have additional properties.
    at Array.forEach (<anonymous>)

You may use special comments to disable some warnings.
Use // eslint-disable-next-line to ignore the next line.
Use /* eslint-disable */ to ignore all warnings in a file.
 ERROR  Build failed with errors.
[ERROR] An error occurred while running subprocess vue-cli-service.
        vue-cli-service build exited with exit code 1.

my code is in js, not typescript

:pill: Capacitor Doctor :pill:

Latest Dependencies:

@capacitor/cli: 4.5.0
@capacitor/core: 4.5.0
@capacitor/android: 4.5.0
@capacitor/ios: 4.5.0

Installed Dependencies:

@capacitor/cli: 4.5.0
@capacitor/android: 4.5.0
@capacitor/ios: 4.5.0
@capacitor/core: 4.5.0

[success] Android looking great! :ok_hand:
[error] Could not find the web assets directory: ./dist.
Please create it and make sure it has an index.html file. You can change the path of this directory in
capacitor.config.json (webDir option). You may need to compile the web assets for your app (typically npm run
build). More info: Development Workflow | Capacitor Documentation

I hate that the build fails for this missing folder and file… I put a fake one in and its ok to continue…
i don’t have web or android parts to my app.

i had to edit the node_modules/@ionic/eslint_config settings in the plugin to get rid of that error, commented out the ./index line

now trying to get to the plugin from the app…

ok, app builds a runs, but the plugin is ‘not available’ for some reason

import { EstimoteUWB }  from 'estimote-uwb';

never mind, right there in build output… didn’t find export EstimoteUWB in plugin project… doah
its whatever is exported from the plugin/src/index.ts

now invoking plugin

so, net… editing the podspec, removing the line with the multiple frameworks, which excluded Capacitor, was the primary problem. and making sure the index.ts export matches what the app will use.

ok, another problem…

using the wrong framework…

so switch to the other.
no pod file, have to drag/drop, add to the frameworks in xcode.

the plugin builds ok…

the framework appears in the plugin project… all the files are in the plugin definition.

now npm install the plugin

all good…

go to xcode to build to create the app… and now the framework is not found while compiling the plugin code. which just compiled successfully a minute ago in the plugin project.
so the framework was not copied to the right place … wherever that is…
adding the framework manually to the app does not fix the problem I marked it embed and sign in the plugin

editing my app in visual studio , after adding the plugin import to my vue code, i get editing assistance for the plugin and its methods.

anyone have the magic incantation to make this work?

the real question is why is it compiling the plugin again?