I've deployed this Deno Fresh + TypeScript + Supabase stack to production three times. Here's what really happens when you ship it, not the marketing bullshit.
Fresh Is Fast Until It Isn't
Fresh's islands thing ships zero JavaScript by default so your Lighthouse scores look incredible. But the moment you need real interactivity, you're writing islands and suddenly dealing with hydration mismatches that make you want to throw your laptop.
I learned this the hard way when our dashboard went from 98 Lighthouse to 72 after adding client-side charts. The island hydration kicked in and suddenly we had layout shifts everywhere. Fresh is great for content-heavy sites but struggles with app-like interfaces.
Supabase Edge Functions on Deno Deploy do hit sub-100ms cold starts most of the time. But "most of the time" means you'll get random 2-second spikes that will make your monitoring alert. The edge works great until it doesn't.
TypeScript Everywhere (Including the Bugs)
The type safety actually works, which is rare. Supabase's type generation from PostgreSQL schemas means when you add a column, TypeScript immediately yells at you everywhere it's missing.
Here's the shit they don't tell you: the generated types break constantly. Change a table name? The types don't update until you restart the dev server twice and sacrifice a goat. Add a foreign key? The types are wrong for complex joins half the time and you get lovely errors like Property 'user_profiles' does not exist on type 'Database'
even though it clearly fucking does.
I've wasted entire afternoons debugging TypeScript errors that were just stale generated types. The type generation breaks in weird ways too - had it generate a User type with 'undefined' for every property after I renamed a table. Spent an hour thinking my query was broken when it was just the types lying to me.
The Deno TypeScript support is solid but I've hit weird import resolution bugs that force you to restart the LSP. Always pin Deno versions in production - auto-updates will bite you when you least expect it.
Security Is Good When You Remember to Use It
Deno's permission model is actually useful. Running with --allow-net=api.stripe.com,supabase.io
means your code can't accidentally phone home to random APIs. This caught a compromised dependency that was trying to send data to a Chinese server.
Supabase RLS is where most people fuck up. The policies look simple but get complex fast. I spent two days debugging why users could see each other's data only to find a missing auth.uid() = user_id
check in a join table policy.
The Development Experience Reality Check
The file-based routing in Fresh is nice until you have 50 routes and can't find anything. The automatic route generation breaks when you have dynamic segments with the same name in different directories.
Hot reload works great... except when it doesn't. Database schema changes should trigger type regeneration but sometimes the watcher gets stuck. You end up restarting deno task start
more than you'd like.
The Supabase CLI local development is solid but the database migrations can be finicky. I've had supabase db diff
miss foreign key changes and then deployment fails because the migration is incomplete.
When It All Works Together
Despite all this crap, we still shipped in 6 weeks. No webpack config, no babel setup, no Docker compose nightmare for local dev. Edge Functions deploy in seconds, database migrations usually work, and TypeScript catches most of the stupid mistakes.
Fresh forces you to think about what actually needs JavaScript, which makes your app faster. Supabase handles auth and database without the usual PostgreSQL setup hell. When everything works, it's actually pleasant to use.
Just don't expect perfection. Pin your versions, write tests for your RLS policies, and keep supabase db reset
handy for when the local environment gets wedged.