Contributing to yufan.me requires Node.js 25+, a running Postgres instance, and a running Redis instance. The project uses Vite+ (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/syhily/yufan.me/llms.txt
Use this file to discover all available pages before exploring further.
vp) as its build and toolchain runner — use vp commands instead of calling npm, pnpm, or yarn directly for package operations. The npm scripts in package.json are wired through vp under the hood, so npm run dev and similar commands work for day-to-day development once dependencies are installed.
Prerequisites
- Node.js 25 or later — matches the Alpine base in the production Dockerfile
- Postgres — any reachable instance; a local Docker container works fine
- Redis — used for sessions, rate limiting, and generated-image caches
Setup steps
Configure your environment
Copy the example environment file and fill in the three required variables:Open Optional variables in
.env and set:.env.example include MAXMIND_DB_PATH for geo-enriched analytics and ANALYTICS_TRACK_ADMIN to count your own visits in the dashboard.Install dependencies
Install npm dependencies. Vite+ is declared as a dev dependency so it is available immediately after install:For all subsequent package operations use
vp add, vp remove, and vp update rather than npm install <package> — see Adding packages below.Start the dev server
Start the development server with hot module replacement enabled for both server and client code:The server binds to
http://localhost:4321 by default. HMR applies to React components, route modules, and server code so most changes are reflected without a manual restart.Complete the install gate
On the very first boot, every request redirects to
/admin/setup. Open http://localhost:4321/admin/setup to run the two-stage install flow:- Stage 1 — create your admin account
- Stage 2 — at
/admin/setup/settings, supply the two required settings sections (blog.generalandblog.assets); yufan.me writes all 14 settings rows atomically and lifts the gate
/ and the admin console is available at /admin.Available commands
These commands map to the scripts defined inpackage.json. Internally they delegate to vp, Vite+‘s CLI:
| Command | Description |
|---|---|
npm run dev | Start the dev server with HMR |
npm run build | Produce a production build under build/ |
npm run start | Serve the production build (node ./build/server/index.js) |
npm run check | Run format, lint, and typecheck in parallel, then the test suite |
npm run typecheck | TypeScript type check only (react-router typegen && tsc) |
npm run db:generate | Generate a Drizzle migration file from schema changes |
Running tests
Run tests in watch mode during development:npm run check runs vp lint and vp run typecheck in parallel, then waits before running vp test run, so a lint or type error stops the suite early.
Adding packages
Usevp add / vp remove / vp update for all package operations after the initial install:
vite or vitest — need to be pinned through the overrides block in package.json to resolve against the Vite+ shims rather than upstream Vite. See AGENTS.md for details.
src/assets/scripts is intentionally absent from the repository. All client-side interactivity lives in React hooks and components under src/client/ and src/ui/. Do not create a scripts/ directory or add vanilla JS entry points.