supabase/supabase-flutter/supabase-flutter-idioms
- community
Checking that the SKILL.md file is still in the repository.
The current supabase_flutter v3 API for writing or reviewing Dart code that talks to Supabase: client setup, typed queries with table(), typed rpc, auth, realtime streams, error handling and logging. Use whenever code imports supabase_flutter, or the user asks to query, insert, subscribe, sign in or handle errors with Supabase. Prevents v2 patterns such as from() with maps, anonKey, and realtime callbacks.
Install
npx vskill@latest install supabase/supabase-flutter/supabase-flutter-idiomsSKILL.md
Writing supabase_flutter v3 code
Most published Supabase Dart examples are v2 code. v3 changed many of the APIs those examples use, so do not copy a pattern from memory without checking it against this file. To upgrade an existing v2 project, use the supabase-flutter-migrate-v3 skill instead.
Rules
- Query tables with
table()and the generated schema, never with
from() and Map<String, dynamic>, unless the table is missing from the generated file.
- Generate the schema with the Supabase CLI (2.122.0 or newer) and never edit
it by hand. Regenerate it after every database migration: supabase gen types --lang dart --local > lib/supabase_schema.g.dart. The supabase-typegen-generate skill, installed with the supabase_typegen dev dependency, covers the setup and the options.
- Pass
publishableKey.anonKeydoes not exist in v3. - Listen to realtime with streams. v3 has no
callback:parameters. - Catch the
SupabaseExceptionhierarchy, neverClientException,
TimeoutException or String.
- A typed
update()ordelete()does nothing until.where(…)or
.all() is called on it. The analyzer reports a missing one as an unused_result warning.
- Use one client,
Supabase.instance.client, for the whole app.
Client setup
Supabase.initialize persists the session with SharedPreferencesAsync and restores it before it returns. Pass FlutterAuthClientOptions(asyncStorage: …) to store it elsewhere, for example in secure storage.
Reading rows
The generated file has, per table, a row type (BooksRow), insert and update types (BooksInsert, BooksUpdate) and a class (Books) with the table definition and one constant per column and relation. A table in another schema carries the schema as a prefix, InventoryBooks.
Filters are methods on the column constants, combined with &, | and not(). Values must match the column type, and isNull() only exists on nullable columns. order() sorts ascending unless the ordering says .desc().
Read some columns only, or embed related rows, with selectOnly, and read the values back through the same constants:
Writing rows
- Several rows go through
insertAll()andupsertAll(). - A
nullargument toBooksInsertorBooksUpdateleaves the column out.
Write SQL NULL with the generated set…ToNull() methods.
- Writes resolve to
void. Add.select()to get the written rows back. upsert()takesonConflictas a list of columns,
onConflict: [Authors.name].
Calling database functions
Every function PostgREST exposes gets a typed method on rpc:
supabase.rpc('fn', params: {...}) is the untyped fallback for functions the generator gives no method, which it explains in a comment in the generated file.
Auth
Sign-in methods that always produce a session return the Session:
signUp() and verifyOTP() still return an AuthResponse, since they can complete without a session.
AuthState is sealed, with one subtype per event. Every new listener first receives AuthInitialSession with the current session or null. A failed token refresh, for example while offline, is an error of the stream, so every listener passes onError:
user.userMetadata is never null, and user.appMetadata is an AppMetadata with typed provider and providers.
Realtime
Keep a list of rows up to date with stream():
The supabase-flutter-realtime skill covers broadcast, presence and channel status in more depth.
React to individual changes with onTableChanges. Create the stream before subscribe(), and remove the channel when done:
Broadcast and connection status are streams too:
The table must be added to the supabase_realtime publication in the database, or no changes arrive.
Create a stream once in State, never inside build(), or every rebuild resubscribes:
Errors
Every exception the SDK throws for a failed request extends SupabaseException. SupabaseApiException means the server answered with an error, and SupabaseTransportException means no response arrived, including a timeout:
Each service also has its own base, such as PostgrestException, AuthException or StorageException, to catch the errors of one service only. AuthApiException and PostgrestApiException carry the server's errorCode.
Logging
The SDK never prints. It logs through package:logging under the supabase logger, so listen to it to see the records:
Tests
Use the supabase_test package as a dev dependency instead of mocking the HTTP client by hand. Its MockSupabaseHttpClient, testSupabaseClient and signInTestUser answer requests and put a client in a signed-in state. The supabase-test-testing skill, installed with the supabase_test dev dependency, covers stubbing, assertions, auth and realtime in tests.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingpackages/supabase_flutter/skills/supabase-flutter-idioms/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/supabase/supabase-flutter/supabase-flutter-idioms)