Tutorials February 16, 2026 | 11 min read

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 #Database #PostgreSQL #CRUD #Python #VB6 #Tutorial
TL;DR

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

  1. Go to supabase.com/dashboard and sign in (or create an account)
  2. Click New Project
  3. Choose a name (e.g. webvb-products), set a database password, and pick a region
  4. Wait ~60 seconds for the project to provision
  5. 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
Keep your keys safe

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;
Testing only

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

  1. Paste your Supabase Project URL into the URL field
  2. Paste your Publishable Key into the Key field
  3. Click Connect
  4. 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


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.