Managing local data without a full-fledged database like SQLite is often ideal for simple applications. In Dart, you can use a JSON file as a lightweight and easy-to-manage local database. This approach works well for storing structured data like user settings, lists, or even offline content.

In this tutorial, you’ll learn how to read and write data from a local JSON file in Dart, simulating database behavior with simple file operations. This is especially useful for Flutter apps that require offline storage with low complexity.
Step 1: Create the JSON File
Create a JSON file named data.json
and place it in the assets
folder of your Flutter project.
[ { "id": 1, "name": "John Doe", "email": "john@example.com" }, { "id": 2, "name": "Jane Smith", "email": "jane@example.com" } ]
Don’t forget to register it in pubspec.yaml
:
flutter: assets: - assets/data.json
Step 2: Create the Model Class
// models/user.dart class User { final int id; final String name; final String email; User({required this.id, required this.name, required this.email}); factory User.fromJson(Map<String, dynamic> json) { return User( id: json['id'], name: json['name'], email: json['email'], ); } Map<String, dynamic> toJson() => { 'id': id, 'name': name, 'email': email, }; }
Step 3: Local JSON Database Service
// services/json_database.dart import 'dart:convert'; import 'dart:io'; import 'package:flutter/services.dart' show rootBundle; import '../models/user.dart'; class JsonDatabase { List<User> _users = []; Future<void> loadData() async { final dataString = await rootBundle.loadString('assets/data.json'); final List<dynamic> jsonData = json.decode(dataString); _users = jsonData.map((json) => User.fromJson(json)).toList(); } List<User> getAllUsers() { return _users; } User? getUserById(int id) { return _users.firstWhere((user) => user.id == id, orElse: () => User(id: 0, name: 'Not Found', email: '')); } void addUser(User user) { _users.add(user); } String exportToJson() { return jsonEncode(_users.map((user) => user.toJson()).toList()); } }
Note: For real-time writable local files, consider using path_provider to access and modify files within the app’s document directory.