Welcome to my corner of the web.
To run the site locally, follow these steps:
# install dependencies
pnpm install
# add the GitHub token used to render the contributions chart
printf 'CONTRIBUTIONS_TOKEN=your-token\n' > .env.local
# run development server
pnpm run devEnvironment variables are declared in .env.schema and loaded by
Varlock. Run pnpm env:check to validate the schema and
local values. .env.local is gitignored; it can also contain the optional
DISCOGS_TOKEN used by the vinyl sync script.
The project uses Oxc for linting and formatting, with ESLint for template checks:
- Oxlint lints JavaScript, TypeScript, and script blocks in Astro and Svelte files.
- ESLint keeps the Astro and Svelte template rules that Oxlint does not support. Rules handled by Oxlint are disabled in ESLint.
- Oxfmt formats supported files,
including JavaScript, TypeScript, Astro, Svelte, JSON, CSS, Markdown, MDX, and
YAML. Astro formatting requires the
@astrojs/compiler-rsdevelopment dependency. astro checkprovides Astro, Svelte, and TypeScript diagnostics.
Use pnpm lint to run all checks, pnpm lint:fix to fix lint issues, and
pnpm format to format all supported files.
The vinyl collection is an Astro content collection. Each record has:
- A JSON entry in
src/content/vinyls/<slug>.json - A square WebP cover in
src/assets/vinyls/<slug>.webp
Run pnpm vinyls:sync after adding records to Discogs. The script compares the
live collection with local content and downloads possible clean covers for only
the missing records into .vinyl-sync/. Review the candidates, then add the
generated JSON and selected cover to the content and asset directories above.
The JSON filename becomes the record's URL under /music/vinyls/<slug>.
Set DISCOGS_TOKEN in the environment or .env.local for authenticated Discogs
requests. Public collections also work without a token at a lower rate limit.
pnpm vinyls:check validates that every record has a matching square WebP cover
no larger than 1000×1000 or 500 KiB. It runs as part of pnpm lint and CI.
To build the website, I'm using: