Back to articles

Build a Full-Stack CRUD App with SvelteKit and Supabase

AuthorMajd Muhtaseb07/01/202515 minutes
Build a Full-Stack CRUD App with SvelteKit and Supabase

Introduction

This tutorial will guide you through building a basic CRUD (Create, Read, Update, Delete) application using SvelteKit for the frontend and Supabase as your backend. SvelteKit provides a fantastic developer experience, and Supabase simplifies database management and authentication.

Prerequisites

  • Node.js and npm installed
  • A Supabase account and project set up

Setting up the SvelteKit Project

npm create svelte@latest my-crud-app
cd my-crud-app
npm install
npm install @supabase/supabase-js
npm run dev

Creating the Supabase Table

In your Supabase project, create a table named items with the following columns:

  • id (UUID, Primary Key)
  • name (Text)
  • description (Text)

Enable Row Level Security (RLS) and create policies as needed. For this example, let's assume you've created policies that allow authenticated users to create, read, update, and delete items.

Connecting to Supabase

Create a supabaseClient.js file in your src/lib directory:

// src/lib/supabaseClient.js
import { createClient } from '@supabase/supabase-js';

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;

export const supabase = createClient(supabaseUrl, supabaseAnonKey);

Make sure to set VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY in your .env file. These are found in your Supabase project settings.

Building the CRUD Operations

Reading Data (+page.svelte)

<script>
  import { supabase } from '$lib/supabaseClient';
  import { onMount } from 'svelte';

  let items = [];

  onMount(async () => {
    const { data, error } = await supabase
      .from('items')
      .select('*');

    if (data) {
      items = data;
    } else {
      console.error(error);
    }
  });
</script>

<h1>Items</h1>

{#each items as item (item.id)}
  <div>
    <h2>{item.name}</h2>
    <p>{item.description}</p>
  </div>
{/each}

Creating Data (+page.svelte - added to the above)

<script>
  // ... (previous code)
  let newItemName = '';
  let newItemDescription = '';

  async function createItem() {
    const { data, error } = await supabase
      .from('items')
      .insert([{ name: newItemName, description: newItemDescription }]);

    if (data) {
      items = [...items, ...data]; //add the new item to the UI
      newItemName = ''; //reset the form
      newItemDescription = '';
    } else {
      console.error(error);
    }
  }
</script>

<!-- ... (previous HTML) -->

<h2>Create New Item</h2>
<input type="text" bind:value={newItemName} placeholder="Name" />
<input type="text" bind:value={newItemDescription} placeholder="Description" />
<button on:click={createItem}>Create</button>

Updating and Deleting Data

Updating and deleting data would follow a similar pattern, using supabase.from('items').update() and supabase.from('items').delete() respectively. You'd need to add event handlers and input fields to your Svelte components to handle user interactions. Due to space constraints, the complete implementation is left as an exercise for the reader.

Conclusion

This tutorial provides a basic foundation for building a CRUD application with SvelteKit and Supabase. You can expand upon this by adding authentication, more complex data models, and improved UI/UX. Remember to consult the SvelteKit and Supabase documentation for more detailed information.