A flashcard application for memorizing vocabulary, developed in Flutter.
- User Guide: Complete guide for using the app
- Architecture: Detailed technical documentation
- Contributing: Guidelines for contributors
- Changelog: Version history and changes
- Create decks: Create card decks with unique names
- Rename decks: Edit the name of existing decks
- Customize icons: Assign emoji icons to your decks for easy identification
- Archive decks: Move decks to the archive instead of deleting them
- Restore decks: Recover archived decks whenever you need them
- Delete decks: Remove decks permanently from the archive
- Predefined decks: Import pre-made vocabulary decks in English (A1-C1) and Spanish (A1-C1)
- View card count: Each deck displays how many cards it contains
- View modes: Toggle between grid and list view for displaying decks
- Sort decks: Order decks by name (A-Z or Z-A) or creation date (newest or oldest)
- Quick edit: Tap any card to edit it directly
- Add cards: Add new cards with word (front) and meaning (back)
- Edit cards: Modify the content of existing cards
- Delete cards: Remove individual cards from a deck
- Continuous dialog: After adding a card, the dialog reopens automatically to add more
- Interactive visualization: Tap the card to see the answer (can only be flipped once)
- Swipe gestures:
- Swipe right if you know the meaning
- Swipe left if you don't know it
- Answer buttons: You can also use the ✓ (correct) and ✗ (incorrect) buttons
- Progress counter: See how many cards you got right and wrong
- Position indicator: Shows which card you're reviewing (e.g., "Card 3 / 10")
- Final summary: When you finish the review, see your total score
- Repeat option: Review the deck again without leaving the screen
- Screen awake: Keeps the screen on during review (on mobile devices)
- Exit confirmation: Shows a confirmation dialog when trying to exit the review
- Export decks: Export all your decks to a JSON file
- Import decks: Import decks from a JSON file
- Conflict resolution: If an imported deck has the same name as an existing one, it's automatically renamed
- Themes: Switch between light, dark, or system automatic theme
- Languages: Supports English and Spanish, with option to follow system language
- Drawer navigation: Access all functions from the side menu
- About page: View app information, version, and developer details
The application follows the MVVM (Model-View-ViewModel) pattern for clear separation of concerns:
- Model: Data entities (Flashcard, Deck with icon and archive support)
- View: Flutter widgets (Views organized by feature) - UI and presentation only
- ViewModel: Business logic, validation, and state management
- Services: Data access (Database, predefined decks, settings)
- Providers: State management and data coordination
- ✅ Testability: Business logic is isolated and can be tested independently
- ✅ Maintainability: Changes in logic don't affect UI and vice versa
- ✅ Separation of concerns: Each layer has a clear purpose
- ✅ Reusability: ViewModels can be reused in different contexts
lib/
├── l10n/
│ └── app_localizations.dart # Internationalization system (i18n)
├── models/
│ ├── flashcard.dart # Model: Individual card
│ └── deck.dart # Model: Card deck with icon and archive support
├── viewmodels/
│ ├── base_viewmodel.dart # Base ViewModel with common functionality
│ ├── home_viewmodel.dart # ViewModel: Home screen logic
│ ├── deck_detail_viewmodel.dart # ViewModel: Deck detail logic
│ └── review_viewmodel.dart # ViewModel: Review logic
├── providers/
│ ├── deck_provider.dart # Provider: Deck and card management
│ └── settings_provider.dart # Provider: Settings, themes, and language
├── views/
│ ├── home/
│ │ ├── home_view.dart # View: Home screen (UI only)
│ │ ├── archived_decks_view.dart # View: Archived decks screen
│ │ ├── about_view.dart # View: About screen
│ │ └── widgets/ # Reusable widgets for home views
│ ├── deck_detail/
│ │ ├── deck_detail_view.dart # View: Card screen (UI only)
│ │ └── widgets/ # Reusable widgets for deck detail
│ ├── review/
│ │ ├── review_view.dart # View: Review screen (UI only)
│ │ └── widgets/ # Reusable widgets for review
│ └── settings/
│ ├── settings_view.dart # View: Settings screen
│ └── widgets/ # Reusable widgets for settings
├── services/
│ ├── database_service.dart # Service: SQLite database access
│ └── predefined_decks_service.dart # Service: Predefined vocabulary decks
└── main.dart # Application entry point
The application uses SQLite (with sqflite and sqflite_common_ffi) to automatically save all decks and cards locally. Data persists between application sessions and works on all platforms (Android, iOS, Windows, Linux, macOS).
Settings preferences (such as selected theme) are saved with shared_preferences.
The application includes pre-made vocabulary decks for language learning, organized by CEFR levels (Common European Framework of Reference for Languages).
English (🇬🇧):
- English A1 (Beginner)
- English A2 (Elementary)
- English B1 (Intermediate)
- English B2 (Upper Intermediate)
- English C1 (Advanced)
Spanish (🇪🇸):
- Español A1 (Principiante)
- Español A2 (Elemental)
- Español B1 (Intermedio)
- Español B2 (Intermedio alto)
- Español C1 (Avanzado)
- Español C1 (Avanzado)
- Open the drawer menu (☰)
- Select "Predefined Decks" / "Mazos Predefinidos"
- Browse available decks by language and level
- Tap "Import" / "Importar" on the decks you want to add
- The decks will be added to your collection and can be reviewed immediately
Note: Imported predefined decks are fully editable - you can add, edit, or remove cards as needed.
Instead of permanently deleting decks, you can archive them to keep your main view organized while preserving the data.
- Archive decks: Move decks to the archive instead of deleting them
- View archived decks: Access all archived decks from the drawer menu
- Restore decks: Bring archived decks back to your main collection
- Permanent deletion: Delete decks permanently only from the archived view
- Sort archived decks: Same sorting options as the main view (name, date, card count)
To Archive:
- On the home screen, long press a deck
- Select "Archive" / "Archivar"
- The deck moves to the archived section
To Restore:
- Open the drawer menu (☰)
- Select "Archived Decks" / "Mazos Archivados"
- Long press the deck you want to restore
- Select "Restore" / "Restaurar"
To Delete Permanently:
- Open "Archived Decks" from the drawer
- Long press the deck you want to delete permanently
- Select "Delete Permanently" / "Eliminar Permanentemente"
- Confirm the action (this cannot be undone)
# Install dependencies
flutter pub get
# Run in debug mode
flutter run
# Build for release
flutter build apk # Android
flutter build ios # iOS- provider: State management
- sqflite / sqflite_common_ffi: Cross-platform SQLite database
- shared_preferences: Settings persistence
- uuid: Unique identifier generation
- wakelock_plus: Keep screen on during review
- file_picker: File selection for import
- path_provider: System directory access
- package_info_plus: Access to app version information
- flutter_localizations: Internationalization system
- intl: Internationalization utilities
- Create a deck: On the home screen, tap the "+" button and enter the deck name
- Choose an icon: Select an emoji icon for your deck (optional)
- Use predefined decks: From the drawer menu, select "Predefined Decks" to import vocabulary decks in English or Spanish (levels A1-C1)
- Add cards: Enter the deck and tap the "+" button to add cards with word and meaning
- Review: Tap the "play" icon in the deck's top bar to start reviewing
- Interact with cards: Tap to flip the card and swipe or use buttons to answer
- Sort decks: Use the sort button (⋮) to organize decks by name or date
- Toggle view: Tap the view mode button to switch between grid and list view
- Archive decks: Long press a deck and select "Archive" to move it out of the main view
- Restore decks: Access "Archived Decks" from the drawer menu to restore or permanently delete decks
- Change theme: Open the side menu (☰) → Settings → Theme
- Change language: Open the side menu (☰) → Settings → Language
- Export/Import: Open the side menu (☰) → Export/Import Decks
- About: View app information from the drawer menu → About
Decks are exported in JSON format with the following structure:
{
"version": "1.0",
"exportDate": "2026-01-15T10:30:00.000Z",
"decks": [
{
"name": "Deck Name",
"icon": "📚",
"archived": false,
"cards": [
{
"front": "Word or question",
"back": "Meaning or answer"
}
]
}
]
}- version (string): Export format version
- exportDate (string): Export date and time in ISO 8601 format
- decks (array): List of decks
- name (string): Deck name
- icon (string, optional): Emoji icon for the deck. If not provided, the default icon (📚) will be used
- archived (boolean, optional): Whether the deck is archived. Defaults to false if not provided
- cards (array): List of cards in the deck
- front (string): Front text of the card (question/word)
- back (string): Back text of the card (answer/meaning)
- When importing, if a deck with the same name exists, it will be automatically renamed by adding a number in parentheses (e.g., "Deck (1)")
- Unique identifiers (IDs) are automatically generated on import
- The file must have a
.jsonextension - The
versionandexportDatefields are optional for import, butdecksis required - The format is simple and readable; you can create JSON files manually following this structure
# Export
1. Open the drawer (side menu)
2. Select "Export Decks"
3. Confirm the export in the dialog
4. Select the folder where to save the file
5. The file will be saved with the name flashcards_export_[timestamp].json
# Import
1. Open the drawer (side menu)
2. Select "Import Decks"
3. Read the dialog information and confirm
4. Select the JSON file to import
5. Review the import summary and confirm
6. Decks will be imported automaticallyThe application supports multiple languages thanks to the internationalization system (i18n):
- English
- Spanish (Español)
- System (follows device language)
- Open the side menu (☰)
- Select "Settings" / "Configuración"
- Tap "Language" / "Idioma"
- Select your preferred language
To add support for a new language:
- Open
lib/l10n/app_localizations.dart - Add translations to the
_localizedValuesmap:'fr': { // Language code (e.g., French) 'appTitle': 'Flashcards', 'myDecks': 'Mes Paquets', // ... more translations }
- Update the
isSupportedmethod in_AppLocalizationsDelegate:bool isSupported(Locale locale) { return ['en', 'es', 'fr'].contains(locale.languageCode); }
- Add the locale in
main.dart:supportedLocales: const [ Locale('en', ''), Locale('es', ''), Locale('fr', ''), ],
- Update
settings_screen.dartto include the new option in the language selection dialog
We welcome contributions! Please see CONTRIBUTING.md for guidelines on:
- Setting up the development environment
- Code style and best practices
- Submitting pull requests
- Reporting issues
Copyright © 2026 SC.
- Issues: Report bugs or request features on GitHub Issues
- Discussions: Join the community discussions
- Documentation: Check the docs folder for detailed guides
Built with:
- Flutter - UI framework
- Provider - State management
- SQLite - Local database
- Various other amazing open-source packages (see Dependencies)
Made with ❤️ using Flutter



