Simple Reddit‑Free Reader (Ueddit) Clone

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.

Before you start…

Component Overview
YOUR MACHINE EXTERNAL SERVICES fetch posts HTTP request Express Server Reddit JSON API https://www.reddit.com/r/:sub/.json Web Browser
1

Phase 1: Scaffold the project

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=module
2

Phase 2: Data fetch layer (model)

Add 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));
  });
}
3

Phase 3: API + UI (controller & view)

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}`));
4

Phase 4: Run locally

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.js
5

Phase 5: Verify & extend

With 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

Verifying the Stack

CheckCommand / Why it matters
Server starts without errorsnode index.js → console shows listening message
Browser displays a list of titles for /r/technologyOpen http://localhost:3000/technology and see at least 5 <li> items
cURL returns a numeric count of <li> elementscurl -s http://localhost:3000/programming | grep '<li' | wc -l → >0

What’s next?

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.