🚀 Build a HackerNews Clone Using Svelte and Supabase

“A blazing-fast HackerNews clone with zero backend boilerplate? Yes, please!”

In this tutorial, we’ll build a lightweight, fast, and modern HackerNews clone using Svelte (the frontend wizard 🧙) and Supabase (the open-source Firebase alternative 💾).

📦 Why Svelte + Supabase?

  • Svelte compiles to tiny, performant JS
  • Supabase gives us:

    • PostgreSQL with RESTful & realtime APIs
    • Auth, storage, edge functions
    • No server-side code required

Together, they let you build fullstack apps without fullstack headaches.

🧰 What We’ll Build

A HackerNews-style app with:

  • ✅ Sign Up / Login (via Supabase Auth)
  • 🔗 Submit links (title + URL)
  • 🗳️ Upvote posts
  • 💬 Comment threads (basic)
  • ⚡ Real-time updates

🛠️ Project Setup

1. Install the SvelteKit App


npm create svelte@latest hackernews-clone  
cd hackernews-clone  
npm install  

2. Install Supabase Client


npm install @supabase/supabase-js  

3. Set up Supabase Project


VITE_SUPABASE_URL=https://xyzcompany.supabase.co  
VITE_SUPABASE_ANON_KEY=your-anon-key-here  

4. Initialize Supabase Client

Create src/lib/supabaseClient.ts:


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);  

🧑‍💻 Auth: Sign Up / Login

Create src/routes/login/+page.svelte


<script lang="ts">
  import { supabase } from '$lib/supabaseClient';
  let email = '';
  let password = '';

  const login = async () => {
    const { error } = await supabase.auth.signInWithPassword({ email, password });
    if (error) alert(error.message);
  };
</script>

<input bind:value={email} placeholder="Email" />  
<input type="password" bind:value={password} placeholder="Password" />  
<button on:click={login}>Log In</button>  

🔗 Submitting a Post

Create a posts table with fields:

  • id
  • title
  • url
  • user_email
  • upvotes (default: 0)

Submit Page Example


let title = '';  
let url = '';

const submit = async () => {  
  const user = await supabase.auth.getUser();  
  await supabase.from('posts').insert([{ title, url, user_email: user.data.user.email }]);  
};

🧠 Display Posts

src/routes/+page.svelte


let posts = [];

onMount(async () => {
  const { data } = await supabase.from('posts').select('*').order('upvotes', { ascending: false });
  posts = data;
});

🔼 Upvote Posts


const upvote = async (postId, currentVotes) => {
  await supabase.from('posts')
    .update({ upvotes: currentVotes + 1 })
    .eq('id', postId);
};

⚡ Real-time Updates

Enable Realtime for posts in Supabase UI.

Then:


supabase
  .channel('posts')
  .on('postgres_changes', { event: '*', schema: 'public', table: 'posts' }, payload => {
    // update local posts[]
  })
  .subscribe();

🔐 Auth Guard (optional)

Add to src/hooks.server.ts:


export async function handle({ event, resolve }) {
  const { user } = await supabase.auth.getUser();
  event.locals.user = user;
  return resolve(event);
}

🧪 Features You Can Add

  • 🧵 Comments table + nesting
  • 🧙 Admin flag moderation
  • 🕶️ Dark mode toggle
  • 🚀 PWA setup
  • 📱 Mobile-first UI

💡 Conclusion

You just built a modern HackerNews clone with Svelte and Supabase!

  • Svelte keeps your frontend blazing fast ⚡
  • Supabase handles your backend like magic 🧙

🌐 Useful Links

🔥 If you want part 2 — “Add Comments and Dark Mode” — let me know!


Source: DEV Community.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.