The official C# client for Supabase. This is a monorepo: the top-level
Supabase client and every service package it builds on live here, under packages/.
Use the Supabase meta-package for the full client, or reference an individual service package
(Auth, Postgrest, Storage, Realtime, Functions) on its own.
Every package targets .NET Standard 2.1, so it runs on .NET Core 3.0+ / .NET 5+, recent MAUI, Xamarin, and Unity. See the wiki for platform-specific guides (Unity, desktop/mobile, server-side).
dotnet add package Supabaseusing Supabase;
var url = Environment.GetEnvironmentVariable("SUPABASE_URL");
var key = Environment.GetEnvironmentVariable("SUPABASE_KEY");
var options = new SupabaseOptions
{
AutoRefreshToken = true,
AutoConnectRealtime = true
};
var supabase = new Client(url, key, options);
await supabase.InitializeAsync();
// Auth
await supabase.Auth.SignIn("user@example.com", "password");
// Database
var movies = await supabase.From<Movie>().Get();
// Storage
await supabase.Storage.From("avatars").Download("me.png", null);Each service is reached from the initialized client: supabase.Auth, supabase.From<T>() /
supabase.Rpc(...), supabase.Storage, supabase.Realtime, and supabase.Functions. For using a
single service on its own, see that package's README.
A note on keys: some APIs (user administration, bypassing RLS, etc.) require the
service_keyrather than the public/anon key. Never expose aservice_keyin client-side code, and use a separate client instance for service and user contexts.
The clients emit traces and metrics through System.Diagnostics, so you can wire them into
OpenTelemetry (or any ActivityListener / MeterListener) without taking a dependency on the
OpenTelemetry packages. Emission is zero-cost while nothing is listening, so it is always on and
stays silent until you subscribe.
Register every instrumented source at once with SupabaseDiagnostics.SourceNames — each client
shares one name between its ActivitySource and its Meter, so the same list works for tracing and
metrics:
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
using Supabase;
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddSource(SupabaseDiagnostics.SourceNames.ToArray())
.AddOtlpExporter())
.WithMetrics(metrics => metrics
.AddMeter(SupabaseDiagnostics.SourceNames.ToArray())
.AddOtlpExporter());This covers the Auth, Postgrest, Functions, and Storage clients (Realtime is not yet instrumented). URLs are recorded without their query string, and no token, credential, or payload is placed in a tag. Each package's README documents the specific spans and metrics it produces.
packages/
Supabase/ The unified client (NuGet: Supabase)
Gotrue/ Auth (NuGet: Supabase.Gotrue)
Postgrest/ Database (NuGet: Supabase.Postgrest)
Storage/ Storage (NuGet: Supabase.Storage)
Realtime/ Realtime (NuGet: Supabase.Realtime)
Functions/ Functions (NuGet: Supabase.Functions)
Core/ Shared (NuGet: Supabase.Core)
Each packages/<Name>/ holds the library project and its test project. Package metadata common to
every project (license, authors, repository) lives in Directory.Build.props;
dependency versions are managed centrally in Directory.Packages.props.
The SDK builds with the .NET SDK version pinned in global.json.
dotnet restore
dotnet build Supabase.sln --configuration Release
dotnet test Supabase.sln --configuration ReleaseSome test suites are end-to-end and need a local Supabase stack via the
Supabase CLI (supabase start, which requires Docker). The
Realtime suite additionally expects realtime-dev.localhost to resolve locally — add a hosts entry:
127.0.0.1 realtime-dev.localhost
Releases are automated with release-please. Commits
follow Conventional Commits; the changelog is generated in
CHANGELOG.md. For breaking changes and how to adapt to them across major
versions, see the migration guides.
Contributions are welcome — please open an issue to discuss substantial changes, then submit a PR.
