How to Build a Supabase CRUD App with Visual Basic & Python — No Backend Needed
Step-by-step tutorial to build a full CRUD application with Supabase PostgreSQL using WebVB Studio. Connect, read, create, update, and delete records in VB6 or Python — entirely in the browser.
Supabase gives you a free hosted PostgreSQL database with an instant REST API. WebVB Studio gives you a visual form designer and code editor in the browser. Combine them and you get a full CRUD app — browse, create, update, and delete records — without writing a single line of backend code, without installing anything, and without deploying a server. Open the live example →
What Is Supabase?
Supabase is an open-source Firebase alternative built on top of PostgreSQL. It gives you a fully managed database, auto-generated REST API, authentication, real-time subscriptions, and storage — all from a generous free tier. If you've ever wanted to add a real database to an app without standing up an Express server or learning Django, Supabase is your shortcut.
Key things that make Supabase great for this tutorial:
- Instant REST API — every table you create gets a fully typed REST endpoint automatically
- Free tier — 500 MB database, 50,000 monthly active users, unlimited API requests
- Row Level Security — fine-grained access control built into PostgreSQL
- SQL Editor — run SQL directly in the Supabase Dashboard
- No backend needed — call the API directly from the browser with the Publishable Key
What You'll Build
By the end of this tutorial you'll have a product management app that connects to a Supabase PostgreSQL table and performs full CRUD operations:
- Connect to your Supabase project with a URL and Publishable Key
- Read — load all products into a scrollable list
- Create — add new products with name, description, price, stock, and category
- Update — edit existing products in-place
- Delete — remove products with a single click
- Navigate — browse records with First / Previous / Next / Last buttons
The entire app runs in your browser via WebVB Studio. No Node.js, no React, no Next.js, no deploy pipeline. Just open the IDE, paste your Supabase credentials, and click Run.
Prerequisites
| What | Where | Cost |
|---|---|---|
| Supabase account | supabase.com | Free |
| WebVB Studio | app.webvbstudio.com | Free |
| Modern browser | Chrome, Firefox, Safari, Edge | Free |
No downloads, no installs, no command line. Everything happens in the browser.
Step 1: Create a Supabase Project
- Go to supabase.com/dashboard and sign in (or create an account)
- Click New Project
- Choose a name (e.g.
webvb-products), set a database password, and pick a region - Wait ~60 seconds for the project to provision
- Once ready, go to Settings → API and copy your:
- Project URL — looks like
https://abcdefg.supabase.co - Publishable Key (anon public) — a long
eyJ...string
- Project URL — looks like
The Publishable Key is designed to be used in client-side code, but it only works because Row Level Security restricts what it can do. Never expose your service_role key in the browser.
Step 2: Create the Products Table
Open the SQL Editor in the Supabase Dashboard (left sidebar) and run this:
-- Create a table for Products
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
price NUMERIC(10, 2) NOT NULL,
stock_quantity INTEGER DEFAULT 0,
category TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
); Why this schema works well:
- SERIAL — auto-incrementing ID, no need to provide one on insert
- NUMERIC(10,2) — better than FLOAT for money because it avoids rounding errors
- NOW() — automatically timestamps when a product is added
Step 3: Insert Sample Data
Still in the SQL Editor, run:
INSERT INTO products (name, description, price, stock_quantity, category)
VALUES
('Mechanical Keyboard', 'RGB backlit with blue switches', 89.99, 50, 'Electronics'),
('Ergonomic Mouse', 'Wireless optical mouse with 6 buttons', 45.00, 120, 'Electronics'),
('Coffee Mug', 'Ceramic 12oz mug with matte finish', 12.50, 200, 'Home & Kitchen'),
('Leather Notebook', 'Hand-bound A5 ruled notebook', 24.00, 75, 'Stationery'),
('USB-C Hub', '7-in-1 adapter with HDMI and SD ports', 35.95, 30, 'Electronics'); You should now see 5 rows in Table Editor → products.
Step 4: Disable RLS (Quick Start)
Supabase enables Row Level Security by default on new tables, which blocks all access until you create policies. For the fastest path to a working app, disable it:
ALTER TABLE products DISABLE ROW LEVEL SECURITY; With RLS disabled, your Publishable Key has full read/write access to the table. This is fine for learning, but never do this in production. See Step 8 for proper RLS policies.
Step 5: Open the Example in WebVB Studio
Click the button below to open the Supabase CRUD example directly in WebVB Studio:
Open Supabase Example in WebVB Studio →
Or open it manually: go to app.webvbstudio.com, click File → Examples, and select Supabase Database from the Database category.
Step 6: Connect and Run
- Paste your Supabase Project URL into the URL field
- Paste your Publishable Key into the Key field
- Click Connect
- Your 5 sample products should appear in the list
That's it. You now have a working database app in your browser.
How It Works Under the Hood
The example uses two WebVB Studio controls to talk to Supabase:
| Control | Purpose | Supabase Endpoint |
|---|---|---|
| Database (Data1) | Read data via REST | GET /rest/v1/products |
| Inet (Inet1) | Write data via JSON methods | POST, PATCH, DELETE |
Connecting (VB6)
Sub cmdConnect_Click
ApiKey = Trim(txtKey.Text)
BaseUrl = Trim(txtUrl.Text) & "/rest/v1"
' Set up the Database control for reading
Data1.InitREST BaseUrl
Data1.SetHeader "apikey", ApiKey
Data1.SetHeader "Authorization", "Bearer " & ApiKey
Data1.SetHeader "Prefer", "return=representation"
Data1.TableName = "products"
' Set up the Inet control for writing
Inet1.ClearHeaders
Inet1.SetHeader "apikey", ApiKey
Inet1.SetHeader "Authorization", "Bearer " & ApiKey
Inet1.SetHeader "Content-Type", "application/json"
Inet1.SetHeader "Prefer", "return=representation"
Reload
End Sub Connecting (Python)
def cmdConnect_Click():
global api_key, base_url
api_key = txtKey.Text.strip()
base_url = txtUrl.Text.strip() + "/rest/v1"
Data1.InitREST(base_url)
Data1.SetHeader("apikey", api_key)
Data1.SetHeader("Authorization", "Bearer " + api_key)
Data1.SetHeader("Prefer", "return=representation")
Data1.TableName = "products"
Inet1.ClearHeaders()
Inet1.SetHeader("apikey", api_key)
Inet1.SetHeader("Authorization", "Bearer " + api_key)
Inet1.SetHeader("Content-Type", "application/json")
Inet1.SetHeader("Prefer", "return=representation")
reload_data() CRUD Operations
Each operation maps directly to a Supabase REST endpoint:
| Action | HTTP Method | Endpoint | WebVB Method |
|---|---|---|---|
| Read all | GET | /rest/v1/products | Data1.RESTRefresh |
| Create | POST | /rest/v1/products | Inet1.PostJSON |
| Update | PATCH | /rest/v1/products?id=eq.5 | Inet1.PatchJSON |
| Delete | DELETE | /rest/v1/products?id=eq.5 | Inet1.DeleteJSON |
Notice the ?id=eq.5 query filter — this is how Supabase's PostgREST API targets specific rows. The eq. operator means "equals".
Creating a Product (VB6)
Sub cmdSave_Click
Dim url
url = BaseUrl & "/products"
Dim body
body = BuildBody() ' builds JSON from form fields
Inet1.PostJSON url, body, "OnInserted"
End Sub
Sub OnInserted(resp)
Dim s
s = Inet1.ResponseStatus
If s >= 200 And s < 300 Then
lblStatus.Caption = "Inserted! (HTTP " & s & ")"
Else
lblStatus.Caption = "Insert failed"
End If
Reload
End Sub Creating a Product (Python)
def cmdSave_Click():
import json
body = json.dumps({
"name": txtName.Text.strip(),
"description": txtDesc.Text,
"price": float(txtPrice.Text or "0"),
"stock_quantity": int(txtStock.Text or "0"),
"category": txtCategory.Text
})
url = base_url + "/products"
Inet1.PostJSON(url, body, "OnInserted")
def OnInserted(resp):
s = Inet1.ResponseStatus
if 200 <= s < 300:
lblStatus.Caption = f"Inserted! (HTTP {s})"
else:
lblStatus.Caption = f"Insert failed — HTTP {s}"
reload_data() Step 7: Enable Realtime (Optional)
If you want the app to automatically detect changes made by other users or from the Supabase Dashboard, enable Realtime on the table:
ALTER PUBLICATION supabase_realtime ADD TABLE products; You can also enable this from the Supabase Dashboard UI under Table Editor → products → Realtime.
Step 8: Row Level Security (Production)
When you're ready to go beyond testing, enable Row Level Security and add proper policies. RLS is PostgreSQL's built-in access control — it lets you define exactly who can do what, per row, per operation.
-- 1. Enable Row Level Security (this is the bouncer at the door)
ALTER TABLE products ENABLE ROW LEVEL SECURITY;
-- 2. Anyone with the Publishable Key can VIEW products (Read / GET)
CREATE POLICY "Allow public read"
ON products FOR SELECT
TO anon -- "anon" is the Supabase role used by the Publishable Key
USING (true);
-- 3. Only logged-in users can ADD products (Write / POST)
CREATE POLICY "Allow auth insert"
ON products FOR INSERT
TO authenticated
WITH CHECK (true);
-- 4. Only logged-in users can EDIT products (Update / PATCH)
CREATE POLICY "Allow auth update"
ON products FOR UPDATE
TO authenticated
USING (true);
-- 5. Only logged-in users can DELETE products (Delete / DELETE)
CREATE POLICY "Allow auth delete"
ON products FOR DELETE
TO authenticated
USING (true); With these policies in place:
- Unauthenticated visitors (using the Publishable Key) can only read products
- Logged-in users (authenticated via Supabase Auth) can read, insert, update, and delete
- Without any policy, RLS blocks all access — this is secure by default
Supabase vs Alternatives for Quick Apps
| Feature | Supabase + WebVB | Firebase | Airtable | Express + PostgreSQL |
|---|---|---|---|---|
| Install required | None | npm / SDK | None | Node.js, npm, pg |
| Database type | PostgreSQL | NoSQL (Firestore) | Spreadsheet | PostgreSQL |
| SQL support | Full SQL | No | No | Full SQL |
| REST API | Auto-generated | SDK only | Auto-generated | Manual |
| Visual GUI builder | Yes (25+ controls) | No | No | No |
| Backend code | None | Minimal | None | Full backend |
| Free tier | Generous | Limited | Limited rows | Self-hosted |
| Time to first CRUD app | ~5 minutes | ~30 minutes | ~10 minutes | ~2 hours |
Troubleshooting Common Errors
| Error | Cause | Fix |
|---|---|---|
HTTP 401 Unauthorized | Wrong or missing API key | Check that you pasted the full Publishable Key (starts with eyJ) |
HTTP 403 Forbidden | RLS is blocking access | Disable RLS for testing, or add proper policies (see Step 8) |
HTTP 404 Not Found | Wrong table name or URL | Double-check your Project URL and that the table exists |
0 products loaded | Table is empty or wrong table name | Run the INSERT sample data query, check the Table field |
Insert failed | Missing required fields or RLS | Ensure name and price are filled in, check RLS policies |
Real-World Use Cases
Once you understand the Supabase + WebVB pattern, you can build far more than a product catalog:
- Inventory management system — track stock levels across warehouses
- Customer relationship manager (CRM) — store contacts, notes, and deal stages
- Project task tracker — kanban-style boards backed by PostgreSQL
- IoT device registry — combine with MQTT dashboards for a full IoT platform
- School grade book — teachers manage students, assignments, and scores
- E-commerce admin panel — manage orders, customers, and products
- Survey / form collector — POST responses to a Supabase table, view them in a DataGrid
Any Supabase table works with the same pattern: InitREST, set headers, RESTRefresh to read, PostJSON / PatchJSON / DeleteJSON to write.
Frequently Asked Questions
Do I need to know SQL to use Supabase?
Not necessarily. Supabase has a Table Editor UI where you can create tables visually. But knowing basic SQL (CREATE TABLE, INSERT, SELECT) makes you much more productive. This tutorial gives you all the SQL you need.
Can I use this with a different Supabase table?
Yes. Change the Table field in the app to any table name and click Switch. The app dynamically queries whatever table you specify. You'll just need to update the form fields to match your table's columns.
Is the Publishable Key safe to use in the browser?
Yes, when combined with Row Level Security. The Publishable Key uses the anon role, which is restricted by RLS policies. Without RLS policies, the key can do nothing. That's why you define exactly what anon can do per table.
Can I switch between VB6 and Python?
Yes. The example includes both VB6 and Python code. In WebVB Studio, go to Options → Language to switch. The controls and form layout are identical in both languages.
Does this work offline?
The WebVB Studio IDE works offline, but the Supabase connection requires internet access since the database is hosted in the cloud. For offline databases, see the SQLite Database example.
Next Steps
- Open the Supabase example and try it with your own project
- Browse the 38+ other examples — calculators, charts, MQTT IoT, encryption, and more
- Read the Control Reference to learn about Database and Inet controls
- Explore SQLite Database for an offline alternative
- Build an MQTT IoT Dashboard and store sensor data in Supabase
Have a question? Join the WebVB community or open an issue on GitHub.
Ready to try WebVB Studio?
Build your first Python GUI app in under 5 minutes. No installation, no sign-up. Just open your browser and start coding.
Related Posts
Introduction to WebVB Studio for Python Developers
Building Python GUIs has always been painful — until now. WebVB Studio lets you design forms visually, write Python event handlers, and run everything in the browser. No pip install, no virtual envs, no config files.
Python GUI in 2026: Tkinter vs WebVB Studio — Which Should You Use?
Tkinter ships with Python, but is it still the best option in 2026? We compare Tkinter and WebVB Studio head-to-head across 10 real-world tasks — from a simple form to a Pandas dashboard — with full code examples for both.
How to Build a Custom Victron Energy MQTT Dashboard — Free, No Install
Your Victron Cerbo GX already publishes hundreds of MQTT topics — solar, battery, grid, inverter. This guide shows you how to build a beautiful real-time dashboard with gauges and charts in minutes, with zero installation.