Persisting Data with SQLite Using sqflite
May 28, 2025



Summary
Summary
Summary
Summary
This tutorial details how to set up the sqflite plugin in Flutter, create models, perform CRUD operations, and display data. It also covers batch operations, schema migrations, and data encryption for secure, high-performance mobile app storage.
This tutorial details how to set up the sqflite plugin in Flutter, create models, perform CRUD operations, and display data. It also covers batch operations, schema migrations, and data encryption for secure, high-performance mobile app storage.
This tutorial details how to set up the sqflite plugin in Flutter, create models, perform CRUD operations, and display data. It also covers batch operations, schema migrations, and data encryption for secure, high-performance mobile app storage.
This tutorial details how to set up the sqflite plugin in Flutter, create models, perform CRUD operations, and display data. It also covers batch operations, schema migrations, and data encryption for secure, high-performance mobile app storage.
Key insights:
Key insights:
Key insights:
Key insights:
Local Persistence: SQLite via sqflite enables secure local storage without a backend.
Easy Integration: Simple dependency setup and database initialization.
CRUD Operations: Models and methods simplify data handling.
UI Binding: Load and show data using stateful widgets.
Advanced Techniques: Batch inserts, schema migrations, and encryption.
Scalable Pattern: Supports complex schemas for robust apps.
Introduction
Persisting data locally is a common requirement for mobile apps. Flutter SQLite integration—using the sqflite plugin—provides a lightweight, high-performance solution. Whether you need a simple key-value store or a fully relational SQLite database, sqflite lets you execute SQL commands and manage data without a remote backend. In this tutorial, you’ll learn how to set up sqflite in your Flutter project, define a data model, create CRUD operations, and display persisted data in your UI.
Adding sqflite to Your Project
Start by adding the required dependencies to your pubspec.yaml:
dependencies:
flutter:
sdk: flutter
sqflite: ^2.0.0+4
path
Run flutter pub get to install. The path package helps construct platform-specific file paths for your SQLite file.
Initializing the SQLite Database
Create a singleton database helper to open and initialize your database. Inside lib/db_helper.dart:
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DBHelper {
static final DBHelper _instance = DBHelper._internal();
factory DBHelper() => _instance;
DBHelper._internal();
static Database? _db;
Future<Database> get database async {
if (_db != null) return _db!;
final dbPath = await getDatabasesPath();
final path = join(dbPath, 'notes.db');
_db = await openDatabase(
path,
version: 1,
onCreate: (db, version) => db.execute(
'CREATE TABLE notes(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT)',
),
);
return _db!;
}
}
This setup uses Flutter SQLite via sqflite to open “notes.db”, creating a table for storing note entries.
Defining the Data Model and CRUD Operations
Model classes encapsulate data and map it to rows in your SQLite database. In lib/note.dart:
class Note {
final int? id;
final String title;
final String content;
Note({this.id, required this.title, required this.content});
Map<String, dynamic> toMap() {
return {'id': id, 'title': title, 'content': content};
}
factory Note.fromMap(Map<String, dynamic> map) {
return Note(
id: map['id'],
title: map['title'],
content: map['content'],
);
}
}
Expand DBHelper with CRUD methods in db_helper.dart:
// Inside DBHelper class
Future<int> insertNote(Note note) async {
final db = await database;
return await db.insert('notes', note.toMap());
}
Future<List<Note>> fetchNotes() async {
final db = await database;
final maps = await db.query('notes', orderBy: 'id DESC');
return List.generate(maps.length, (i) => Note.fromMap(maps[i]));
}
Future<int> updateNote(Note note) async {
final db = await database;
return db.update('notes', note.toMap(),
where: 'id = ?', whereArgs: [note.id]);
}
Future<int> deleteNote(int id) async {
final db = await database;
return db.delete('notes', where: 'id = ?', whereArgs: [id]);
}
With these methods, you can insert, retrieve, update, and delete rows in your SQLite database.
Displaying Data in the UI
Use a StatefulWidget to load and display notes. In lib/main.dart:
import 'package:flutter/material.dart';
import 'db_helper.dart';
import 'note.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: NoteList());
}
}
class NoteList extends StatefulWidget {
@override
_NoteListState createState() => _NoteListState();
}
class _NoteListState extends State<NoteList> {
late Future<List<Note>> _noteList;
@override
void initState() {
super.initState();
_refreshNotes();
}
void _refreshNotes() {
_noteList = DBHelper().fetchNotes();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Flutter SQLite Demo')),
body: FutureBuilder<List<Note>>(
future: _noteList,
builder: (ctx, snap) {
if (!snap.hasData) return Center(child: CircularProgressIndicator());
final notes = snap.data!;
return ListView.builder(
itemCount: notes.length,
itemBuilder: (_, i) => ListTile(
title: Text(notes[i].title),
subtitle: Text(notes[i].content),
),
);
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () async {
await DBHelper().insertNote(
Note(title: 'New Note', content: 'Details here'),
);
setState(_refreshNotes);
},
),
);
}
}
This example demonstrates sqflite in action: fetching, displaying, and inserting into an SQLite database.
Advanced Tips
• Batch Operations: Use transactions for bulk inserts to improve performance.
• Migrations: Handle schema changes by passing an onUpgrade callback to openDatabase.
• Encryption: For sensitive data, consider using sqflite_sqlcipher for encrypted SQLite.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
You’ve learned how to integrate Flutter SQLite using the sqflite plugin: adding dependencies, initializing the database, defining models, implementing CRUD operations, and displaying data in widgets. This pattern can scale to more complex schemas and relationships in a robust SQLite database.
With these building blocks, you’re ready to persist complex data and build rich offline experiences in Flutter. Happy coding!
Introduction
Persisting data locally is a common requirement for mobile apps. Flutter SQLite integration—using the sqflite plugin—provides a lightweight, high-performance solution. Whether you need a simple key-value store or a fully relational SQLite database, sqflite lets you execute SQL commands and manage data without a remote backend. In this tutorial, you’ll learn how to set up sqflite in your Flutter project, define a data model, create CRUD operations, and display persisted data in your UI.
Adding sqflite to Your Project
Start by adding the required dependencies to your pubspec.yaml:
dependencies:
flutter:
sdk: flutter
sqflite: ^2.0.0+4
path
Run flutter pub get to install. The path package helps construct platform-specific file paths for your SQLite file.
Initializing the SQLite Database
Create a singleton database helper to open and initialize your database. Inside lib/db_helper.dart:
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
class DBHelper {
static final DBHelper _instance = DBHelper._internal();
factory DBHelper() => _instance;
DBHelper._internal();
static Database? _db;
Future<Database> get database async {
if (_db != null) return _db!;
final dbPath = await getDatabasesPath();
final path = join(dbPath, 'notes.db');
_db = await openDatabase(
path,
version: 1,
onCreate: (db, version) => db.execute(
'CREATE TABLE notes(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, content TEXT)',
),
);
return _db!;
}
}
This setup uses Flutter SQLite via sqflite to open “notes.db”, creating a table for storing note entries.
Defining the Data Model and CRUD Operations
Model classes encapsulate data and map it to rows in your SQLite database. In lib/note.dart:
class Note {
final int? id;
final String title;
final String content;
Note({this.id, required this.title, required this.content});
Map<String, dynamic> toMap() {
return {'id': id, 'title': title, 'content': content};
}
factory Note.fromMap(Map<String, dynamic> map) {
return Note(
id: map['id'],
title: map['title'],
content: map['content'],
);
}
}
Expand DBHelper with CRUD methods in db_helper.dart:
// Inside DBHelper class
Future<int> insertNote(Note note) async {
final db = await database;
return await db.insert('notes', note.toMap());
}
Future<List<Note>> fetchNotes() async {
final db = await database;
final maps = await db.query('notes', orderBy: 'id DESC');
return List.generate(maps.length, (i) => Note.fromMap(maps[i]));
}
Future<int> updateNote(Note note) async {
final db = await database;
return db.update('notes', note.toMap(),
where: 'id = ?', whereArgs: [note.id]);
}
Future<int> deleteNote(int id) async {
final db = await database;
return db.delete('notes', where: 'id = ?', whereArgs: [id]);
}
With these methods, you can insert, retrieve, update, and delete rows in your SQLite database.
Displaying Data in the UI
Use a StatefulWidget to load and display notes. In lib/main.dart:
import 'package:flutter/material.dart';
import 'db_helper.dart';
import 'note.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: NoteList());
}
}
class NoteList extends StatefulWidget {
@override
_NoteListState createState() => _NoteListState();
}
class _NoteListState extends State<NoteList> {
late Future<List<Note>> _noteList;
@override
void initState() {
super.initState();
_refreshNotes();
}
void _refreshNotes() {
_noteList = DBHelper().fetchNotes();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Flutter SQLite Demo')),
body: FutureBuilder<List<Note>>(
future: _noteList,
builder: (ctx, snap) {
if (!snap.hasData) return Center(child: CircularProgressIndicator());
final notes = snap.data!;
return ListView.builder(
itemCount: notes.length,
itemBuilder: (_, i) => ListTile(
title: Text(notes[i].title),
subtitle: Text(notes[i].content),
),
);
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () async {
await DBHelper().insertNote(
Note(title: 'New Note', content: 'Details here'),
);
setState(_refreshNotes);
},
),
);
}
}
This example demonstrates sqflite in action: fetching, displaying, and inserting into an SQLite database.
Advanced Tips
• Batch Operations: Use transactions for bulk inserts to improve performance.
• Migrations: Handle schema changes by passing an onUpgrade callback to openDatabase.
• Encryption: For sensitive data, consider using sqflite_sqlcipher for encrypted SQLite.
Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.
Conclusion
You’ve learned how to integrate Flutter SQLite using the sqflite plugin: adding dependencies, initializing the database, defining models, implementing CRUD operations, and displaying data in widgets. This pattern can scale to more complex schemas and relationships in a robust SQLite database.
With these building blocks, you’re ready to persist complex data and build rich offline experiences in Flutter. Happy coding!
Build Your Next Flutter App Faster
Build Your Next Flutter App Faster
Build Your Next Flutter App Faster
Build Your Next Flutter App Faster
Vibe Studio combines Flutter with Firebase to create beautiful apps efficiently—no coding required.
Vibe Studio combines Flutter with Firebase to create beautiful apps efficiently—no coding required.
Vibe Studio combines Flutter with Firebase to create beautiful apps efficiently—no coding required.
Vibe Studio combines Flutter with Firebase to create beautiful apps efficiently—no coding required.
Join a growing community of builders today
Join a growing
community
of builders today
Join a growing
community
of builders today










© Steve • All Rights Reserved 2025


© Steve • All Rights Reserved 2025


© Steve • All Rights Reserved 2025


© Steve • All Rights Reserved 2025