IndexedDB는 브라우저에 기본으로 들어 있는 데이터베이스입니다. 웹페이지가 사용자의 PC나 휴대폰 안에 데이터를 많이, 구조적으로 저장할 때 씁니다. 따로 설치할 것이 없고 Chrome, Safari, Firefox 등 주요 브라우저와 앱 속 웹뷰에서 모두 동작합니다. 이 글에서 언급하는 오픈소스 라이브러리의 원본 주소와 라이선스는 글 끝에 모아 두었습니다.

Capacitor로 웹앱을 앱으로 만들면 앱 안에서도 IndexedDB를 그대로 쓸 수 있습니다. 그렇다면 휴대폰에서 IndexedDB에 무엇을 얼마나 믿고 맡겨도 될까요? 이 글에서는 IndexedDB의 구조와 쓰는 법, 다른 저장 방법과의 차이, 휴대폰에서 특히 조심할 점을 정리합니다.
핵심 요약
- IndexedDB는 JavaScript 객체와 파일을 키·인덱스와 함께 저장하는 브라우저 내장 데이터베이스로, localStorage보다 훨씬 많이 저장하고 빠르게 찾을 수 있습니다.
- 기본 API는 장황하므로 실무에서는 Dexie.js나 idb 같은 작은 라이브러리를 많이 씁니다.
- 휴대폰, 특히 iOS에서는 저장 공간이 부족하면 데이터가 지워질 수 있으므로, 중요한 데이터는 네이티브 저장소나 서버에 두고 IndexedDB는 빠른 사본으로 써야 합니다.
IndexedDB는 표가 아니라 객체를 담는 데이터베이스입니다

IndexedDB는 행과 열로 이루어진 표(SQL) 대신 객체 저장소에 데이터를 넣습니다. { text: '장보기', createdAt: ... } 같은 JavaScript 객체를 통째로 저장하고, 각 객체는 고유한 키(예: id)로 꺼냅니다. 이런 방식을 NoSQL이라고 부르며, 표의 칸을 미리 정하지 않아도 되고 이미지 같은 파일(Blob)도 그대로 넣을 수 있습니다.
자주 찾는 항목에는 인덱스(검색용 색인)를 만들 수 있습니다. 예를 들어 작성 날짜에 인덱스를 걸어 두면 최근 글 10개를 빠르게 꺼낼 수 있습니다. 여러 작업을 묶어 처리하다가 중간에 실패하면 모두 되돌리는 트랜잭션도 지원합니다.
데이터는 사이트(도메인)마다 따로 보관됩니다. 한 사이트가 저장한 데이터는 다른 사이트에서 읽을 수 없습니다. 또 모든 작업이 비동기로 처리되므로 데이터를 저장하는 동안에도 화면이 멈추지 않습니다.
기본 API는 길어서 보통 라이브러리를 씁니다
브라우저 기본 API는 이벤트 방식이라 간단한 저장에도 코드가 길어집니다. 데이터베이스를 열고, 처음이면 저장소를 만들고, 트랜잭션을 열어 저장하는 순서를 모두 직접 써야 합니다.
const req = indexedDB.open('memo-db', 1);
req.onupgradeneeded = () => req.result.createObjectStore('memos', { keyPath: 'id' });
req.onsuccess = () => {
const tx = req.result.transaction('memos', 'readwrite');
tx.objectStore('memos').put({ id: 1, text: '장보기' });
};
그래서 실무에서는 Dexie.js나 idb 같은 작은 라이브러리를 많이 씁니다. Dexie.js를 쓰면 저장소와 인덱스를 한 줄로 정의하고, await로 저장과 조회를 짧게 쓸 수 있습니다.
import Dexie from 'dexie';
const db = new Dexie('memo-db');
db.version(1).stores({ memos: '++id, createdAt' });
await db.memos.add({ text: '장보기', createdAt: Date.now() });
const recent = await db.memos.orderBy('createdAt').reverse().limit(10).toArray();
'++id, createdAt'은 id를 자동으로 1씩 늘어나는 키로 쓰고, createdAt에 인덱스를 만든다는 뜻입니다. 기본 API를 그대로 쓰되 Promise로만 감싸고 싶다면 더 가벼운 idb가 맞습니다.
localStorage보다 크고 빠르지만 쓰임새가 다릅니다
브라우저에는 localStorage라는 더 간단한 저장소도 있습니다. 문자열 키와 값을 한 줄로 저장할 수 있어 편하지만, 용량이 보통 5MB 안팎으로 작고 동기 방식이라 큰 데이터를 다루면 화면이 잠깐 멈출 수 있습니다. 검색이나 정렬도 직접 구현해야 합니다.
IndexedDB는 기기 여유 공간에 따라 수백 MB 이상도 저장할 수 있고, 인덱스로 검색·정렬하며, 파일도 넣을 수 있습니다. 그래서 테마나 마지막으로 연 탭 같은 작은 설정은 localStorage에, 오프라인에서 보여 줄 글 목록이나 사진, 작성 중인 임시 글처럼 크고 구조가 있는 데이터는 IndexedDB에 두는 것이 일반적입니다.
휴대폰에서는 데이터가 지워질 수 있다고 가정해야 합니다
IndexedDB의 가장 큰 약점은 운영체제나 브라우저가 데이터를 비울 수 있다는 점입니다. 기기 저장 공간이 부족해지면 브라우저는 웹사이트 데이터를 정리할 수 있고, iOS의 Safari는 오랫동안 방문하지 않은 사이트의 데이터를 지우기도 합니다. navigator.storage.persist()로 데이터를 지우지 말아 달라고 요청할 수는 있지만, 받아들여진다는 보장은 없습니다.
Capacitor 앱도 마찬가지입니다. Capacitor 공식 문서는 웹뷰의 localStorage는 언젠가 사라질 수 있는 임시 데이터로 다뤄야 하고, IndexedDB도 적어도 iOS에서는 같은 위험이 있다고 안내합니다. 안드로이드에서는 persist 요청으로 IndexedDB를 지속 저장 상태로 표시할 수 있습니다. 그래서 문서는 작은 설정은 @capacitor/preferences에, 많고 중요한 데이터는 SQLite 플러그인처럼 앱이 직접 관리하는 네이티브 저장소에 두라고 권합니다.
무엇을 어디에 저장할지 먼저 정해야 합니다

정리하면 저장 위치는 데이터를 잃었을 때의 피해로 고르면 됩니다. 사라져도 다시 받으면 되는 캐시와 오프라인 사본은 IndexedDB에, 앱을 지우기 전까지는 남아 있어야 하는 로그인 정보나 기기 데이터는 네이티브 저장소에 둡니다.
그리고 잃으면 안 되는 데이터의 원본은 서버에 둡니다. IndexedDB는 서버 데이터를 기기에 복사해 두고 인터넷이 끊겨도 빠르게 보여 주는 용도로 쓰고, 연결이 돌아오면 서버와 다시 맞추는 구조가 가장 안전합니다.
| 구분 | 내용 | 시사점 |
|---|---|---|
| localStorage | 문자열 키-값, 약 5MB, 동기 방식 | 테마 같은 작은 설정에만 씁니다 |
| IndexedDB | 객체·파일·인덱스, 대용량, 비동기 | 오프라인 데이터와 캐시에 맞지만 iOS에서 지워질 수 있습니다 |
| 네이티브 저장소 | Capacitor Preferences, SQLite 플러그인 | 앱을 지우기 전까지 남아야 하는 데이터에 씁니다 |
| 서버 | 데이터의 원본 | 기기를 바꾸거나 데이터가 지워져도 복구할 수 있습니다 |
정리하며
IndexedDB는 브라우저와 앱 속 웹뷰에 기본으로 들어 있는 대용량 객체 데이터베이스입니다. 객체와 파일을 키와 인덱스로 저장해 빠르게 꺼낼 수 있고, Dexie.js나 idb를 쓰면 코드도 짧아집니다.
다만 휴대폰에서는 데이터가 지워질 수 있다는 점을 전제로 설계해야 합니다. IndexedDB는 빠른 사본, 원본은 서버나 네이티브 저장소라는 원칙만 지키면 오프라인에서도 빠른 웹앱을 안전하게 만들 수 있습니다.
원본과 라이선스
- Dexie.js · Dexie 프로젝트 · Apache-2.0 · github.com/dexie/Dexie.js
- idb · Jake Archibald · ISC · github.com/jakearchibald/idb
- Capacitor Preferences · Ionic 팀 · MIT · github.com/ionic-team/capacitor-plugins
- Capacitor SQLite · Capacitor 커뮤니티 · MIT · github.com/capacitor-community/sqlite
라이선스는 2026년 10월 26일 기준 각 GitHub 저장소와 npm 배포 정보에서 확인했습니다.
한마디로 정리하면
IndexedDB는 휴대폰 안에 놓인 개인 서랍장입니다. 칸마다 이름표(인덱스)가 붙어 있어 물건을 빨리 찾을 수 있고, 냉장고에 붙이는 메모지 한 장(localStorage)보다 훨씬 많이 넣을 수 있습니다. 사진 같은 큰 물건도 그대로 들어갑니다.
다만 이 서랍장은 셋방에 놓여 있습니다. 집이 비좁아지면 집주인(운영체제)이 말없이 서랍을 비울 수 있습니다. 그래서 자주 꺼내 쓰는 물건은 서랍에 두더라도, 계속 갖고 있어야 하는 물건은 내 방 금고(네이티브 저장소)에 넣어야 합니다.
잃어버리면 안 되는 원본은 은행 금고(서버)에 맡기고, 서랍장에는 빨리 꺼내 쓸 사본만 두는 것이 가장 안전한 사용법입니다.
'IT·AI 도구' 카테고리의 다른 글
| UI 컴포넌트와 디자인 패턴은 어떻게 분류할까? (0) | 2026.10.26 |
|---|---|
| 네이티브 앱과 웹서비스를 함께 운영하려면 어떻게 할까? (0) | 2026.10.26 |
| Capacitor는 웹앱을 어떻게 앱으로 바꿀까? (0) | 2026.10.26 |
| 웹사이트를 앱으로 만들려면 어떤 방법을 골라야 할까? (1) | 2026.10.26 |
| PHP2Shell은 무엇이고 왜 위험할까? (0) | 2026.10.23 |
