A full-stack replica of HN using Next.js and AI generated content.
- Uses Next.js 14 with App Router and RSC on the Node.js runtime
- All pages are server-rendered and dynamic, with no data caching
- All mutations are done via Server Actions
- Streaming is used throughout to maximize speed and concurrency
- Uses pnpm for package management
- Uses Drizzle ORM and Zod as the data layer
- Uses Auth.js's Next-Auth for password authentication
- Used v0 to generate all initial UIs with Tailwind, Shadcn UI and Radix UI
- Developed entirely and tested with the new Next.js
--turboRust compiler - Uses react-highlight-words for search highlights
- PPR (experimental) is used to precompute the shells of pages
- When deployed, these are served statically from the edge
- This makes TTFB faster and speeds up CSS/fonts while origin streams
- Deployed serverlessly on Vercel's Edge Network using:
- Cron Jobs for AI generation
- Serverless Functions (Node.js) for SSR (
iad1/us-east-1) - KV (Upstash) for rate-limiting (
iad1/us-east-1) - Postgres (Neon) for core storage and search with
pg_trgm(iad1/us-east-1)
- Uses Mixtral
mixtral-8x7b-32kseqlenas the LLM for generated content - Uses Anyscale's finetune for Tools support
- Uses openai-zod-functions for structured and runtime-validated generation
- Make sure the Vercel project is connected to a Vercel Postgres (Neon) database
- Optionally, for rate limiting, add a Vercel KV (Upstash) database
- Run
pnpm drizzle-kit push:pg - Update
metadataBaseinapp/layout.tsxto match your target domain
- Run
vc env pullto get a.env.localfile with your db credentials. - Run
pnpm devto start developing - For DB migrations with
drizzle-kit:- Make sure
?sslmode=requiredis added to thePOSTGRES_URLenv for dev - Run
pnpm drizzle-kit generate:pgto generate migrations - Run
pnpm drizzle-kit push:pgto apply them
- Make sure
PageSpeed report for Emulated Moto G Power with Lighthouse 11.0.0, Slow 4G Throttling:
💩 The SEO
98 score cannot be 100 without sacrificing stylistic fidelity to the original HN navigation
- Auth is initialized in
app/auth.tsx, Drizzle inapp/db.tsx. - Shared components are in
./components(exposed as@/components) - Only one component was not reused from npm / shadcn (
components/time-ago.tsx)- I couldn't find something very light that worked well with server-rendering (takes a
nowprop with a timestamp)
- I couldn't find something very light that worked well with server-rendering (takes a
- The following db migrations were added manually:
CREATE EXTENSION IF NOT EXISTS pg_trgm;as part of #13USING GIN (title gin_trgm_ops);as part of #13
This project is unique in that it's a full-stack replica of HN, with quite a few features. It'd be great for the community to fill in some important gaps, however:
- Inline comment replies
- "Forgot password" flow
- Voting and ranking
- "Next" and "Prev" comment links
- Comment toggling
- Flagging submissions and comments
- Improve search further
- Comment pagination
- More efficient comment datastructures
- Optimistic comments with
useOptimistic - Local storage of comment and submission drafts
- Improve the
/nextimplementation after login - Add support for passkeys
- A basic admin panel
- User profiles
MIT