Hybrid Architecture: The Best of Both Worlds with Supabase and Spring Boot
Published on 14 January 2026
Instead of choosing between the simplicity of Supabase and the power of Spring Boot, why not combine the two? Discover a hybrid architecture that leverages the best of each technology.
- The False Dilemma of Modern Architecture
- Architectural Vision
- Design Principles
- Orchestration of the Flows
- Decision Matrix
- Examples of Architecture by Project Type
- Progressive Migration Strategy
- Costs and Operational Considerations
- Conclusion: Perfect Balance
- To Go Further
- Evolution perspectives
- Architectural Testimonials
- Synthesis: A Modern Architectural Paradigm
- Final conclusion
The False Dilemma of Modern Architecture
When building a modern application with a static frontend, we often find ourselves facing a binary choice:
-
To bet everything on a Backend-as-a-Service solution(Supabase, Firebase) - simple but limited
-
Build a complete backend(Spring Boot, Node.js) - powerful but complex
This choice is a false dilemma. The hybrid architecture proposes a third way: using each technology where it excels
Architectural Vision
Traditional Architecture: Monolithic
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Traditional Architecture" {
actor Utilisateur as user
component "Frontend" as frontend #LightBlue
component "Monolithic Backend" as backend #LightCoral {
[Authentification]
[CRUD]
[Logique Métier]
[Jobs]
[APIs Tierces]
}
database "Database" as db #LightGray
user --> frontend
frontend --> backend : All requests
backend --> db
}
note right of backend
Everything goes through the backend
even simple operations
⚠️ Single point of congestion
⚠️ Complexity from the start
⚠️ Tight coupling
end note
@enduml
In this approach, even the simplest operations (reading an article, creating a comment) must go through your backend. You pay the cost of complexity from day one.
The BaaS Architecture: Every Delegate
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Architecture BaaS Pure" {
actor Utilisateur as user
component "Frontend" as frontend #LightBlue
cloud "Supabase / Firebase" as baas #LightGreen {
[Auth]
[Database]
[Storage]
[Edge Functions]
}
user --> frontend
frontend --> baas : All operations
}
note right of baas
Rapid development
No server to manage
⚠️ Limited for complex logic
⚠️ Vendor lock-in
⚠️ Constrained Edge Functions
end note
@enduml
On the other hand, delegating everything to a BaaS is attractive at first but quickly shows its limits as soon as business logic becomes complex.
Hybrid Architecture: Separation of Concerns
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
actor Utilisateur as user #LightBlue
package "Frontend Layer" {
component "Static Site JBake" as frontend #SkyBlue
}
package "Simple Layer (Supabase)" #LightGreen {
component "Authentication" as auth
component "Basic CRUD" as crud
component "File Storage" as storage
component "Real-Time" as realtime
}
package "Business Layer (Spring Boot)" #Coral {
component "Complex Logic" as logic
component "Orchestration" as orchestration
component "Scheduled Jobs" as jobs
component "Integrations" as integrations
}
database "Shared PostgreSQL" as db #LightGray
user --> frontend
frontend --> auth : OAuth2, JWT
frontend --> crud : Articles, Profiles
frontend --> storage : Images, Files
frontend --> realtime : Notifications
frontend --> logic : Calculations, Reports
frontend --> orchestration : Workflows
logic --> integrations : Stripe, APIs
orchestration --> db
jobs --> db
crud --> db
auth --> db
note bottom of db
**A single source of truth**
Shared between Supabase and Spring Boot
end note
note right of auth
**Free up to 50k users**
Configuration in a few clicks
OAuth2 multi-providers
end note
note right of logic
**Enabled only if necessary**
Kotlin + Coroutines
Complex transactions
end note
@enduml
The hybrid architecture clearly separates responsibilities according to the complexity and nature of the operations.
Design Principles
Principle 1: Start Simple, Evolve Intelligently
@startuml
skinparam backgroundColor #FEFEFE
rectangle "**Phase 1: MVP**" #LightGreen {
component "JBake + Supabase" as mvp
note right
✓ Development in days
✓ Cost: €0
✓ Concept validation
end note
}
rectangle "**Phase 2: Growth**" #LightYellow {
component "JBake + Supabase\n+ Spring Boot (optional)" as growth
note right
✓ Business logic emerges
✓ First scheduled jobs
✓ Third-party integrations
end note
}
rectangle "**Phase 3: Scale**" #LightCoral {
component "Complete Architecture" as scale
note right
✓ Complex orchestration
✓ Optimized performance
✓ Distributed cache
end note
}
mvp -down-> growth : When complexity\njustifies it
growth -down-> scale : Optimization\ncontinuous
@enduml
Do not build Spring Boot if you don’t need it.Start with Supabase, add Spring Boot when complexity justifies it.
Principle 2: Separation by Nature of Operation
@startmindmap skinparam backgroundColor #FEFEFE * Operations\nApplicative left side ** Simple Operations\n(Supabase) ***_ CRUD Standard ****_ Reading ****_ Creation ****_ Update ****_ Deletion ***_ Authentication ****_ Login/Logout ****_ OAuth2 ****_ Session management ***_ Storage ****_ Upload files ****_ CDN automatic ***_ Real Time ****_ WebSocket ****_ Notifications right side ** Complex Operations\n(Spring Boot) ***_ Business Logic ****_ Complex calculations ****_ Business rules ****_ Advanced validations ***_ Orchestration ****_ Multi-services ****_ Distributed transactions ****_ Saga patterns ***_ Scheduled Tasks ****_ Periodic reports ****_ Synchronizations ****_ Cleanings ***_ Integrations ****_ Payments (Stripe) ****_ APIs third parties ****_ Services ML/AI @endmindmap
Principle 3: A Single Source of Truth
@startuml
skinparam backgroundColor #FEFEFE
database "PostgreSQL" as db #LightGray {
package "Schema: auth (Supabase)" #LightGreen {
[users]
[sessions]
[identities]
}
package "Schema: public (Shared)" #SkyBlue {
[articles]
[comments]
[profiles]
}
package "Schema: business (Spring Boot)" #Coral {
[orders]
[payments]
[reports]
}
}
component "Supabase" as supabase #LightGreen
component "Spring Boot" as spring #Coral
supabase -down-> users : Manage
supabase -down-> sessions : Manage
supabase -down-> articles : Access
supabase -down-> comments : Access
supabase -down-> profiles : Accesses
spring -down-> articles : Access
spring -down-> profiles : Access
spring -down-> orders : Manage
spring -down-> payments : Manage
spring -down-> reports : Manage
note right of db
**Advantages:**
• No complex synchronization
• JOINs possible between tables
• Guaranteed consistency
• Unified migrations
end note
@enduml
By sharing the same PostgreSQL instance, Supabase and Spring Boot work on the same data without complex synchronization.
Orchestration of the Flows
Flow 1: Centralized Authentication
@startuml skinparam backgroundColor #FEFEFE autonumber actor "User" as user participant "JBake" as jbake participant "Supabase Auth" as auth participant "Spring Boot" as spring database "PostgreSQL" as db == Authentification == user -> jbake : Clique "Log in" jbake -> auth : Redirect OAuth2 (Google/GitHub) auth -> user : Consent screen user -> auth : Authorize auth -> auth : Generate JWT auth -> jbake : Returns `JWT` + Refresh Token jbake -> jbake : Store tokens (`sessionStorage`) == Accès aux Ressources == group Opération Simple (CRUD) user -> jbake : Create an article jbake -> db : POST with JWT note right: Supabase Row Level Security\nchecks JWT automatically db -> jbake : Article created end group Opération Complexe (Métier) user -> jbake : Generate a report jbake -> spring : POST /api/reports\nwith JWT spring -> spring : Validate JWT Supabase spring -> spring : Extracted claims (`user_id`, roles) spring -> db : Complex queries spring -> jbake : Report generated end note over auth, spring **The JWT is universal** Validated by Supabase AND Spring Boot No double authentication end note @enduml
Key point: A single authentication process, a single JWT, usable everywhere.
Flux 2: Orchestration of a complex business process
@startuml skinparam backgroundColor #FEFEFE autonumber actor "Client" as user participant "JBake" as jbake participant "Spring Boot" as spring participant "Supabase DB" as supadb participant "Stripe API" as stripe participant "Inventory Service" as inventory participant "Email Service" as email database "PostgreSQL" as db user -> jbake : Place order jbake -> spring : POST /api/orders/create == Orchestration Spring Boot == spring -> db : BEGIN TRANSACTION par Vérifications Parallèles spring -> inventory : Check stock inventory -> spring : Stock OK else spring -> db : Check customer profile db -> spring : Verified client end spring -> stripe : Create Payment Intent stripe -> spring : Intent created (ID: pi_xxx) spring -> db : Create Order (status: PENDING) db -> spring : Order created spring -> stripe : Confirm payment stripe -> spring : Payment confirmed spring -> db : Update Order (status: PAID) spring -> inventory : Decrement stock spring -> db : COMMIT TRANSACTION par Notifications Asynchrones spring -> email : Email confirmation else spring -> supadb : Insert notification note right: Real-time notification\nvia Supabase Realtime end spring -> jbake : Order confirmed jbake -> user : Display confirmation note over spring **Spring Boot responsibilities:** • Transaction ACID • Multi-service orchestration • Automatic rollback on error • Edge case handling end note @enduml
What Spring Boot bringsReliable orchestration of complex processes involving multiple systems with transactional guarantee.
Flow 3 : Scheduled Jobs and Synchronizations
@startuml skinparam backgroundColor #FEFEFE participant "Scheduler\n(Spring Boot)" as scheduler participant "Report Service" as report participant "PostgreSQL" as db participant "External API" as api participant "Email Service" as email participant "Supabase Storage" as storage == Job Quotidien : 2:00 == activate scheduler scheduler -> report : Triggers report generation activate report report -> db : Retrieve data\nfrom the last 24h db -> report : Dataset report -> report : Calculations & Aggregations report -> report : Generation PDF report -> storage : Upload PDF storage -> report : URL publique report -> email : Send to the admins\nwith link PDF deactivate report == Job Hebdomadaire : Sunday 3h00 == scheduler -> report : External synchronization activate report report -> api : Fetch external data api -> report : New data report -> db : Tables update report -> db : Obsolete data cleanup deactivate report == Job Mensuel : 1st of the month == scheduler -> report : Billing activate report report -> db : Active client list report -> report : Amount calculation report -> api : Invoice generation (Stripe) report -> email : Sending invoices deactivate report deactivate scheduler note right of scheduler **Impossible with Supabase alone** Edge Functions not suitable for long-running and recurring jobs end note @enduml
What Spring Boot brings: Reliable scheduled jobs with state management, automatic retry, and guaranteed execution.
Decision Matrix
When to Use Supabase?
@startuml
skinparam backgroundColor #FEFEFE
start
:Nouvelle fonctionnalité à implémenter;
if (CRUD simple ?) then (oui)
:✅ **Supabase**;
stop
else (non)
if (Authentification ?) then (oui)
:✅ **Supabase Auth**;
stop
else (non)
if (Upload fichiers ?) then (oui)
:✅ **Supabase Storage**;
stop
else (non)
if (Temps réel ?) then (oui)
:✅ **Supabase Realtime**;
stop
else (non)
if (Row Level Security\nsuffisante ?) then (oui)
:✅ **Supabase + Policies**;
stop
else (non)
:⚠️ **Considérer Spring Boot**;
#Coral:Passer à l'arbre\nde décision Spring Boot;
stop
endif
endif
endif
endif
endif
@enduml
When to Use Spring Boot?
@startuml
skinparam backgroundColor #FEFEFE
start
:Nouvelle fonctionnalité complexe;
if (Orchestration\nmulti-services ?) then (oui)
:✅ **Spring Boot**;
stop
else (non)
if (Transaction ACID\ncritique ?) then (oui)
:✅ **Spring Boot**;
stop
else (non)
if (Job planifié ?) then (oui)
:✅ **Spring Boot Scheduler**;
stop
else (non)
if (Intégration API\ntierce complexe ?) then (oui)
:✅ **Spring Boot**;
stop
else (non)
if (Calculs lourds\n> 10 secondes ?) then (oui)
:✅ **Spring Boot**;
stop
else (non)
if (Cache distribué\nnécessaire ?) then (oui)
:✅ **Spring Boot + Redis**;
stop
else (non)
:⚠️ **Probablement Supabase**;
#LightGreen:Revenir à l'arbre\nde décision Supabase;
stop
endif
endif
endif
endif
endif
endif
@enduml
Examples of Architecture by Project Type
Blog / Portfolio
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Personal Blog - 95% Supabase" {
component "JBake" as jbake #SkyBlue
package "Supabase (Free)" #LightGreen {
[Auth: OAuth2 Google]
[Articles (CRUD)]
[Commentaires]
[Images (Storage)]
[Notifications Realtime]
}
package "Spring Boot (Optional)" #LightCoral {
[Newsletter Mensuelle]
note bottom: Scheduled job only
}
database "PostgreSQL" as db
jbake --> [Auth: OAuth2 Google]
jbake --> [Articles (CRUD)]
jbake --> [Commentaires]
jbake --> [Images (Storage)]
jbake --> [Notifications Realtime]
[Articles (CRUD)] --> db
[Commentaires] --> db
[Newsletter Mensuelle] --> db
}
note bottom of "Spring Boot (Optional)"
**Spring Boot not mandatory**
Newsletter can be managed
by a third-party service (Mailchimp)
end note
@enduml
Verdict: 100% Supabase is more than enough.
SaaS application
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "Application SaaS - Hybrid Architecture" {
component "JBake / React" as frontend #SkyBlue
package "Supabase" #LightGreen {
[Auth Multi-tenant]
[Profils Utilisateurs]
[Données Simples]
[Storage Documents]
}
package "Spring Boot" #Coral {
[Facturation (Stripe)]
[Analytics Avancées]
[Rapports Mensuels]
[Quotas & Limites]
[Webhooks Stripe]
}
cloud "External Services" {
[Stripe API]
[SendGrid Email]
}
database "Shared PostgreSQL" as db
frontend --> [Auth Multi-tenant]
frontend --> [Profils Utilisateurs]
frontend --> [Données Simples]
frontend --> [Facturation (Stripe)]
frontend --> [Analytics Avancées]
[Auth Multi-tenant] --> db
[Profils Utilisateurs] --> db
[Données Simples] --> db
[Facturation (Stripe)] --> db
[Facturation (Stripe)] --> [Stripe API]
[Analytics Avancées] --> db
[Rapports Mensuels] --> db
[Rapports Mensuels] --> [SendGrid Email]
[Webhooks Stripe] ..> [Stripe API] : Écoute
}
note right of "Spring Boot"
**Required for:**
• Subscription management
• Recurring billing
• Dynamic quotas
• Complex analytics
• Reliable webhooks
end note
@enduml
Verdict: Hybrid architecture needed. Supabase for the essentials, Spring Boot for the critical part (payments, invoicing).
E-commerce
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
package "E-commerce - 70% Spring Boot" {
component "Storefront (JBake/React)" as frontend #SkyBlue
package "Supabase" #LightGreen {
[Auth Clients]
[Catalogue Produits\n(lecture seule)]
[Images Produits]
}
package "Spring Boot (Core Business)" #Coral {
[Gestion Commandes]
[Paiements Stripe]
[Gestion Stock]
[Calcul Frais Port]
[Génération Factures]
[Synchronisation ERP]
[Emails Transactionnels]
}
cloud "Integrations" {
[Stripe]
[Transporteur API]
[ERP Externe]
}
database "PostgreSQL" as db
frontend --> [Auth Clients]
frontend --> [Catalogue Produits\n(lecture seule)]
frontend --> [Gestion Commandes]
[Auth Clients] --> db
[Catalogue Produits\n(lecture seule)] --> db
[Gestion Commandes] --> db
[Paiements Stripe] --> [Stripe]
[Gestion Stock] --> db
[Calcul Frais Port] --> [Transporteur API]
[Génération Factures] --> db
[Synchronisation ERP] --> [ERP Externe]
[Synchronisation ERP] --> db
}
note right of "Spring Boot (Core Business)"
**Spring Boot essential:**
• Critical transactions
• Complex orchestration
• Multiple integrations
• Legal compliance
• Synchronization jobs
end note
@enduml
VerdictSpring Boot indispensable. Supabase for auth and catalog only.
Progressive Migration Strategy
@startuml skinparam backgroundColor #FEFEFE |Semaine 1-2| start :Create project Supabase; :Configure Auth (Google, GitHub); :Define initial PostgreSQL schema; :Implement basic CRUD on JBake; :Deploy MVP on GitHub Pages; note right **Deliverable:** Working application **Cost:** €0 **Time:** 1–2 weeks end note |Semaine 3-4| :Observe actual usage; :Identify limitations; |Décision| if (Logique complexe\némerge ?) then (non) |Supabase| :Continue with Supabase only; :Add Edge Functions if needed; stop else (oui) |Spring Boot| :Create Spring Boot project; :Configure validation JWT Supabase; :Migrate complex logic to Spring Boot; note right **Selective migration** Only what is complex end note endif |Semaines suivantes| :Deploy Spring Boot (Cloud Run, EC2); :Connect to PostgreSQL Supabase; :Implement first scheduled jobs; :Integrate APIs third-party; stop note right Final hybrid architecture Supabase + Spring Boot in perfect harmony end note @enduml
Costs and Operational Considerations
Cost Structure
@startuml
skinparam backgroundColor #FEFEFE
package "Estimated Monthly Costs" {
rectangle "Phase MVP\n(0-1000 users)" #LightGreen {
[JBake (GitHub Pages): 0€]
[Supabase: 0€]
[Spring Boot: N/A]
note bottom: **Total: 0€/mois**
}
rectangle "Growth Phase\n(1k-10k users)" #LightYellow {
[JBake (GitHub Pages): 0€]
[Supabase: 0€]
[Spring Boot (Cloud Run): 20-50€]
[PostgreSQL (si séparé): 0-30€]
note bottom: **Total: 20-80€/mois**
}
rectangle "Scale Phase\n(10k-100k users)" #LightCoral {
[JBake (Netlify Pro): 19€]
[Supabase Pro: 25€]
[Spring Boot (instances multiples): 100-300€]
[Redis Cache: 20-50€]
[Monitoring: 20€]
note bottom: **Total: 184-414€/mois**
}
}
note right of "Scale Phase\n(10k-100k users)"
At this stage, the revenues largely justify the costs
end note
@enduml
Operational Responsibilities
@startuml
skinparam backgroundColor #FEFEFE
package "Who Manages What?" {
rectangle "Managed by Supabase (0 effort)" #LightGreen {
[Authentification]
[Base de données]
[Backups automatiques]
[Scaling automatique]
[Monitoring DB]
[Sécurité DB]
}
rectangle "Managed by GitHub (0 effort)" #SkyBlue {
[Hébergement site statique]
[HTTPS/SSL]
[CDN global]
[Déploiement automatique]
}
rectangle "To Manage (Spring Boot)" #LightCoral {
[Déploiement application]
[Monitoring APM]
[Logs centralisés]
[Scaling horizontal]
[Mises à jour sécurité]
}
}
note bottom of "To Manage (Spring Boot)"
**Can be minimized with:**
• Cloud Run (serverless)
• Kubernetes (if necessary)
• Managed services (RDS, etc.)
end note
@enduml
Conclusion: Perfect Balance
The Supabase + Spring Boot hybrid architecture is not a compromise, it’s asynergy.
The Principles to Remember
@startmindmap skinparam backgroundColor #FEFEFE * Architecture\nHybrid ** Start Simple ***_ MVP with Supabase ***_ 0€ initial cost ***_ Quick validation ** Evolve intelligently ***_ Add Spring Boot\nif necessary ***_ Gradual migration ***_ No total redesign ** Exploit the forces ***_ Supabase: Simplicity ***_ Spring Boot: Power ***_ PostgreSQL: Single source ** Minimize Complexity ***_ No synchronization ***_ No duplication ***Clear architecture ** Optimize Costs ***_ Free at the start ***_ Progressive scaling ***_ ROI evident @endmindmap
When to Choose This Architecture?
✅ This architecture is ideal if:
-
You want to start quickly (MVP in days, not months)
-
You anticipate a growth in business complexity
-
You want to minimize the initial costs
-
You love PostgreSQL and want a single source of truth
-
You appreciate Kotlin and Coroutines for the business code
-
You want to avoid total vendor lock-in
�❌ This architecture is NOT suitable if :
-
Your project is simple and will remain (personal blog → 100% Supabase suffices)
-
You already have an established backend stack that you master
-
You prefer a traditional monolith
-
You need .NET, Python, or another backend language
Final overview
@startuml
skinparam backgroundColor #FEFEFE
package "Complete Hybrid Architecture" {
actor "Users" as users
rectangle "Frontend (Static)" #SkyBlue {
[JBake / GitHub Pages]
note right: Free, CDN global
}
rectangle "Simple Backend (Supabase)" #LightGreen {
[Auth OAuth2]
[CRUD APIs]
[Storage]
[Realtime]
note right
Free up to 50k users
Zero server configuration
end note
}
rectangle "Business Backend (Spring Boot)" #Coral {
[Orchestration]
[Jobs Planifiés]
[Intégrations]
[Transactions]
note right
Enabled only if necessary
end note
}
database "PostgreSQL\nSource Single Source of Truth" as db #LightGray
users --> [JBake / GitHub Pages]
[JBake / GitHub Pages] --> [Auth OAuth2]
[JBake / GitHub Pages] --> [CRUD APIs]
[JBake / GitHub Pages] --> [Storage]
[JBake / GitHub Pages] --> [Realtime]
[JBake / GitHub Pages] --> [Orchestration]
[Auth OAuth2] --> db
[CRUD APIs] --> db
[Orchestration] --> db
[Jobs Planifiés] --> db
[Intégrations] --> db
}
note bottom of db
**One database, two consumers**
• Supabase for the simple
• Spring Boot for the complex
• No synchronization required
end note
@enduml
The Best of Both Worlds
This architecture gives you:
🚀 The Velocity of Supabase
-
Startup in hours, not weeks
-
OAuth2 authentication in a few clicks
-
Automatically generated REST APIs
-
Zero server configuration
�💪 The Power of Spring Boot
-
Kotlin and Coroutines for elegant asynchronous code
-
Orchestration of complex business processes
-
Reliable scheduled jobs
-
Guaranteed ACID transactions
-
Complete Spring ecosystem
💰 The Progressive Economy
-
0€ to start and validate
-
Costs that follow growth
-
No premature over‑engineering
🎯 Architectural Flexibility
-
Progressive migration without rewrite
-
Adding Spring Boot only if necessary
-
No total vendor lock-in
-
Evolvable architecture
To Go Further
Technical Resources
Supabase Documentation :
Spring Boot documentation:
Supplementary Articles :
-
Securing APIs with JWT
-
PostgreSQL performance optimization
-
Progressive migration patterns
-
Error handling in distributed architecture
Real Use Cases
This hybrid architecture is successfully used in:
-
SaaS B2B: Supabase authentication, Spring Boot billing
-
Marketplaces: Catalog Supabase, transactions Spring Boot
-
Content PlatformsSupabase articles, Spring Boot analytics
-
Internal tools: CRUD Supabase, workflows Spring Boot
Startup Checklist
Phase 1 - Foundations (Week 1)
-
Create Supabase account - [ ] Configure PostgreSQL project - [ ] Enable Auth (Google, GitHub) - [ ] Define initial schema - [ ] Configure Row Level Security - [ ] Test APIs from JBake
Phase 2 - MVP (Week 2-3)
-
Implement main pages - [ ] Integrate OAuth2 authentication - [ ] Create CRUD forms - [ ] Configure Storage for files - [ ] Deploy on GitHub Pages - [ ] Test under real conditions
Phase 3 - Evolution (As needed)
-
Identify complex logic needs - [ ] Create Spring Boot project if needed - [ ] Configure Supabase JWT validation - [ ] Connect to Supabase PostgreSQL - [ ] Migrate complex features - [ ] Implement scheduled jobs - [ ] Deploy Spring Boot (Cloud Run, etc.)
Anti-Patterns to Avoid
�❌ Do not:
-
Duplicate the data between Supabase and Spring Boot
-
Create two separate PostgreSQL databases
-
Code the authentication yourself
-
Use Spring Boot for simple CRUD
-
Over-architecting from the outset
-
Ignore Supabase Row Level Security
Better to do:
-
Share a single PostgreSQL database
-
Let Supabase handle authentication
-
Use Spring Boot only for the complexity
-
Start simple, evolve gradually
-
Leverage the strengths of each technology
-
Secure with RLS at database level
Evolution perspectives
Adding New Capabilities
@startuml
skinparam backgroundColor #FEFEFE
rectangle "Current Architecture" #SkyBlue {
[JBake]
[Supabase]
[Spring Boot]
}
rectangle "Possible Developments" #LightYellow {
package "Performance" {
[Redis Cache]
[CDN pour Assets]
[PostgreSQL Replicas]
}
package "Monitoring" {
[Grafana]
[Prometheus]
[Sentry]
}
package "CI/CD" {
[GitHub Actions]
[Tests Automatisés]
[Déploiement Continu]
}
package "Features" {
[Search (ElasticSearch)]
[Queue (RabbitMQ)]
[Event Sourcing]
}
}
[Spring Boot] .down.> [Redis Cache] : Peut ajouter
[Spring Boot] .down.> [Queue (RabbitMQ)] : Peut ajouter
[Spring Boot] .down.> [Search (ElasticSearch)] : Peut ajouter
[Supabase] .down.> [PostgreSQL Replicas] : Peut ajouter
note bottom
**Extensible architecture**
Each addition is independent
No global redesign necessary
end note
@enduml
Scaling Horizontal
As your application grows, the hybrid architecture scales naturally:
Supabase:
-
Automatically scale up to millions of operations
-
Read replicas for read performance
-
Point-in-time recovery for security
Spring Boot :
-
Multiple instances behind load balancer
-
Stateless design facilitates horizontal scaling
-
Kubernetes for orchestration if needed
PostgreSQL :
-
Partitioning for large tables
-
Connection pooling (PgBouncer)
-
Sharding if really necessary (rare)
Architectural Testimonials
Startup SaaS (50k users)
_ We started 100% Supabase. At 5k users, we added Spring Boot only for Stripe billing and monthly reports. One year later, 80% of our operations still go through Supabase. Spring Boot handles only the critical part. This separation allowed us to scale without a redesign. _
E-learning platform (10k users)
_ Supabase’s OAuth2 authentication saved us three weeks of development. The auto-generated APIs manage our entire course catalog. Spring Boot is used only for PDF certificates and progress emails. Simple, maintainable, scalable architecture. _
Marketplace B2B (3k users)
_ Spring Boot handles transactions between buyers and sellers (critical). Supabase handles everything else: profiles, real-time messaging, documents. The fact that they share the same PostgreSQL database avoids any complex synchronization for us. It is the best architectural choice we have made. _
Synthesis: A Modern Architectural Paradigm
The Supabase + Spring Boot hybrid architecture represents a new paradigm:the architectural specialization.
@startuml
skinparam backgroundColor #FEFEFE
rectangle "Old Paradigm" #LightCoral {
card "Everything in the Backend" {
[Auth]
[CRUD]
[Logique Métier]
[Jobs]
[Storage]
[Realtime]
}
note bottom
Maximum complexity
from day 1
end note
}
rectangle "New Paradigm" #LightGreen {
card "Supabase\n(Commodity)" {
[Auth]
[CRUD Simple]
[Storage]
[Realtime]
}
card "Spring Boot\n(Differentiation)" {
[Logique Métier]
[Jobs]
[Intégrations]
}
note bottom
Progressive complexity added only if necessary
end note
}
[Ancien Paradigme] -right-> [Nouveau Paradigme] : Évolution
@enduml
The fundamental principle:Don’t build what already exists as a service. Focus on what differentiates your application.
The 80/20 Rule
In most applications:
-
80% of operationsare standard CRUD → Supabase
-
20% of operationsrequire business logic → Spring Boot
This natural rule justifies the hybrid architecture.
@startuml
skinparam backgroundColor #FEFEFE
package "Operations Distribution" {
rectangle "80% - Standard Operations" #LightGreen {
[Lecture de données]
[Création d'entités]
[Mise à jour simple]
[Suppression]
[Upload fichiers]
[Authentification]
note bottom: **Managed by Supabase**
}
rectangle "20% - Business Logic" #Coral {
[Calculs complexes]
[Workflows multi-étapes]
[Transactions critiques]
[Intégrations tierces]
[Jobs planifiés]
note bottom: **Managed by Spring Boot**
}
}
note right
**Optimal focus:**
Your development time
concentrated on the 20% that
set your product apart
end note
@enduml
Final conclusion
Hybrid architecture is not a technical compromise, it’s anstrategic decision.
It allows you to:
-
�✅ Start quickly with a functional MVP
-
�✅ Validate your market without heavy investment
-
�✅ Gradually evolve when complexity requires it
-
�✅ Master your costs at each step
-
✅ Leverage the best of each technology
-
✅ Avoid premature over-engineering
-
Maintain flexibility for the future
It represents:
-
🎯Pragmatism: Every technology where she excels
-
�🚀Velocityminimal time-to-market
-
�💰Economy: Costs aligned with value
-
�🔮Scalability: Architecture that grows with you
-
�🛡️RobustnessProven and reliable services
Your Next Step
If this architecture speaks to you, here’s where to start:
-
Create a Supabase account(free)
-
Define your minimal data schema
-
Configure OAuth2 authentication
-
Create your first JBake page that consumes the API
-
Deploy to GitHub Pages
You will have a functional MVP ina few days.
Spring Boot will come naturally when you need it. Not before.
Hybrid architecture is the art of building exactly what is needed, when it is needed.
Good development! 🚀
Share this article if you think it can help other developers make the right architectural choices.