Build cross-platform Native Progressive Web Apps for iOS, Android, and the Web ⚡️
This report summarizes scanner evidence for ionic-team/capacitor, a TypeScript project with 17,009 GitHub stars. SynthScan examined 52,007 lines of code across 387 source files, recording 78 pattern matches distributed across 10 syntactic categories. The legacy adjusted pattern signal is 2.1 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 68 finding(s).
Are imports declared and package/API names verified? 5 finding(s).
Are wrappers, guards, and repeated structures necessary? 46 finding(s).
Which changes need focused human review? 78 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 78 distinct pattern matches across 10 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | core/cordova.js | 477 | function assignOrWrapInDeprecateGetter(obj, key, value, message) { | CODE |
| LOW | core/cordova.js | 683 | function checkSubscriptionArgument(argument) { | CODE |
| LOW | core/cordova.js | 883 | function convertMessageToArgsNativeToJs(message) { | CODE |
| LOW | cli/test/migrate-uiscene-scene-delegate.spec.ts | 91 | function stripConfigurationForConnecting(source: string): string { | CODE |
| LOW | cli/src/plugin.ts | 45 | export function getIncludedPluginPackages(config: Config, platform: string): readonly string[] | undefined { | CODE |
| LOW | cli/src/common.ts | 248 | export async function getCapacitorPackageVersion(config: Config, platform: string): Promise<string> { | CODE |
| LOW | cli/src/common.ts | 273 | export async function getProjectPlatformDirectory(config: Config, platform: string): Promise<string | null> { | CODE |
| LOW⚡ | cli/src/common.ts | 319 | export async function getKnownCommunityPlatforms(): Promise<string[]> { | CODE |
| LOW⚡ | cli/src/common.ts | 327 | export async function getKnownEnterprisePlatforms(): Promise<string[]> { | CODE |
| LOW⚡ | cli/src/common.ts | 331 | export async function isValidEnterprisePlatform(platform: string): Promise<boolean> { | CODE |
| LOW | cli/src/cordova.ts | 32 | export function generateCordovaPluginsJSFile(config: Config, plugins: Plugin[], platform: string): string { | CODE |
| LOW | cli/src/cordova.ts | 532 | export function getIncompatibleCordovaPlugins(platform: string): string[] { | CODE |
| LOW | cli/src/cordova.ts | 622 | export async function writeCordovaAndroidManifest( | CODE |
| LOW | cli/src/config.ts | 335 | async function determineXcodeWorkspaceDirAbs(nativeProjectDirAbs: string): Promise<string> { | CODE |
| LOW | cli/src/config.ts | 368 | async function determineAndroidStudioPath(os: OS): Promise<string> { | CODE |
| LOW | cli/src/tasks/migrate.ts | 341 | async function checkCapacitorMajorVersion(config: Config): Promise<number> { | CODE |
| LOW | cli/src/tasks/migrate.ts | 422 | async function getAndroidVariablesAndClasspaths(config: Config) { | CODE |
| LOW | cli/src/tasks/migrate-uiscene.ts | 218 | function extractConfigurationForConnecting(appDelegateSource: string): string | null { | CODE |
| LOW | cli/src/tasks/migrate-uiscene.ts | 242 | function insertBeforeAppDelegateClassEnd(source: string, snippet: string): string | null { | CODE |
| LOW | cli/src/tasks/open.ts | 48 | function createOpenablePlatformFilter(config: Config): (platform: string) => boolean { | CODE |
| LOW | cli/src/tasks/run.ts | 143 | function createRunnablePlatformFilter(config: Config): (platform: string) => boolean { | CODE |
| LOW | cli/src/tasks/build.ts | 81 | function createBuildablePlatformFilter(config: Config): (platform: string) => boolean { | CODE |
| LOW | cli/src/util/spm.ts | 54 | export async function checkPluginsForPackageSwift(config: Config, plugins: Plugin[]): Promise<Plugin[]> { | CODE |
| LOW | cli/src/util/spm.ts | 70 | export async function extractSPMPackageDirectory(config: Config): Promise<void> { | CODE |
| LOW | cli/src/util/spm.ts | 222 | export async function addInfoPlistDebugIfNeeded(config: Config): Promise<void> { | CODE |
| LOW | cli/src/util/spm.ts | 304 | export async function checkPackageTraitsRequirements(config: Config): Promise<string | null> { | CODE |
| LOW | cli/src/util/monorepotools.ts | 75 | export function findPackageRelativePathInMonorepo(packageName: string, currentPath: string): string | null { | CODE |
| LOW | cli/src/util/npm.ts | 75 | export function parseBlockedInstallScripts(commandOutput: string | null): BlockedInstallScript[] { | CODE |
| LOW | cli/src/util/npm.ts | 119 | export function hasBlockedCapacitorScripts(blocked: BlockedInstallScript[]): boolean { | CODE |
| LOW | cli/src/ios/update.ts | 98 | async function generateCordovaPackageFiles(cordovaPlugins: Plugin[], config: Config) { | CODE |
| LOW | cli/src/ios/update.ts | 104 | async function generateCordovaPackageFile(p: Plugin, config: Config) { | CODE |
| LOW | cli/src/ios/update.ts | 253 | async function writeGeneratedPackageSwift(p: Plugin, config: Config, iosPlatformVersion: string) { | CODE |
| LOW | cli/src/ios/update.ts | 356 | async function getRelativeCapacitoriOSPath(config: Config) { | CODE |
| LOW | cli/src/ios/update.ts | 703 | async function replaceFrameworkVariables(config: Config, prefsArray: any[], frameworkString: string) { | CODE |
| LOW | cli/src/android/common.ts | 52 | export async function editProjectSettingsAndroid(config: Config): Promise<void> { | CODE |
| LOW | cli/src/android/update.ts | 84 | async function findAndroidPluginClassesInPlugin(plugin: Plugin): Promise<PluginsJsonEntry[]> { | CODE |
| LOW | cli/src/android/update.ts | 224 | export async function handleCordovaPluginsGradle(config: Config, cordovaPlugins: Plugin[]): Promise<void> { | CODE |
| LOW | cli/src/android/update.ts | 386 | async function replaceFrameworkVariables(config: Config, prefsArray: any[], frameworkString: string) { | CODE |
| LOW | …s/Capacitor/Capacitor/Plugins/HttpRequestHandler.swift | 52 | open class HttpRequestHandler { | CODE |
| LOW | …/src/main/java/com/getcapacitor/plugin/SystemBars.java | 44 | function capacitorSystemBarsCheckMetaViewport() { | CODE |
| LOW | …a/com/getcapacitor/plugin/util/HttpRequestHandler.java | 31 | public class HttpRequestHandler { | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | cli/src/ios/doctor.ts | 1 | import { check, checkWebDir } from '../common'; | COMMENT |
| LOW | cli/src/android/add.ts | 21 | ## This file is automatically generated by Android Studio. | COMMENT |
| LOW | ios/Capacitor/Capacitor/Capacitor.h | 1 | #import <UIKit/UIKit.h> | COMMENT |
| LOW | ios/Capacitor/Capacitor/KeyValueStore.swift | 1 | // | COMMENT |
| LOW | ios/Capacitor/Capacitor/KeyValueStore.swift | 21 | /// | COMMENT |
| LOW | ios/Capacitor/Capacitor/KeyValueStore.swift | 41 | /// | COMMENT |
| LOW | ios/Capacitor/Capacitor/KeyValueStore.swift | 61 | /// | COMMENT |
| LOW | ios/Capacitor/Capacitor/KeyValueStore.swift | 81 | /// [NSFileWriteOutOfSpaceError](https://developer.apple.com/documentation/foundation/1448136-nserror_codes/nsfile | COMMENT |
| LOW | ios/Capacitor/Capacitor/KeyValueStore.swift | 141 | try backend.delete(key) | COMMENT |
| LOW | ios/Capacitor/Capacitor/CAPInstancePlugin.swift | 1 | // | COMMENT |
| LOW | ios/Capacitor/Capacitor/Codable/JSValueEncoder.swift | 1 | // | COMMENT |
| LOW | ios/Capacitor/Capacitor/Codable/JSValueDecoder.swift | 1 | // | COMMENT |
| LOW | …acitor/CapacitorTests/CapacitorTests-Bridging-Header.h | 1 | // | COMMENT |
| LOW | …s/CapacitorCordova/CapacitorCordova/CapacitorCordova.h | 1 | #import <UIKit/UIKit.h> | COMMENT |
| LOW | …s/CapacitorCordova/CapacitorCordova/CapacitorCordova.h | 21 | #import <Cordova/CDVScreenOrientationDelegate.h> | COMMENT |
| LOW | …torCordova/CapacitorCordova/Classes/Public/CDVPlugin.m | 61 | // You can listen to more app notifications, see: | COMMENT |
| LOW | …dova/CapacitorCordova/Classes/Public/CDVAvailability.h | 21 | COMMENT | |
| LOW | …dova/CapacitorCordova/Classes/Public/CDVAvailability.h | 41 | #define __CORDOVA_2_5_0 20500 | COMMENT |
| LOW | …dova/CapacitorCordova/Classes/Public/CDVAvailability.h | 61 | #define __CORDOVA_4_1_0 40100 | COMMENT |
| LOW | …dova/CapacitorCordova/Classes/Public/CDVAvailability.h | 101 | COMMENT | |
| LOW | …CapacitorCordova/CapacitorCordova/Classes/Public/CDV.h | 21 | #import "CDVPlugin.h" | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | cli/src/cordova.ts | 204 | config.app.extConfig.cordova.accessOrigins.map(async (host): Promise<string> => { | CODE |
| CRITICAL | cli/src/ios/update.ts | 581 | return `\n s.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '${config.app.extConfig.ios.cordovaLinkerFlags.join( | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | ios/Capacitor/Capacitor/JSExport.swift | 179 | CAPLog.print("Error: plugin method return type \(returnType) is not supported!") | STRING |
| MEDIUM | ios/Capacitor/Capacitor/JSExport.swift | 205 | CAPLog.print("Error while enumerating files") | STRING |
| MEDIUM | ios/Capacitor/Capacitor/CapacitorBridge.swift | 343 | CAPLog.print("Error registering plugins: \(error)") | CODE |
| MEDIUM | ios/Capacitor/Capacitor/CapacitorBridge.swift | 571 | CAPLog.print("Error: Plugin \(plugin.className ?? "") does not respond to method call \(selector).") | STRING |
| MEDIUM | ios/Capacitor/Capacitor/CapacitorBridge.swift | 584 | CAPLog.print("Error: Cordova Plugin mapping not found") | STRING |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | …d/capacitor/src/main/java/com/getcapacitor/Plugin.java | 573 | * @deprecated use {@link #requestAllPermissions(PluginCall, String)} in conjunction with @CapacitorPlugin | COMMENT |
| MEDIUM | …d/capacitor/src/main/java/com/getcapacitor/Plugin.java | 586 | * @deprecated use {@link #requestPermissionForAlias(String, PluginCall, String)} in conjunction with @CapacitorPlug | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | cli/test/migrate-uiscene-scan.spec.ts | 27 | print("received url: \\(url)") | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | cli/src/android/add.ts | 21 | ## This file is automatically generated by Android Studio. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | ios/Capacitor/Capacitor/CAPInstanceDescriptor.swift | 24 | The purpose of this function is to hide the messy details of parsing the configuration(s) so | CODE |
| LOW | …/Capacitor/Capacitor/Plugins/CapacitorUrlRequest.swift | 26 | // We need to check if the JSON is valid before attempting to serialize, as JSONSerialization.data will not thro | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | ios/Capacitor/CodableTests/NestedCodableTests.swift | 18 | "fullName": "John Doe" | CODE |
| LOW | ios/Capacitor/CodableTests/NestedCodableTests.swift | 29 | fullName: "John Doe", | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/publish-android.sh | 20 | # Check if we need to publish a new native version of the Capacitor Android library | COMMENT |