Personal portfolio — photographer · vibe coder · tech enthusiast.
Dark, photo-first design: near-black canvas, photos carry the color, terminal-styled projects section. Fully static — no DB, no CMS.
Stack: Next.js (App Router) · TypeScript · Tailwind 4 · Bun · Vercel
bun install
bun devThe site never reads the NAS at runtime. It renders only from content/photos.json,
which is generated from a curated set of originals:
- Drop picks into
photos-src/<Album Name>/*.jpg— the folder name becomes the album title.photos-src/is gitignored (originals stay local). - Run
bun run photos. For each image this:- resizes to max 2560px and re-encodes as WebP into
public/photos/<album-slug>/ - strips all EXIF/GPS metadata from the published file
- records only camera/exposure info (never GPS) in the manifest for captions
- resizes to max 2560px and re-encodes as WebP into
- Commit
content/photos.jsonandpublic/photos/— both are checked in so builds are deterministic.
Folders named close ups (any spelling) are refused by a hard-coded denylist and
will never be published.
The hero image is the first photo of the first album (albums and files sort alphabetically) — rename files to control ordering.
Hand-edited in content/projects.ts.
bunx vercel # preview
bunx vercel --prod # productionDomain: edmundlim.systems (root). The timetable stays at
timetable.edmundlim.systems.