Personal portfolio — a Next.js 14 site deployed on Vercel at roshan.codes.
npm install
npm run dev # dev server at localhost:3000
npm run build # production build
npm run start # serve the production build
npm run lint # ESLint (next/core-web-vitals); passes clean, not enforced at build timeFor the view counter, set UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN in .env.local. The site works fully without them — the counter just returns null.
Mostly statically generated. Almost all content is data-driven: edit JSON in data/ and Markdown in public/blog/ rather than JSX. See data/ADDING_CONTENT.md for the quick reference on adding content, and CLAUDE.md for the full architecture map (content table, blog system, hero deck, MapLibre research pages, global features).
| URL | Source | Maintenance |
|---|---|---|
/llms.txt |
public/llms.txt |
Hand-written — update when adding content |
/robots.txt |
public/robots.txt |
Hand-written; rarely changes |
/sitemap.xml |
pages/sitemap.xml.js |
Self-maintaining |
/feed.xml |
pages/feed.xml.js |
Self-maintaining |
/ and /about additionally emit schema.org Person JSON-LD from data/person.json.
After any substantive change (adding/removing/renaming a page, component, dependency, data file, script, or feature), follow the post-change maintenance protocol: keep CLAUDE.md, README.md, and data/ADDING_CONTENT.md in sync with reality, sweep out whatever the change deprecated, and finish with a passing npm run build. The protocol — and the claudemd-maintainer, docs-syncer, and rot-sweeper subagents that carry it out — is documented in CLAUDE.md and .claude/agents/.