{"id":47943672,"url":"https://github.com/fluttersdk/magic","last_synced_at":"2026-04-04T08:17:20.041Z","repository":{"id":336669640,"uuid":"1125193903","full_name":"fluttersdk/magic","owner":"fluttersdk","description":"Build production-ready Flutter apps with Facades, Eloquent ORM, Service Providers, and IoC Container — zero boilerplate.","archived":false,"fork":false,"pushed_at":"2026-03-25T00:07:38.000Z","size":1347,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-03-25T22:47:11.238Z","etag":null,"topics":["flutter","framework","mvc","orm"],"latest_commit_sha":null,"homepage":"https://magic.fluttersdk.com","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fluttersdk.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-30T09:52:06.000Z","updated_at":"2026-03-25T00:07:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fluttersdk/magic","commit_stats":null,"previous_names":["fluttersdk/magic"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/fluttersdk/magic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluttersdk%2Fmagic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluttersdk%2Fmagic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluttersdk%2Fmagic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluttersdk%2Fmagic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fluttersdk","download_url":"https://codeload.github.com/fluttersdk/magic/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluttersdk%2Fmagic/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31392536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T04:26:24.776Z","status":"ssl_error","status_checked_at":"2026-04-04T04:23:34.147Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flutter","framework","mvc","orm"],"created_at":"2026-04-04T08:17:19.505Z","updated_at":"2026-04-04T08:17:20.022Z","avatar_url":"https://github.com/fluttersdk.png","language":"Dart","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/fluttersdk/magic/master/.github/magic-logo.svg\" width=\"120\" alt=\"Magic Logo\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eMagic\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eThe Laravel Experience for Flutter.\u003c/strong\u003e\u003cbr/\u003e\n  Build production-ready Flutter apps with Facades, Eloquent ORM, Service Providers, and IoC Container — zero boilerplate.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://pub.dev/packages/magic\"\u003e\u003cimg src=\"https://img.shields.io/pub/v/magic.svg\" alt=\"pub package\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/fluttersdk/magic/actions\"\u003e\u003cimg src=\"https://img.shields.io/github/actions/workflow/status/fluttersdk/magic/ci.yml?branch=master\u0026label=CI\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-blue.svg\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://pub.dev/packages/magic/score\"\u003e\u003cimg src=\"https://img.shields.io/pub/points/magic\" alt=\"pub points\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/fluttersdk/magic/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/fluttersdk/magic?style=flat\" alt=\"GitHub stars\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://magic.fluttersdk.com\"\u003eDocumentation\u003c/a\u003e ·\n  \u003ca href=\"https://pub.dev/packages/magic\"\u003epub.dev\u003c/a\u003e ·\n  \u003ca href=\"https://github.com/fluttersdk/magic/issues\"\u003eIssues\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n\u003e **Alpha Release** — Magic is under active development. APIs may change before stable. [Star the repo](https://github.com/fluttersdk/magic) to follow progress.\n\n## Why Magic?\n\nFlutter gives you widgets, but not architecture. Building a real app means wiring up HTTP clients, auth flows, caching, validation, routing, and state management — all from scratch, every time.\n\n**Magic fixes this.** If you know Laravel, you already know Magic:\n\n```dart\n// Before — the Flutter way\nfinal dio = Dio(BaseOptions(baseUrl: 'https://api.example.com'));\nfinal response = await dio.get('/users/1');\nfinal user = User.fromJson(response.data['data']);\n// ...manually handle tokens, errors, caching, state...\n\n// After — the Magic way\nfinal user = await User.find(1);\n```\n\n## Features\n\n| | Feature | Description |\n|:--|:--------|:------------|\n| 🏗️ | **IoC Container** | Service Container with singleton, bind, and instance registration |\n| 🎭 | **16 Facades** | `Auth`, `Http`, `Cache`, `DB`, `Event`, `Gate`, `Log`, `Route`, `Lang`, `Storage`, `Vault`, `Crypt` and more |\n| 🗄️ | **Eloquent ORM** | Models, QueryBuilder, migrations, seeders, factories — hybrid API + SQLite persistence |\n| 🛣️ | **Routing** | GoRouter integration with middleware, named routes, and context-free navigation |\n| 🔐 | **Authentication** | Token-based auth with guards (Bearer, BasicAuth, ApiKey), session restore, auto-refresh |\n| 🛡️ | **Authorization** | Gates, policies, `MagicCan` / `MagicCannot` widgets |\n| ✅ | **Validation** | Laravel-style rules: `Required`, `Email`, `Min`, `Max`, `In`, `Confirmed` |\n| 📡 | **Events** | Pub/sub event system with `MagicEvent` and `MagicListener` |\n| 💾 | **Caching** | Memory and file drivers with TTL and `remember()` |\n| 🌍 | **Localization** | JSON-based i18n with `:attribute` placeholders |\n| 🎨 | **Wind UI** | Built-in Tailwind CSS-like styling with `className` syntax |\n| 🧰 | **Magic CLI** | Artisan-style code generation: `magic make:model`, `magic make:controller` |\n\n## Quick Start\n\n### 1. Add Magic to Your Project\n\n```bash\n# Create a new Flutter project (or use an existing one)\nflutter create my_app\ncd my_app\n\n# Add Magic as a dependency\nflutter pub add magic\n```\n\n### 2. Scaffold with Magic CLI\n\nMagic CLI is bundled with the package — no global install needed:\n\n```bash\n# Initialize Magic with all features\ndart run magic:magic install\n\n# Or exclude specific features\ndart run magic:magic install --without-database --without-auth\n```\n\nThe CLI sets up everything: directory structure, config files, service providers, environment files, and bootstraps `main.dart`.\n\n\u003e [!TIP]\n\u003e For convenience, you can also activate the CLI globally: `dart pub global activate magic_cli`, then use `magic install` directly.\n\n### 3. Build\n\n```dart\nclass UserController extends MagicController with MagicStateMixin\u003cList\u003cUser\u003e\u003e {\n  static UserController get instance =\u003e Magic.findOrPut(UserController.new);\n\n  Future\u003cvoid\u003e fetchUsers() async {\n    setLoading();\n    final response = await Http.get('/users');\n    response.successful\n        ? setSuccess(response.data['data'].map((e) =\u003e User.fromMap(e)).toList())\n        : setError(response.firstError ?? 'Failed to load');\n  }\n\n  Widget index() =\u003e renderState(\n    (users) =\u003e ListView.builder(\n      itemCount: users.length,\n      itemBuilder: (_, i) =\u003e ListTile(title: Text(users[i].name ?? '')),\n    ),\n    onLoading: const CircularProgressIndicator(),\n    onError: (msg) =\u003e Text('Error: $msg'),\n  );\n}\n```\n\n## Facades\n\n### Auth\n\n```dart\n// Login with token and user model\nfinal response = await Http.post('/login', data: credentials);\nfinal user = User.fromMap(response['data']['user']);\nawait Auth.login({'token': response['data']['token']}, user);\n\n// Check authentication\nif (Auth.check()) {\n  final user = Auth.user\u003cUser\u003e();\n}\n\n// Restore session on app start\nawait Auth.restore();\n\n// Logout\nawait Auth.logout();\n```\n\n### HTTP Client\n\n```dart\n// Standard requests\nfinal response = await Http.get('/users', query: {'page': 1});\nawait Http.post('/users', data: {'name': 'John', 'email': 'john@example.com'});\nawait Http.put('/users/1', data: {'name': 'Jane'});\nawait Http.delete('/users/1');\n\n// RESTful resource helpers\nfinal users = await Http.index('users', filters: {'role': 'admin'});\nfinal user = await Http.show('users', '1');\nawait Http.store('users', {'name': 'John'});\nawait Http.update('users', '1', {'name': 'Jane'});\nawait Http.destroy('users', '1');\n\n// File upload\nawait Http.upload('/avatar', data: {'user_id': '1'}, files: {'photo': file});\n\n// Response API\nresponse.successful   // 200-299\nresponse.failed       // \u003e= 400\nresponse.data         // Map\u003cString, dynamic\u003e\nresponse['key']       // Shorthand access\nresponse.errors       // Laravel validation errors (422)\nresponse.firstError   // First error message\n```\n\n### Routing\n\n```dart\n// Define routes\nMagicRoute.page('/home', () =\u003e HomeController.instance.index());\nMagicRoute.page('/users/:id', () =\u003e UserController.instance.show());\n\n// Route groups with middleware\nMagicRoute.group(\n  prefix: '/admin',\n  middleware: [AuthMiddleware()],\n  routes: () {\n    MagicRoute.page('/dashboard', () =\u003e AdminController.instance.index());\n  },\n);\n\n// Navigate (context-free)\nMagicRoute.to('/users');\nMagicRoute.toNamed('user.show', params: {'id': '1'});\nMagicRoute.back();\nMagicRoute.replace('/login');\n```\n\n### Cache\n\n```dart\n// Store and retrieve\nawait Cache.put('key', 'value', ttl: Duration(minutes: 30));\nfinal value = await Cache.get('key');\n\n// Remember pattern — fetch once, cache for duration\nfinal users = await Cache.remember\u003cList\u003cUser\u003e\u003e(\n  'all_users',\n  Duration(minutes: 5),\n  () =\u003e fetchUsersFromApi(),\n);\n\n// Check and forget\nif (Cache.has('key')) {\n  await Cache.forget('key');\n}\nawait Cache.flush(); // Clear all\n```\n\n## Eloquent ORM\n\n```dart\nclass User extends Model with HasTimestamps, InteractsWithPersistence {\n  // Typed getters — always use get\u003cT\u003e()\n  int? get id =\u003e get\u003cint\u003e('id');\n  String? get name =\u003e get\u003cString\u003e('name');\n  String? get email =\u003e get\u003cString\u003e('email');\n\n  // Setters\n  set name(String? v) =\u003e set('name', v);\n  set email(String? v) =\u003e set('email', v);\n\n  // Required overrides\n  @override String get table =\u003e 'users';\n  @override String get resource =\u003e 'users';\n  @override List\u003cString\u003e get fillable =\u003e ['name', 'email'];\n\n  // Static finders\n  static Future\u003cUser?\u003e find(dynamic id) =\u003e\n      InteractsWithPersistence.findById\u003cUser\u003e(id, User.new);\n  static Future\u003cList\u003cUser\u003e\u003e all() =\u003e\n      InteractsWithPersistence.allModels\u003cUser\u003e(User.new);\n}\n\n// CRUD — hybrid persistence (API + local SQLite)\nfinal user = await User.find(1);     // SQLite first → API fallback → sync\nfinal users = await User.all();\nawait user.save();                    // POST (create) or PUT (update)\nawait user.delete();                  // DELETE\nawait user.refresh();                 // Re-fetch from API\n```\n\n## Validation\n\n```dart\nfinal validator = Validator.make(\n  {'email': email, 'password': password},\n  {\n    'email': [Required(), Email()],\n    'password': [Required(), Min(8)],\n  },\n);\n\nif (validator.fails()) {\n  print(validator.errors()); // {'email': 'The email field is required.'}\n}\n\n// Or throw on failure\nfinal data = validator.validate(); // Throws ValidationException if invalid\n```\n\n## Authorization\n\n```dart\n// Define abilities\nGate.define('update-post', (user, post) =\u003e user.id == post.userId);\nGate.before((user, ability) {\n  if (user.isAdmin) return true;\n  return null; // Fall through to specific check\n});\n\n// Check in code\nif (Gate.allows('update-post', post)) {\n  // Show edit button\n}\n\n// Check in widgets\nMagicCan(\n  ability: 'update-post',\n  arguments: post,\n  child: EditButton(),\n)\n```\n\n## Forms\n\n```dart\nfinal form = MagicFormData({\n  'name': user.name ?? '',\n  'email': user.email ?? '',\n});\n\n// In widget tree\nMagicForm(\n  formData: form,\n  child: Column(children: [\n    WFormInput(label: 'Name', controller: form['name']),\n    WFormInput(label: 'Email', controller: form['email']),\n    WButton(\n      onTap: () async {\n        if (form.validate()) {\n          await form.process(() =\u003e controller.updateProfile(form.data));\n        }\n      },\n      isLoading: form.isProcessing,\n      child: Text('Save'),\n    ),\n  ]),\n)\n```\n\n## Events\n\n```dart\n// Define event\nclass UserRegistered extends MagicEvent {\n  final User user;\n  UserRegistered(this.user);\n}\n\n// Dispatch\nawait Event.dispatch(UserRegistered(user));\n\n// Listen (register in ServiceProvider)\nEvent.listen\u003cUserRegistered\u003e(() =\u003e SendWelcomeEmail());\n```\n\n## Service Providers\n\n```dart\nclass AppServiceProvider extends ServiceProvider {\n  @override\n  void register() {\n    // Sync — bind to container\n    app.singleton('payment', () =\u003e StripeService());\n  }\n\n  @override\n  Future\u003cvoid\u003e boot() async {\n    // Async — other services available\n    Auth.registerModel\u003cUser\u003e(User.fromMap);\n  }\n}\n\n// Register in config\nfinal appConfig = {\n  'app': {\n    'providers': [\n      (app) =\u003e AppServiceProvider(app),\n    ],\n  },\n};\n```\n\n## Wind UI\n\nMagic includes [Wind UI](https://wind.fluttersdk.com/getting-started/installation) — a utility-first styling engine inspired by Tailwind CSS. Build UIs with `className` strings instead of nested widget trees.\n\n```dart\nWDiv(\n  className: 'flex flex-col gap-4 p-6 bg-white dark:bg-gray-900 rounded-xl shadow-lg',\n  children: [\n    WText('Dashboard', className: 'text-2xl font-bold text-gray-900 dark:text-white'),\n    WButton(\n      onTap: _refresh,\n      className: 'bg-blue-600 hover:bg-blue-700 text-white px-6 py-3 rounded-lg',\n      child: Text('Refresh'),\n    ),\n  ],\n)\n```\n\n\u003e See [Wind UI Documentation](https://wind.fluttersdk.com/getting-started/installation) for the complete widget reference and utility class guide.\n\n## CLI Commands\n\n```bash\ndart run magic:magic make:model User -mcf        # Model + migration + controller + factory\ndart run magic:magic make:controller User         # Controller\ndart run magic:magic make:view Login              # View class\ndart run magic:magic make:migration create_users  # Migration\ndart run magic:magic make:seeder UserSeeder       # Database seeder\ndart run magic:magic make:policy Post             # Authorization policy\ndart run magic:magic make:provider Payment        # Service provider\ndart run magic:magic make:event OrderShipped      # Event class\ndart run magic:magic make:listener SendEmail      # Event listener\ndart run magic:magic make:middleware Auth          # Middleware\ndart run magic:magic make:request StoreUser       # Form request\ndart run magic:magic make:lang tr                 # Language file\ndart run magic:magic make:enum Status             # Enum class\n```\n\n\u003e [!TIP]\n\u003e If you activated the CLI globally (`dart pub global activate magic_cli`), you can use the shorter `magic \u003ccommand\u003e` syntax instead.\n\n## Architecture\n\n```\nMagic.init() → Env.load() → configFactories → providers register() → providers boot() → app ready\n```\n\n```\nlib/\n├── config/              # Configuration files (app, auth, cache, database)\n├── app/\n│   ├── controllers/     # Request handlers (MagicController)\n│   ├── models/          # Eloquent models\n│   └── policies/        # Authorization policies\n├── database/\n│   ├── migrations/      # Schema migrations\n│   ├── seeders/         # Database seeders\n│   └── factories/       # Model factories\n├── resources/views/     # UI view classes\n├── routes/              # Route definitions\n└── main.dart            # Entry point\n```\n\n## Documentation\n\nFull docs at **[magic.fluttersdk.com](https://magic.fluttersdk.com)**.\n\n| Topic | |\n|-------|--|\n| [Installation](https://magic.fluttersdk.com/getting-started/installation) | Setup and requirements |\n| [Configuration](https://magic.fluttersdk.com/getting-started/configuration) | Environment and config files |\n| [Service Providers](https://magic.fluttersdk.com/getting-started/service-providers) | Provider lifecycle |\n| [Routing](https://magic.fluttersdk.com/basics/routing) | Routes and navigation |\n| [Controllers](https://magic.fluttersdk.com/basics/controllers) | Request handlers |\n| [Views](https://magic.fluttersdk.com/basics/views) | UI layer |\n| [HTTP Client](https://magic.fluttersdk.com/basics/http-client) | Network requests |\n| [Middleware](https://magic.fluttersdk.com/basics/middleware) | Request pipeline |\n| [Forms](https://magic.fluttersdk.com/basics/forms) | Form handling and validation |\n\n## AI Agent Integration\n\nUse Magic with AI coding assistants like Claude Code, Cursor, or GitHub Copilot. The **magic-framework** skill teaches your AI the correct patterns — Facades, Eloquent ORM, Service Providers, controllers, routing, and common anti-patterns — so it generates correct Magic code on the first try.\n\nSetup instructions and skill files: **[fluttersdk/ai](https://github.com/fluttersdk/ai)**\n\n## Contributing\n\n```bash\ngit clone https://github.com/fluttersdk/magic.git\ncd magic \u0026\u0026 flutter pub get\nflutter test \u0026\u0026 dart analyze\n```\n\n[Report a bug](https://github.com/fluttersdk/magic/issues/new?template=bug_report.yml) · [Request a feature](https://github.com/fluttersdk/magic/issues/new?template=feature_request.yml)\n\n## License\n\nMIT — see [LICENSE](LICENSE) for details.\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003csub\u003eBuilt with care by \u003ca href=\"https://github.com/fluttersdk\"\u003eFlutterSDK\u003c/a\u003e\u003c/sub\u003e\u003cbr/\u003e\n  \u003csub\u003eIf Magic saves you time, \u003ca href=\"https://github.com/fluttersdk/magic\"\u003egive it a star\u003c/a\u003e — it helps others discover it.\u003c/sub\u003e\n\u003c/p\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluttersdk%2Fmagic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffluttersdk%2Fmagic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluttersdk%2Fmagic/lists"}