A minimal Node.js/Express app that fetches public Reddit posts without login
Welcome to another official UVF IT build guide. In the next 45 minutes you’ll spin up a tiny web service that mirrors the core of Ueddit – displaying Reddit threads without any authentication.
We’ll use plain Node.js, Express, and the free Reddit JSON endpoint, storing nothing locally. The result is a single‑page reader you can run on your laptop.
Create a fresh folder for the clone, initialise a new npm project, and install Express as the only runtime dependency. Adding "type":"module" lets us write modern ES‑module code without .mjs extensions.
These steps give you a clean workspace and a runnable Node server to which we will later attach our data‑fetching logic.
mkdir ueddit && cd ueddit
npm init -y
npm install express
# enable ES‑module syntax
npm pkg set type=moduleAdd a tiny module that contacts Reddit’s public JSON endpoint and returns an array of post titles. The function is async, uses the built‑in https module, and keeps the clone dependency‑free.
We expose fetchPosts(subreddit) so the Express route can call it later, keeping networking concerns separate from request handling.
fetchReddit.js
import https from 'https';
export async function fetchPosts(subreddit = 'news') {
const url = `https://www.reddit.com/r/${subreddit}/.json`;
return new Promise((resolve, reject) => {
https.get(url, res => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
try {
const json = JSON.parse(data);
const titles = json.data.children.map(c => c.data.title);
resolve(titles);
} catch (e) { reject(e); }
});
}).on('error', err => reject(err));
});
}In this step we expose an HTTP endpoint that talks to our model and turns the raw Reddit data into a readable page. The route extracts the subreddit name from the URL, asks the model for the latest posts, and then builds a tiny HTML list so anyone can see the titles without logging in.
We keep the view logic inline for simplicity: a string of <ul> items is interpolated into a basic HTML skeleton. This keeps the clone tiny while still demonstrating the classic MVC flow – controller fetches, view renders.
index.js
const express = require('express');
const fetch = require('node-fetch');
const app = express();
const PORT = process.env.PORT || 3000;
// Model: fetch top posts from a subreddit (public JSON endpoint)
async function getPosts(sub) {
const url = `https://www.reddit.com/r/${sub}/top.json?limit=10`;
const res = await fetch(url);
if (!res.ok) throw new Error('Failed to fetch subreddit');
const data = await res.json();
return data.data.children.map(c => c.data.title);
}
// Controller + View: route renders a simple HTML list
app.get('/:subreddit', async (req, res) => {
const sub = req.params.subreddit;
try {
const titles = await getPosts(sub);
const listItems = titles.map(t => `<li>${t}</li>`).join('');
const html = `<!doctype html><html><head><title>/r/${sub}</title></head><body><h1>/r/${sub}</h1><ul>${listItems}</ul></body></html>`;
res.send(html);
} catch (e) {
res.status(500).send(`<p>Error loading /r/${sub}: ${e.message}</p>`);
}
});
app.listen(PORT, () => console.log(`Ueddit clone listening on http://localhost:${PORT}`));Now that the server code is ready, we just need to start it and point a browser at the right address. The app listens on port 3000 by default, which is a common development port and works on most machines without extra configuration.
npm init -y
npm install express node-fetch@2
node index.jsWith the server running, open http://localhost:3000/technology in any browser – you should see a heading and a list of recent post titles. If you want to experiment, try adding a CSS file in a public folder and link it in the HTML string, or accept a ?limit= query parameter to control how many posts are fetched.
# Quick sanity check from the terminal
curl -s http://localhost:3000/programming | grep '<li' | wc -l| Check | Command / Why it matters |
|---|---|
| Server starts without errors | node index.js → console shows listening message |
| Browser displays a list of titles for /r/technology | Open http://localhost:3000/technology and see at least 5 <li> items |
| cURL returns a numeric count of <li> elements | curl -s http://localhost:3000/programming | grep '<li' | wc -l → >0 |
You now have a functional Reddit‑free reader. Consider adding pagination, caching with SQLite, or styling with Tailwind to turn this prototype into a full‑featured clone.