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
--turbo
Rust 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-32kseqlen
as 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
metadataBase
inapp/layout.tsx
to match your target domain
- Run
vc env pull
to get a.env.local
file with your db credentials. - Run
pnpm dev
to start developing - For DB migrations with
drizzle-kit
:- Make sure
?sslmode=required
is added to thePOSTGRES_URL
env for dev - Run
pnpm drizzle-kit generate:pg
to generate migrations - Run
pnpm drizzle-kit push:pg
to 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
now
prop 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
/next
implementation after login - Add support for passkeys
- A basic admin panel
- User profiles
MIT