Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
cap-go avatar

Capacitor Best Practices

  • 634 installs
  • 57 repo stars
  • Updated July 13, 2026
  • cap-go/capgo-skills

This is a copy of capacitor-best-practices by cap-go - installs and ranking accrue to the original listing.

Capacitor Best Practices is a mobile development skill that applies production-grade Capacitor guidelines for project structure, plugins, performance, security, and app store deployment when developers build or review hy

About

Capacitor Best Practices is a comprehensive agent skill from cap-go/capgo-skills that encodes guidelines for production-ready Capacitor applications. It covers recommended directory layout, plugin selection and usage, performance optimization, security hardening, and app store submission preparation. Developers invoke it when setting up a new Capacitor project, reviewing existing Capacitor architecture, optimizing runtime performance, or preparing a release candidate for iOS and Android stores. The skill acts as a structured checklist and reference during code review and project scaffolding rather than generating one-off snippets.

  • Recommended project directory layout with clear separation of web, Android, and iOS code
  • Secure and conditional capacitor.config.ts patterns that avoid exposing cleartext in production
  • Plugin usage, performance optimization, and security best practices for production apps
  • Guidelines for app store submission and native project configuration
  • Architecture review checklist usable for new projects or existing codebases

Capacitor Best Practices by the numbers

  • 634 all-time installs (skills.sh)
  • Data as of Aug 1, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cap-go/capgo-skills --skill capacitor-best-practices

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs634
repo stars57
Last updatedJuly 13, 2026
Repositorycap-go/capgo-skills

What are production Capacitor app best practices?

Apply production-grade guidelines when creating, reviewing, or optimizing Capacitor mobile apps.

Who is it for?

Developers building or reviewing Ionic/Capacitor hybrid apps who need structured production guidance across structure, plugins, performance, and release prep.

Skip if: Developers working on pure native Swift/Kotlin apps, React Native projects, or backend-only APIs without a Capacitor shell.

When should I use this skill?

User sets up a Capacitor project, reviews Capacitor code, optimizes app performance, implements mobile security, or prepares for app store submission.

What you get

Reviewed architecture guidance, optimized plugin patterns, security checklist, and app store deployment recommendations.

  • Architecture review notes
  • Performance and security recommendations
  • Store submission checklist

Files

SKILL.mdMarkdownGitHub ↗

Capacitor Best Practices

Comprehensive guidelines for building production-ready Capacitor applications.

When to Use This Skill

  • Setting up a new Capacitor project
  • Reviewing Capacitor app architecture
  • Optimizing app performance
  • Implementing security measures
  • Preparing for app store submission

Project Structure

Recommended Directory Layout

my-app/
├── src/                      # Web app source
├── android/                  # Android native project
├── ios/                      # iOS native project
├── capacitor.config.ts       # Capacitor configuration
├── package.json
└── tsconfig.json

Configuration Best Practices

capacitor.config.ts (CORRECT):

import type { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  appId: 'com.company.app',
  appName: 'My App',
  webDir: 'dist',
  server: {
    // Only enable for development
    ...(process.env.NODE_ENV === 'development' && {
      url: 'http://localhost:5173',
      cleartext: true,
    }),
  },
  plugins: {
    SplashScreen: {
      launchAutoHide: false,
    },
  },
};

export default config;

capacitor.config.json (AVOID):

{
  "server": {
    "url": "http://localhost:5173",
    "cleartext": true
  }
}

Never commit development server URLs to production

Plugin Usage

CRITICAL: Always Use Latest Capacitor

Keep Capacitor core packages in sync:

npm install @capacitor/core@latest @capacitor/cli@latest
npm install @capacitor/ios@latest @capacitor/android@latest
npx cap sync

Plugin Installation Pattern

CORRECT:

# 1. Install the package
npm install @capgo/capacitor-native-biometric

# 2. Sync native projects
npx cap sync

# 3. For iOS: Install pods (or use SPM)
cd ios/App && pod install && cd ../..

INCORRECT:

# Missing sync step
npm install @capgo/capacitor-native-biometric
# App crashes because native code not linked

Plugin Initialization

CORRECT - Check availability before use:

import { NativeBiometric, BiometryType } from '@capgo/capacitor-native-biometric';

async function authenticate() {
  const { isAvailable, biometryType } = await NativeBiometric.isAvailable();

  if (!isAvailable) {
    // Fallback to password
    return authenticateWithPassword();
  }

  try {
    await NativeBiometric.verifyIdentity({
      reason: 'Authenticate to access your account',
      title: 'Biometric Login',
    });
    return true;
  } catch (error) {
    // User cancelled or biometric failed
    return false;
  }
}

INCORRECT - No availability check:

// Will crash if biometrics not available
await NativeBiometric.verifyIdentity({ reason: 'Login' });

Performance Optimization

CRITICAL: Lazy Load Plugins

CORRECT - Dynamic imports:

// Only load when needed
async function scanDocument() {
  const { DocumentScanner } = await import('@capgo/capacitor-document-scanner');
  return DocumentScanner.scanDocument();
}

INCORRECT - Import everything at startup:

// Increases initial bundle size
import { DocumentScanner } from '@capgo/capacitor-document-scanner';
import { NativeBiometric } from '@capgo/capacitor-native-biometric';
import { Camera } from '@capacitor/camera';
// ... 20 more plugins

HIGH: Optimize WebView Performance

CORRECT - Use hardware acceleration:

<!-- android/app/src/main/AndroidManifest.xml -->
<application
    android:hardwareAccelerated="true"
    android:largeHeap="true">
<!-- ios/App/App/Info.plist -->
<key>UIViewGroupOpacity</key>
<false/>

HIGH: Minimize Bridge Calls

CORRECT - Batch operations:

// Single call with batch data
await Storage.set({
  key: 'userData',
  value: JSON.stringify({ name, email, preferences }),
});

INCORRECT - Multiple bridge calls:

// Each call crosses the JS-native bridge
await Storage.set({ key: 'name', value: name });
await Storage.set({ key: 'email', value: email });
await Storage.set({ key: 'preferences', value: JSON.stringify(preferences) });

MEDIUM: Image Optimization

CORRECT:

import { Camera, CameraResultType } from '@capacitor/camera';

const photo = await Camera.getPhoto({
  quality: 80,           // Not 100
  width: 1024,           // Reasonable max
  resultType: CameraResultType.Uri,  // Not Base64 for large images
  correctOrientation: true,
});

INCORRECT:

const photo = await Camera.getPhoto({
  quality: 100,
  resultType: CameraResultType.Base64,  // Memory intensive
  // No size limits
});

Security Best Practices

CRITICAL: Secure Storage

CORRECT - Use secure storage for sensitive data:

import { NativeBiometric } from '@capgo/capacitor-native-biometric';

// Store credentials securely
await NativeBiometric.setCredentials({
  username: 'user@example.com',
  password: 'secret',
  server: 'api.myapp.com',
});

// Retrieve with biometric verification
const credentials = await NativeBiometric.getCredentials({
  server: 'api.myapp.com',
});

INCORRECT - Plain storage:

import { Preferences } from '@capacitor/preferences';

// NEVER store sensitive data in plain preferences
await Preferences.set({
  key: 'password',
  value: 'secret',  // Stored in plain text!
});

CRITICAL: Certificate Pinning

For production apps handling sensitive data:

// capacitor.config.ts
const config: CapacitorConfig = {
  plugins: {
    CapacitorHttp: {
      enabled: true,
    },
  },
  server: {
    // Disable cleartext in production
    cleartext: false,
  },
};

HIGH: Root/Jailbreak Detection

import { IsRoot } from '@capgo/capacitor-is-root';

async function checkDeviceSecurity() {
  const { isRooted } = await IsRoot.isRooted();

  if (isRooted) {
    // Show warning or restrict functionality
    showSecurityWarning('Device appears to be rooted/jailbroken');
  }
}

HIGH: App Tracking Transparency (iOS)

import { AppTrackingTransparency } from '@capgo/capacitor-app-tracking-transparency';

async function requestTracking() {
  const { status } = await AppTrackingTransparency.requestPermission();

  if (status === 'authorized') {
    // Enable analytics
  }
}

Error Handling

CRITICAL: Always Handle Plugin Errors

CORRECT:

import { Camera, CameraResultType } from '@capacitor/camera';

async function takePhoto() {
  try {
    const image = await Camera.getPhoto({
      quality: 90,
      resultType: CameraResultType.Uri,
    });
    return image;
  } catch (error) {
    if (error.message === 'User cancelled photos app') {
      // User cancelled, not an error
      return null;
    }
    if (error.message.includes('permission')) {
      // Permission denied
      showPermissionDialog();
      return null;
    }
    // Unexpected error
    console.error('Camera error:', error);
    throw error;
  }
}

INCORRECT:

// No error handling
const image = await Camera.getPhoto({ quality: 90 });

Live Updates

Using Capacitor Updater

import { CapacitorUpdater } from '@capgo/capacitor-updater';

// Notify when app is ready
CapacitorUpdater.notifyAppReady();

// Listen for updates
CapacitorUpdater.addListener('updateAvailable', async (update) => {
  // Download in background
  const bundle = await CapacitorUpdater.download({
    url: update.url,
    version: update.version,
  });

  // Apply on next app start
  await CapacitorUpdater.set(bundle);
});

Update Strategy

CORRECT - Background download, apply on restart:

// Download silently
const bundle = await CapacitorUpdater.download({ url, version });

// User continues using app...

// Apply when they close/reopen
await CapacitorUpdater.set(bundle);

INCORRECT - Interrupt user:

// Don't force reload while user is active
const bundle = await CapacitorUpdater.download({ url, version });
await CapacitorUpdater.reload();  // Disrupts user

Native Project Management

iOS: Use Swift Package Manager (SPM)

Modern approach - prefer SPM over CocoaPods:

# Podfile - Remove plugin pods, use SPM instead
target 'App' do
  capacitor_pods
  # Plugin dependencies via SPM in Xcode
end

Android: Gradle Configuration

// android/app/build.gradle
android {
    defaultConfig {
        minSdkVersion 22
        targetSdkVersion 34
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

Testing

Plugin Mocking

// Mock for web testing
jest.mock('@capgo/capacitor-native-biometric', () => ({
  NativeBiometric: {
    isAvailable: jest.fn().mockResolvedValue({
      isAvailable: true,
      biometryType: 'touchId',
    }),
    verifyIdentity: jest.fn().mockResolvedValue({}),
  },
}));

Platform Detection

import { Capacitor } from '@capacitor/core';

if (Capacitor.isNativePlatform()) {
  // Native-specific code
} else {
  // Web fallback
}

// Or check specific platform
if (Capacitor.getPlatform() === 'ios') {
  // iOS-specific code
}

Deployment Checklist

  • [ ] Remove development server URLs from config
  • [ ] Enable ProGuard for Android release builds
  • [ ] Set appropriate iOS deployment target
  • [ ] Test on real devices, not just simulators
  • [ ] Verify all permissions are declared
  • [ ] Test with poor network conditions
  • [ ] Verify deep links work correctly
  • [ ] Test app backgrounding/foregrounding
  • [ ] Verify push notifications work
  • [ ] Test biometric authentication edge cases

Resources

  • Capacitor Documentation: https://capacitorjs.com/docs
  • Capgo Documentation: https://capgo.app/docs
  • Ionic Framework: https://ionicframework.com/docs

Related skills

How it compares

Use Capacitor Best Practices for Capacitor-specific production checklists; use general mobile or React skills when the stack is not Capacitor-based.

FAQ

When should capacitor-best-practices be used?

Capacitor Best Practices applies when setting up a new Capacitor project, reviewing app architecture, optimizing performance, implementing security measures, or preparing for app store submission. It covers structure, plugins, and deployment readiness.

What areas does capacitor-best-practices cover?

Capacitor Best Practices covers recommended directory layout, plugin usage patterns, performance optimization, security measures, and app store submission steps. It is intended for production-ready hybrid mobile apps built with Capacitor.

Mobile Developmentfrontendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.