---
description: Learn how to use TypeORM with Capacitor and SQLite for decorator-based entity modeling and repository-driven data access in your mobile apps.
title: How to Use TypeORM with Capacitor and SQLite - Capawesome
image: https://capawesome.io/docs/assets/images/social/blog/how-to-use-typeorm-with-capacitor-and-sqlite.png
---

[ Skip to content](#how-to-use-typeorm-with-capacitor-and-sqlite) 

[ 🔐 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

* [  Transactions ](#transactions)
* [  Migrations ](#migrations)
* [  Stay Updated ](#stay-updated)
* [  Conclusion ](#conclusion)

* Related links

# How to Use TypeORM with Capacitor and SQLite[¶](#how-to-use-typeorm-with-capacitor-and-sqlite "Permanent link")

Many developers already use TypeORM on the backend to manage databases with TypeScript decorators and a familiar repository pattern. The good news: the same approach works in Capacitor apps too. The [Capacitor SQLite plugin](/docs/sdks/capacitor/sqlite/) ships with a built-in `SQLiteConnection` class that plugs directly into TypeORM's `DataSource` — no additional adapter package required. This guide walks you through the complete setup, from defining entities to running queries and managing migrations.

For raw API usage, see the [Capacitor SQLite plugin documentation](/docs/sdks/capacitor/sqlite/#api).

[ ![Build and deploy your Capacitor app with Capawesome Cloud](../../assets/external/cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.69628c3f.png) ](/) 

## What is TypeORM?[¶](#what-is-typeorm "Permanent link")

[TypeORM](https://typeorm.io/) is one of the most widely used ORMs in the TypeScript ecosystem. It takes a decorator-based approach to database modeling: you define your tables as classes, annotate columns and relationships with decorators, and interact with data through repositories and query builders.

Here's why it pairs well with Capacitor apps:

* **Decorator-based entities** — Tables are modeled as regular TypeScript classes. Columns, primary keys, and relationships are declared with decorators like `@Column()` and `@ManyToOne()`.
* **Repository pattern** — Each entity gets a repository with built-in methods for common operations (`find`, `save`, `remove`), so you rarely need to write SQL.
* **Automatic schema sync** — During development, TypeORM can synchronize your database schema with your entity definitions automatically.
* **Migration support** — For production, TypeORM provides a migration system to apply schema changes incrementally.
* **Wide adoption** — TypeORM has a large community and extensive documentation, which means answers to most questions are a search away.

## Prerequisites[¶](#prerequisites "Permanent link")

Before you begin, make sure you have a Capacitor project with the [Capacitor SQLite plugin](/docs/sdks/capacitor/sqlite/) installed. To install the plugin, please refer to the [Installation](/docs/sdks/capacitor/sqlite/#installation) section in the plugin documentation.

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

Since the TypeORM driver is included in the [Capacitor SQLite plugin](/docs/sdks/capacitor/sqlite/) itself, you only need to install TypeORM and its peer dependency:

`[](#%5F%5Fcodelineno-0-1)npm install typeorm reflect-metadata
`

TypeORM relies on decorators and metadata reflection, so you need to enable both in your `tsconfig.json`:

`[](#%5F%5Fcodelineno-1-1){
[](#%5F%5Fcodelineno-1-2)  "compilerOptions": {
[](#%5F%5Fcodelineno-1-3)    "experimentalDecorators": true,
[](#%5F%5Fcodelineno-1-4)    "emitDecoratorMetadata": true
[](#%5F%5Fcodelineno-1-5)  }
[](#%5F%5Fcodelineno-1-6)}
`

Finally, import `reflect-metadata` once at the entry point of your app (e.g. `main.ts`), before any other imports:

`[](#%5F%5Fcodelineno-2-1)import 'reflect-metadata';
`

## Configuring the DataSource[¶](#configuring-the-datasource "Permanent link")

TypeORM uses a `DataSource` to manage the database connection. To connect it to the [Capacitor SQLite plugin](/docs/sdks/capacitor/sqlite/), pass an `SQLiteConnection` instance as the `driver`:

`[](#%5F%5Fcodelineno-3-1)import { Sqlite, SQLiteConnection } from '@capawesome-team/capacitor-sqlite';
[](#%5F%5Fcodelineno-3-2)import { DataSource } from 'typeorm';
[](#%5F%5Fcodelineno-3-3)
[](#%5F%5Fcodelineno-3-4)const AppDataSource = new DataSource({
[](#%5F%5Fcodelineno-3-5)  type: 'capacitor',
[](#%5F%5Fcodelineno-3-6)  driver: new SQLiteConnection(Sqlite),
[](#%5F%5Fcodelineno-3-7)  database: 'my-app',
[](#%5F%5Fcodelineno-3-8)  entities: [],
[](#%5F%5Fcodelineno-3-9)  synchronize: true,
[](#%5F%5Fcodelineno-3-10)  logging: ['error', 'schema'],
[](#%5F%5Fcodelineno-3-11)  migrationsRun: false,
[](#%5F%5Fcodelineno-3-12)});
`

A few things to note here:

* `type: 'capacitor'` tells TypeORM to use its built-in Capacitor driver, which delegates database operations to the provided `driver` instance.
* `driver: new SQLiteConnection(Sqlite)` bridges TypeORM to the Capacitor SQLite plugin. The `SQLiteConnection` class handles opening, closing, and routing queries to the correct database.
* `database` is the name used to identify the database file.
* `synchronize: true` automatically creates and updates tables based on your entities. This is convenient during development but should be disabled in production.
* `migrationsRun: false` is required when using the `capacitor` type.

To initialize the connection when your app starts:

`[](#%5F%5Fcodelineno-4-1)await AppDataSource.initialize();
`

## Defining Entities[¶](#defining-entities "Permanent link")

TypeORM models database tables as classes decorated with `@Entity()`. Each property that maps to a column is annotated with a decorator like `@PrimaryGeneratedColumn()` or `@Column()`.

`[](#%5F%5Fcodelineno-5-1)import {
[](#%5F%5Fcodelineno-5-2)  Entity,
[](#%5F%5Fcodelineno-5-3)  PrimaryGeneratedColumn,
[](#%5F%5Fcodelineno-5-4)  Column,
[](#%5F%5Fcodelineno-5-5)  ManyToOne,
[](#%5F%5Fcodelineno-5-6)  OneToMany,
[](#%5F%5Fcodelineno-5-7)  CreateDateColumn,
[](#%5F%5Fcodelineno-5-8)} from 'typeorm';
[](#%5F%5Fcodelineno-5-9)
[](#%5F%5Fcodelineno-5-10)@Entity()
[](#%5F%5Fcodelineno-5-11)export class User {
[](#%5F%5Fcodelineno-5-12)  @PrimaryGeneratedColumn()
[](#%5F%5Fcodelineno-5-13)  id!: number;
[](#%5F%5Fcodelineno-5-14)
[](#%5F%5Fcodelineno-5-15)  @Column('text')
[](#%5F%5Fcodelineno-5-16)  name!: string;
[](#%5F%5Fcodelineno-5-17)
[](#%5F%5Fcodelineno-5-18)  @Column({ type: 'text', unique: true })
[](#%5F%5Fcodelineno-5-19)  email!: string;
[](#%5F%5Fcodelineno-5-20)
[](#%5F%5Fcodelineno-5-21)  @CreateDateColumn()
[](#%5F%5Fcodelineno-5-22)  createdAt!: Date;
[](#%5F%5Fcodelineno-5-23)
[](#%5F%5Fcodelineno-5-24)  @OneToMany(() => Post, (post) => post.author)
[](#%5F%5Fcodelineno-5-25)  posts!: Post[];
[](#%5F%5Fcodelineno-5-26)}
[](#%5F%5Fcodelineno-5-27)
[](#%5F%5Fcodelineno-5-28)@Entity()
[](#%5F%5Fcodelineno-5-29)export class Post {
[](#%5F%5Fcodelineno-5-30)  @PrimaryGeneratedColumn()
[](#%5F%5Fcodelineno-5-31)  id!: number;
[](#%5F%5Fcodelineno-5-32)
[](#%5F%5Fcodelineno-5-33)  @Column('text')
[](#%5F%5Fcodelineno-5-34)  title!: string;
[](#%5F%5Fcodelineno-5-35)
[](#%5F%5Fcodelineno-5-36)  @Column({ type: 'text', nullable: true })
[](#%5F%5Fcodelineno-5-37)  content!: string | null;
[](#%5F%5Fcodelineno-5-38)
[](#%5F%5Fcodelineno-5-39)  @ManyToOne(() => User, (user) => user.posts)
[](#%5F%5Fcodelineno-5-40)  author!: User;
[](#%5F%5Fcodelineno-5-41)}
`

A few things to note:

* `@PrimaryGeneratedColumn()` creates an auto-incrementing primary key.
* `@Column()` accepts a type string or an options object for constraints like `unique` and `nullable`.
* `@CreateDateColumn()` automatically sets the current timestamp when a row is inserted.
* `@OneToMany()` and `@ManyToOne()` define the relationship between `User` and `Post`. TypeORM uses these to generate foreign keys and enable eager/lazy loading.

Don't forget to register your entities in the `DataSource` configuration:

`[](#%5F%5Fcodelineno-6-1)const AppDataSource = new DataSource({
[](#%5F%5Fcodelineno-6-2)  // ...
[](#%5F%5Fcodelineno-6-3)  entities: [User, Post],
[](#%5F%5Fcodelineno-6-4)});
`

## Working with Repositories[¶](#working-with-repositories "Permanent link")

TypeORM's repository pattern provides a high-level API for data access. Each entity gets its own repository with built-in methods for the most common operations.

### Insert[¶](#insert "Permanent link")

`[](#%5F%5Fcodelineno-7-1)const userRepo = AppDataSource.getRepository(User);
[](#%5F%5Fcodelineno-7-2)
[](#%5F%5Fcodelineno-7-3)const user = userRepo.create({
[](#%5F%5Fcodelineno-7-4)  name: 'Alice',
[](#%5F%5Fcodelineno-7-5)  email: 'alice@example.com',
[](#%5F%5Fcodelineno-7-6)});
[](#%5F%5Fcodelineno-7-7)await userRepo.save(user);
`

The `create()` method instantiates an entity without persisting it. Calling `save()` writes it to the database and populates the generated `id`.

### Select[¶](#select "Permanent link")

`[](#%5F%5Fcodelineno-8-1)// Find all users
[](#%5F%5Fcodelineno-8-2)const allUsers = await userRepo.find();
[](#%5F%5Fcodelineno-8-3)
[](#%5F%5Fcodelineno-8-4)// Find with a condition
[](#%5F%5Fcodelineno-8-5)const user = await userRepo.findOneBy({
[](#%5F%5Fcodelineno-8-6)  email: 'alice@example.com',
[](#%5F%5Fcodelineno-8-7)});
[](#%5F%5Fcodelineno-8-8)
[](#%5F%5Fcodelineno-8-9)// Find with relations
[](#%5F%5Fcodelineno-8-10)const userWithPosts = await userRepo.findOne({
[](#%5F%5Fcodelineno-8-11)  where: { id: 1 },
[](#%5F%5Fcodelineno-8-12)  relations: { posts: true },
[](#%5F%5Fcodelineno-8-13)});
`

### Update[¶](#update "Permanent link")

`[](#%5F%5Fcodelineno-9-1)await userRepo.update({ id: 1 }, { name: 'Bob' });
`

### Delete[¶](#delete "Permanent link")

`[](#%5F%5Fcodelineno-10-1)await userRepo.delete({ id: 1 });
`

For more complex queries, TypeORM also offers a `QueryBuilder` that supports joins, subqueries, and aggregations:

`[](#%5F%5Fcodelineno-11-1)const users = await userRepo
[](#%5F%5Fcodelineno-11-2)  .createQueryBuilder('user')
[](#%5F%5Fcodelineno-11-3)  .leftJoinAndSelect('user.posts', 'post')
[](#%5F%5Fcodelineno-11-4)  .where('user.name LIKE :name', { name: '%Ali%' })
[](#%5F%5Fcodelineno-11-5)  .getMany();
`

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

When multiple operations need to succeed or fail as a unit, wrap them in a transaction:

`[](#%5F%5Fcodelineno-12-1)await AppDataSource.transaction(async (manager) => {
[](#%5F%5Fcodelineno-12-2)  const user = manager.create(User, {
[](#%5F%5Fcodelineno-12-3)    name: 'Alice',
[](#%5F%5Fcodelineno-12-4)    email: 'alice@example.com',
[](#%5F%5Fcodelineno-12-5)  });
[](#%5F%5Fcodelineno-12-6)  await manager.save(user);
[](#%5F%5Fcodelineno-12-7)
[](#%5F%5Fcodelineno-12-8)  const post = manager.create(Post, {
[](#%5F%5Fcodelineno-12-9)    title: 'Hello World',
[](#%5F%5Fcodelineno-12-10)    content: '...',
[](#%5F%5Fcodelineno-12-11)    author: user,
[](#%5F%5Fcodelineno-12-12)  });
[](#%5F%5Fcodelineno-12-13)  await manager.save(post);
[](#%5F%5Fcodelineno-12-14)});
`

If any operation inside the callback throws, the entire transaction is rolled back. The `manager` parameter is a transactional `EntityManager` — use it instead of individual repositories to ensure all operations run within the same transaction.

## Migrations[¶](#migrations "Permanent link")

While `synchronize: true` is handy during development, it should not be used in production since it can lead to data loss. Instead, use TypeORM's migration system to apply schema changes incrementally.

### Writing Migrations[¶](#writing-migrations "Permanent link")

Create a migration class that implements `up` and `down` methods:

`` [](#%5F%5Fcodelineno-13-1)import { MigrationInterface, QueryRunner } from 'typeorm';
[](#%5F%5Fcodelineno-13-2)
[](#%5F%5Fcodelineno-13-3)export class CreateUsers1709000000000 implements MigrationInterface {
[](#%5F%5Fcodelineno-13-4)  async up(queryRunner: QueryRunner): Promise<void> {
[](#%5F%5Fcodelineno-13-5)    await queryRunner.query(`
[](#%5F%5Fcodelineno-13-6)      CREATE TABLE IF NOT EXISTS user (
[](#%5F%5Fcodelineno-13-7)        id INTEGER PRIMARY KEY AUTOINCREMENT,
[](#%5F%5Fcodelineno-13-8)        name TEXT NOT NULL,
[](#%5F%5Fcodelineno-13-9)        email TEXT NOT NULL UNIQUE,
[](#%5F%5Fcodelineno-13-10)        createdAt DATETIME DEFAULT (datetime('now'))
[](#%5F%5Fcodelineno-13-11)      )
[](#%5F%5Fcodelineno-13-12)    `);
[](#%5F%5Fcodelineno-13-13)  }
[](#%5F%5Fcodelineno-13-14)
[](#%5F%5Fcodelineno-13-15)  async down(queryRunner: QueryRunner): Promise<void> {
[](#%5F%5Fcodelineno-13-16)    await queryRunner.query(`DROP TABLE IF EXISTS user`);
[](#%5F%5Fcodelineno-13-17)  }
[](#%5F%5Fcodelineno-13-18)}
 ``

### Running Migrations[¶](#running-migrations "Permanent link")

Register your migrations in the `DataSource` and run them at startup:

`[](#%5F%5Fcodelineno-14-1)import { CreateUsers1709000000000 } from './migrations/CreateUsers1709000000000';
[](#%5F%5Fcodelineno-14-2)
[](#%5F%5Fcodelineno-14-3)const AppDataSource = new DataSource({
[](#%5F%5Fcodelineno-14-4)  type: 'capacitor',
[](#%5F%5Fcodelineno-14-5)  driver: new SQLiteConnection(Sqlite),
[](#%5F%5Fcodelineno-14-6)  database: 'my-app',
[](#%5F%5Fcodelineno-14-7)  entities: [User, Post],
[](#%5F%5Fcodelineno-14-8)  migrations: [CreateUsers1709000000000],
[](#%5F%5Fcodelineno-14-9)  synchronize: false,
[](#%5F%5Fcodelineno-14-10)  migrationsRun: false,
[](#%5F%5Fcodelineno-14-11)});
[](#%5F%5Fcodelineno-14-12)
[](#%5F%5Fcodelineno-14-13)await AppDataSource.initialize();
[](#%5F%5Fcodelineno-14-14)await AppDataSource.runMigrations();
`

TypeORM tracks which migrations have been applied in a `migrations` table, so calling `runMigrations()` repeatedly is safe — only pending migrations are executed.

## Stay Updated[¶](#stay-updated "Permanent link")

Want to stay up to date with the latest features and guides? Subscribe to the Capawesome newsletter.

[Subscribe to the Capawesome Newsletter](/newsletter/)

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

TypeORM brings its decorator-based entity modeling and repository pattern to Capacitor apps through the built-in `SQLiteConnection` class in the [Capacitor SQLite plugin](/docs/sdks/capacitor/sqlite/). There's no separate adapter to install — just configure a `DataSource` with `type: 'capacitor'`, define your entities as decorated classes, and use repositories for data access.

**Resources:**

* [API Reference](/docs/sdks/capacitor/sqlite/#api)
* [Exploring the Capacitor SQLite API](/blog/exploring-the-capacitor-sqlite-api/)

**Related tutorials:** 

* If you prefer a lighter, SQL-first approach check [Drizzle ORM](/blog/how-to-use-drizzle-orm-with-capacitor-and-sqlite/) or [Kysely](/blog/how-to-use-kysely-with-capacitor-and-sqlite/)

If you have questions or feedback, join the [Capawesome Discord](https://discord.gg/VCXxSVjefW) server to connect with the community. And subscribe to the Capawesome [newsletter](/newsletter/) to stay updated on the latest news.

June 8, 2026 

 Back to top 