🚀 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
- Go to https://app.supabase.com
- Create a new project
- Grab your
ANON KEYandPROJECT URL - Add these to your
.env:
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:
idtitleurluser_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