๐Ÿš€ 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.