---
description: Capacitor SQLite plugin documentation and API guide covering database management for Ionic and Capacitor with examples, encryption, and best practices.
title: Exploring the Capacitor SQLite API - Capawesome
image: https://capawesome.io/docs/assets/images/social/blog/exploring-the-capacitor-sqlite-api.png
---

[ Skip to content](#exploring-the-capacitor-sqlite-api) 

[ 🔐 Introducing the **Capacitor Vault** plugin — store secrets behind biometrics or a device passcode.](/blog/announcing-the-capacitor-vault-plugin/) 

* [  SDKs ](/docs/sdks/)
* [  Formbricks ](/docs/sdks/capacitor/formbricks/)
* [  Geocoder ](/docs/sdks/capacitor/geocoder/)
* [  Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [  Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [  libSQL ](/docs/sdks/capacitor/libsql/)
* [  Live Update ](/docs/sdks/capacitor/live-update/)
* [  Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [  Media Session ](/docs/sdks/capacitor/media-session/)
* [  ML Kit ](/docs/sdks/capacitor/mlkit/)
* [  Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [  NFC ](/docs/sdks/capacitor/nfc/)
* [  OAuth ](/docs/sdks/capacitor/oauth/)
* [  Pedometer ](/docs/sdks/capacitor/pedometer/)
* [  Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [  PostHog ](/docs/sdks/capacitor/posthog/)
* [  Printer ](/docs/sdks/capacitor/printer/)
* [  Purchases ](/docs/sdks/capacitor/purchases/)
* [  RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [  Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [  Screenshot ](/docs/sdks/capacitor/screenshot/)
* [  Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [  Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [  Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [  Share Target ](/docs/sdks/capacitor/share-target/)
* [  Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [  SQLite ](/docs/sdks/capacitor/sqlite/)
* [  Superwall ](/docs/sdks/capacitor/superwall/)
* [  Torch ](/docs/sdks/capacitor/torch/)
* [  Vault ](/docs/sdks/capacitor/vault/)
* [  Wifi ](/docs/sdks/capacitor/wifi/)
* [  Zip ](/docs/sdks/capacitor/zip/)
* [  Cordova ](/docs/sdks/cordova/)
* [  Cloud ](/docs/cloud/)
* [  Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [  Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [  FAQ ](/docs/cloud/live-updates/faq/)
* [  Native Builds ](/docs/cloud/native-builds/)
* [  Set Up Environments ](/docs/cloud/native-builds/environments/)
* [  Overwrite Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [  Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [  Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [  Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [  Use pnpm or Yarn ](/docs/cloud/native-builds/package-managers/)
* [  Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [  Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [  Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [  Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [  Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [  Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [  Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [  FAQ ](/docs/cloud/native-builds/faq/)
* [  App Store Publishing ](/docs/cloud/app-store-publishing/)
* [  Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [  Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [  Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [  FAQ ](/docs/cloud/app-store-publishing/faq/)
* [  Automations ](/docs/cloud/automations/)
* [  Reference ](/docs/cloud/automations/reference/)
* [  Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [  FAQ ](/docs/cloud/automations/faq/)
* [  Assist ](/docs/cloud/assist/)
* [  CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [  Webhooks ](/docs/cloud/webhooks/)
* [  Integrations ](/docs/cloud/integrations/)
* Account
* [  Organization ](/docs/cloud/organizations/)
* [  Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [  Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [  Billing ](/docs/cloud/organizations/billing/)
* [  License Keys ](/docs/cloud/license-keys/)
* [  AI ](/docs/ai/)
* [  Insiders ](/docs/insiders/)
* [  Billing & Plans ](/docs/insiders/billing-and-plans/)
* [  FAQ ](/docs/insiders/faq/)
* [  License ](https://capawesome.io/legal/eula/)
* [  Support ](/docs/support/)
* [  Contributing ](/docs/contributing/)
* Contributing code
* [  Code of Conduct ](/docs/contributing/code-of-conduct/)
* [  Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [  Blog ](/blog/)
* Categories

* [  Advanced ](#advanced)
* [  Limitations ](#limitations)
* [  Best Practices ](#best-practices)
* [  Conclusion ](#conclusion)

* Related links

# Exploring the Capacitor SQLite API[¶](#exploring-the-capacitor-sqlite-api "Permanent link")

Modern mobile applications often require robust local data storage solutions to manage user information, cache data, and enable offline functionality. With the [Capacitor SQLite plugin](/docs/sdks/capacitor/sqlite/) from Capawesome, developers can integrate powerful SQLite database management capabilities into their Ionic and Capacitor applications, providing a unified API that simplifies cross-platform database operations while offering advanced features like encryption, migrations, and transaction support across Android, iOS, and Web platforms.

This guide walks through the **Capacitor SQLite plugin** API with practical examples and best practices for Ionic and Capacitor apps.

## Bonus: Video Tutorial and Demo App[¶](#bonus-video-tutorial-and-demo-app "Permanent link")

This tutorial walks through a practical Capacitor SQLite setup with CRUD operations, transactions, and real-world data flow patterns for local mobile persistence across platforms.

* **[Angular Capacitor SQLite Demo](https://github.com/capawesome-team/capacitor-sqlite-angular-demo)** — A complete Angular example app with SQLite CRUD and transaction usage.
* **[React Capacitor SQLite Demo](https://github.com/capawesome-team/capacitor-sqlite-react-demo)** — A React implementation of the same SQLite patterns for cross-framework reference.

## Installation[¶](#installation "Permanent link")

To install the Capacitor SQLite plugin, please refer to the [Installation](/docs/sdks/capacitor/sqlite/#installation) section in the plugin documentation.

## Usage[¶](#usage "Permanent link")

Let's explore the key features of the Capacitor SQLite API and how to implement robust database operations in your Ionic applications.

### Opening a Database[¶](#opening-a-database "Permanent link")

Before performing any database operations, you need to open a database connection. The Capacitor SQLite API provides the [open(...)](/docs/sdks/capacitor/sqlite/#open) method to establish a connection to your SQLite database:

`[](#%5F%5Fcodelineno-0-1)import { Sqlite } from '@capawesome-team/capacitor-sqlite';
[](#%5F%5Fcodelineno-0-2)
[](#%5F%5Fcodelineno-0-3)const openDatabase = async () => {
[](#%5F%5Fcodelineno-0-4)  const { databaseId } = await Sqlite.open({
[](#%5F%5Fcodelineno-0-5)    path: 'myapp.sqlite3',
[](#%5F%5Fcodelineno-0-6)    upgradeStatements: [
[](#%5F%5Fcodelineno-0-7)      {
[](#%5F%5Fcodelineno-0-8)        version: 1,
[](#%5F%5Fcodelineno-0-9)        statements: [
[](#%5F%5Fcodelineno-0-10)          'CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT UNIQUE)',
[](#%5F%5Fcodelineno-0-11)          'CREATE TABLE posts (id INTEGER PRIMARY KEY, title TEXT, content TEXT, user_id INTEGER, FOREIGN KEY(user_id) REFERENCES users(id))'
[](#%5F%5Fcodelineno-0-12)        ]
[](#%5F%5Fcodelineno-0-13)      }
[](#%5F%5Fcodelineno-0-14)    ]
[](#%5F%5Fcodelineno-0-15)  });
[](#%5F%5Fcodelineno-0-16)
[](#%5F%5Fcodelineno-0-17)  console.log('Database opened with ID:', databaseId);
[](#%5F%5Fcodelineno-0-18)  return databaseId;
[](#%5F%5Fcodelineno-0-19)};
`

The `open(...)` method returns a unique database identifier that you'll use for subsequent database operations. The `upgradeStatements` parameter allows you to define database schema migrations that will be executed automatically when the database is first created or when upgrading to newer versions.

### Executing SQL Statements[¶](#executing-sql-statements "Permanent link")

Once you have a database connection, you can execute SQL statements using the [execute(...)](/docs/sdks/capacitor/sqlite/#execute) method. This method is ideal for `INSERT`, `UPDATE`, and `DELETE` operations, as well as executing raw SQL commands:

`[](#%5F%5Fcodelineno-1-1)const insertUser = async (databaseId: string, name: string, email: string) => {
[](#%5F%5Fcodelineno-1-2)  const { rowId } = await Sqlite.execute({
[](#%5F%5Fcodelineno-1-3)    databaseId,
[](#%5F%5Fcodelineno-1-4)    statement: 'INSERT INTO users (name, email) VALUES (?, ?)',
[](#%5F%5Fcodelineno-1-5)    values: [name, email]
[](#%5F%5Fcodelineno-1-6)  });
[](#%5F%5Fcodelineno-1-7)
[](#%5F%5Fcodelineno-1-8)  console.log('Inserted user with ID:', rowId);
[](#%5F%5Fcodelineno-1-9)};
[](#%5F%5Fcodelineno-1-10)
[](#%5F%5Fcodelineno-1-11)const updateUser = async (databaseId: string, userId: number, name: string) => {
[](#%5F%5Fcodelineno-1-12)  const { changes } = await Sqlite.execute({
[](#%5F%5Fcodelineno-1-13)    databaseId,
[](#%5F%5Fcodelineno-1-14)    statement: 'UPDATE users SET name = ? WHERE id = ?',
[](#%5F%5Fcodelineno-1-15)    values: [name, userId]
[](#%5F%5Fcodelineno-1-16)  });
[](#%5F%5Fcodelineno-1-17)
[](#%5F%5Fcodelineno-1-18)  console.log('Number of rows updated:', changes);
[](#%5F%5Fcodelineno-1-19)};
[](#%5F%5Fcodelineno-1-20)
[](#%5F%5Fcodelineno-1-21)const deleteUser = async (databaseId: string, userId: number) => {
[](#%5F%5Fcodelineno-1-22)  const { changes } = await Sqlite.execute({
[](#%5F%5Fcodelineno-1-23)    databaseId,
[](#%5F%5Fcodelineno-1-24)    statement: 'DELETE FROM users WHERE id = ?',
[](#%5F%5Fcodelineno-1-25)    values: [userId]
[](#%5F%5Fcodelineno-1-26)  });
[](#%5F%5Fcodelineno-1-27)
[](#%5F%5Fcodelineno-1-28)  console.log('Number of rows deleted:', changes);
[](#%5F%5Fcodelineno-1-29)};
`

Always use parameterized queries with the `values` array to prevent SQL injection attacks. This approach ensures that user input is properly escaped and your database remains secure.

### Querying Data[¶](#querying-data "Permanent link")

To retrieve data from your database, use the [query(...)](/docs/sdks/capacitor/sqlite/#query) method. This method executes SELECT statements and returns the result set:

`` [](#%5F%5Fcodelineno-2-1)const getAllUsers = async (databaseId: string) => {
[](#%5F%5Fcodelineno-2-2)  const result = await Sqlite.query({
[](#%5F%5Fcodelineno-2-3)    databaseId,
[](#%5F%5Fcodelineno-2-4)    statement: 'SELECT id, name, email FROM users ORDER BY name'
[](#%5F%5Fcodelineno-2-5)  });
[](#%5F%5Fcodelineno-2-6)
[](#%5F%5Fcodelineno-2-7)  console.log('Found', result.values?.length, 'users');
[](#%5F%5Fcodelineno-2-8)  return result.values || [];
[](#%5F%5Fcodelineno-2-9)};
[](#%5F%5Fcodelineno-2-10)
[](#%5F%5Fcodelineno-2-11)const getUserById = async (databaseId: string, userId: number) => {
[](#%5F%5Fcodelineno-2-12)  const result = await Sqlite.query({
[](#%5F%5Fcodelineno-2-13)    databaseId,
[](#%5F%5Fcodelineno-2-14)    statement: 'SELECT id, name, email FROM users WHERE id = ?',
[](#%5F%5Fcodelineno-2-15)    values: [userId]
[](#%5F%5Fcodelineno-2-16)  });
[](#%5F%5Fcodelineno-2-17)
[](#%5F%5Fcodelineno-2-18)  return result.values?.[0] || null;
[](#%5F%5Fcodelineno-2-19)};
[](#%5F%5Fcodelineno-2-20)
[](#%5F%5Fcodelineno-2-21)const searchUsers = async (databaseId: string, searchTerm: string) => {
[](#%5F%5Fcodelineno-2-22)  const result = await Sqlite.query({
[](#%5F%5Fcodelineno-2-23)    databaseId,
[](#%5F%5Fcodelineno-2-24)    statement: 'SELECT id, name, email FROM users WHERE name LIKE ? OR email LIKE ?',
[](#%5F%5Fcodelineno-2-25)    values: [`%${searchTerm}%`, `%${searchTerm}%`]
[](#%5F%5Fcodelineno-2-26)  });
[](#%5F%5Fcodelineno-2-27)
[](#%5F%5Fcodelineno-2-28)  return result.values || [];
[](#%5F%5Fcodelineno-2-29)};
 ``

The `query(...)` method returns an object containing a `values` array with the retrieved rows. Each row is represented as an object with column names as keys.

### Closing the Database[¶](#closing-the-database "Permanent link")

When you're done with database operations, it's important to close the database connection to free up system resources. Use the [close(...)](/docs/sdks/capacitor/sqlite/#close) method:

`[](#%5F%5Fcodelineno-3-1)const closeDatabase = async (databaseId: string) => {
[](#%5F%5Fcodelineno-3-2)  await Sqlite.close({
[](#%5F%5Fcodelineno-3-3)    databaseId
[](#%5F%5Fcodelineno-3-4)  });
[](#%5F%5Fcodelineno-3-5)
[](#%5F%5Fcodelineno-3-6)  console.log('Database connection closed');
[](#%5F%5Fcodelineno-3-7)};
`

Always close database connections when your application is shutting down or when you no longer need the database to ensure optimal resource management.

## Advanced[¶](#advanced "Permanent link")

The Capacitor SQLite API provides advanced features for more sophisticated database operations and security requirements.

### Encrypting the Database[¶](#encrypting-the-database "Permanent link")

For applications handling sensitive data, the Capacitor SQLite plugin supports 256-bit AES encryption. You can encrypt your database by providing an encryption key when opening it:

`[](#%5F%5Fcodelineno-4-1)const openEncryptedDatabase = async () => {
[](#%5F%5Fcodelineno-4-2)  const { databaseId } = await Sqlite.open({
[](#%5F%5Fcodelineno-4-3)    path: 'secure.sqlite3',
[](#%5F%5Fcodelineno-4-4)    encryptionKey: 'your-secure-encryption-key',
[](#%5F%5Fcodelineno-4-5)    upgradeStatements: [
[](#%5F%5Fcodelineno-4-6)      {
[](#%5F%5Fcodelineno-4-7)        version: 1,
[](#%5F%5Fcodelineno-4-8)        statements: [
[](#%5F%5Fcodelineno-4-9)          'CREATE TABLE sensitive_data (id INTEGER PRIMARY KEY, data TEXT)'
[](#%5F%5Fcodelineno-4-10)        ]
[](#%5F%5Fcodelineno-4-11)      }
[](#%5F%5Fcodelineno-4-12)    ]
[](#%5F%5Fcodelineno-4-13)  });
[](#%5F%5Fcodelineno-4-14)
[](#%5F%5Fcodelineno-4-15)  return databaseId;
[](#%5F%5Fcodelineno-4-16)};
`

The encryption key should be stored securely using platform-specific secure storage mechanisms. Never hardcode encryption keys in your application code. Consider using the [Capacitor Secure Preferences plugin](/docs/sdks/capacitor/secure-preferences/) to store encryption keys safely.

To change the encryption key for an existing database, you can use the [changeEncryptionKey(...)](/docs/sdks/capacitor/sqlite/#changeencryptionkey) method:

`[](#%5F%5Fcodelineno-5-1)const changeEncryptionKey = async (databaseId: string, newKey: string) => {
[](#%5F%5Fcodelineno-5-2)  await Sqlite.changeEncryptionKey({
[](#%5F%5Fcodelineno-5-3)    databaseId,
[](#%5F%5Fcodelineno-5-4)    encryptionKey: newKey
[](#%5F%5Fcodelineno-5-5)  });
[](#%5F%5Fcodelineno-5-6)  console.log('Encryption key changed successfully');
[](#%5F%5Fcodelineno-5-7)};
`

This method allows you to update the encryption key without needing to recreate the database, ensuring that your data remains secure while allowing for key rotation.

### Transactions[¶](#transactions "Permanent link")

For operations that require atomicity, use the [beginTransaction(...)](/docs/sdks/capacitor/sqlite/#begintransaction) and [commitTransaction(...)](/docs/sdks/capacitor/sqlite/#committransaction) methods to manage transactions effectively:

`[](#%5F%5Fcodelineno-6-1)const performTransaction = async (databaseId: string) => {
[](#%5F%5Fcodelineno-6-2)  // Begin a transaction
[](#%5F%5Fcodelineno-6-3)  await Sqlite.beginTransaction({ databaseId });
[](#%5F%5Fcodelineno-6-4)  // Perform multiple operations within the transaction
[](#%5F%5Fcodelineno-6-5)  await Sqlite.execute({
[](#%5F%5Fcodelineno-6-6)    databaseId,
[](#%5F%5Fcodelineno-6-7)    statement: 'INSERT INTO users (name, email) VALUES (?, ?)',
[](#%5F%5Fcodelineno-6-8)    values: ['Alice Smith', 'alice@example.com']
[](#%5F%5Fcodelineno-6-9)  });
[](#%5F%5Fcodelineno-6-10)  await Sqlite.execute({
[](#%5F%5Fcodelineno-6-11)    databaseId,
[](#%5F%5Fcodelineno-6-12)    statement: 'INSERT INTO posts (user_id, title, content) VALUES (?, ?, ?)',
[](#%5F%5Fcodelineno-6-13)    values: [1, 'My First Post', 'Hello world!']
[](#%5F%5Fcodelineno-6-14)  });
[](#%5F%5Fcodelineno-6-15)  // Commit the transaction
[](#%5F%5Fcodelineno-6-16)  await Sqlite.commitTransaction({ databaseId });
[](#%5F%5Fcodelineno-6-17)};
`

This ensures that either all operations succeed or none are applied, maintaining data integrity. If any operation fails, you can roll back the transaction to revert all changes:

`[](#%5F%5Fcodelineno-7-1)import { Sqlite } from '@capawesome-team/capacitor-sqlite';
[](#%5F%5Fcodelineno-7-2)
[](#%5F%5Fcodelineno-7-3)const rollbackTransaction = async (databaseId: string) => {
[](#%5F%5Fcodelineno-7-4)  await Sqlite.rollbackTransaction({
[](#%5F%5Fcodelineno-7-5)    databaseId
[](#%5F%5Fcodelineno-7-6)  });
[](#%5F%5Fcodelineno-7-7)};
`

### Vacuuming[¶](#vacuuming "Permanent link")

To optimize database performance and reclaim unused space, use the [vacuum(...)](/docs/sdks/capacitor/sqlite/#vacuum) method periodically:

`[](#%5F%5Fcodelineno-8-1)const optimizeDatabase = async (databaseId: string) => {
[](#%5F%5Fcodelineno-8-2)  await Sqlite.vacuum({
[](#%5F%5Fcodelineno-8-3)    databaseId
[](#%5F%5Fcodelineno-8-4)  });
[](#%5F%5Fcodelineno-8-5)
[](#%5F%5Fcodelineno-8-6)  console.log('Database optimized');
[](#%5F%5Fcodelineno-8-7)};
`

Vacuuming rebuilds the database file, removing deleted data and defragmenting the database. This operation can improve query performance and reduce file size, especially after large amounts of data have been deleted.

## Limitations[¶](#limitations "Permanent link")

While the Capacitor SQLite plugin provides comprehensive cross-platform support, there are some platform-specific limitations to consider.

### iOS[¶](#ios "Permanent link")

On iOS, database encryption is only available when using CocoaPods for dependency management. If you're using Swift Package Manager (SPM), encryption features will not be available.

### Web[¶](#web "Permanent link")

On the Web platform, BLOB data types are not fully supported due to browser restrictions. When targeting the Web platform, consider alternative approaches for handling binary data.

## Best Practices[¶](#best-practices "Permanent link")

When working with the Capacitor SQLite API, consider these best practices to ensure optimal performance and security:

1. **Use parameterized queries**: Always use the `values` parameter in your SQL statements to prevent SQL injection attacks. Never concatenate user input directly into SQL strings, as this creates security vulnerabilities that can compromise your entire database.
2. **Implement proper error handling**: Wrap database operations in try-catch blocks and provide meaningful error messages to users. Database operations can fail due to various reasons such as disk space, permissions, or constraint violations, so robust error handling is essential.
3. **Manage database connections efficiently**: Open database connections when needed and close them when done to prevent resource leaks. Consider implementing a connection pool pattern for applications with frequent database access to optimize performance while managing resource usage effectively.

## Conclusion[¶](#conclusion "Permanent link")

The [Capacitor SQLite plugin](/docs/sdks/capacitor/sqlite/) from Capawesome provides a comprehensive solution for integrating robust database management into Ionic applications. By offering a unified API across multiple platforms with advanced features like encryption, transactions, and migrations, it enables developers to create sophisticated data-driven applications without the complexity of platform-specific database implementations. For the full plugin documentation, see the [API Reference](/docs/sdks/capacitor/sqlite/#api).

**Related tutorials:**

* [Announcing the Capacitor SQLite Plugin](/blog/announcing-the-capacitor-sqlite-plugin/)
* [Alternative to the Capacitor Community SQLite plugin](/blog/alternative-to-capacitor-community-sqlite-plugin/)
* [Encrypting SQLite databases](/blog/encrypting-capacitor-sqlite-database/)
* [Key-Value Storage with the SQLite plugin](/blog/key-value-storage-made-simple-with-the-sqlite-plugin/)
* For type-safe ORMs, check [TypeORM](/blog/how-to-use-typeorm-with-capacitor-and-sqlite/), [Drizzle ORM](/blog/how-to-use-drizzle-orm-with-capacitor-and-sqlite/), [Kysely](/blog/how-to-use-kysely-with-capacitor-and-sqlite/)

If you have any questions or need assistance with the Capacitor SQLite Plugin, feel free to [reach out](mailto:support@capawesome.io) to the Capawesome team. We're here to help you implement robust database solutions in your Ionic applications.

Subscribe to the [Capawesome newsletter](/newsletter/) and join the [Capawesome Discord server](https://discord.gg/VCXxSVjefW) for questions and updates on Ionic and Capacitor.

June 8, 2026 

 Back to top 