Personal monorepo for ekel.dev — a static personal site built with Astro and Svelte.
.
├── .moon/ # Moon workspace + shared task presets (extends official Astro tasks)
├── apps
│ └── web # Main web application (Astro + Svelte)
│ ├── public/ # Static assets (images, fonts, etc.)
│ └── src/
│ ├── components/ # Astro and Svelte components
│ ├── content/ # MDX content collections (notes, works)
│ ├── helpers/ # Shared helper functions
│ ├── layouts/ # Page layout components
│ ├── pages/ # File-based routes (including og/, notes/, works/, tags/)
│ └── utils/ # Utilities, env, ImageKit, rehype/remark plugins
├── packages
│ ├── biome # Shared Biome (linter/formatter) config
│ ├── ui # Shared Svelte UI components package (@ikuyo/ui)
│ └── typescript # Shared TypeScript config
├── references/ # Optional writing/reference snippets (not part of the app build)
└── SKILL.md # Cursor skill / project notes (local workflow)
| Layer | Technology |
|---|---|
| Framework | Astro 5 (output: "static") |
| UI | Svelte 5 |
| Styling | Tailwind CSS v4, @tailwindcss/typography |
| Content | MDX via @astrojs/mdx, Content Collections |
| Build / monorepo | Bun, Moonrepo (Astro task preset from moon-configs) |
| OG images | astro-og-canvas + CanvasKit |
| Compression | astro-compressor (gzip/brotli), @playform/compress |
| Observability | Sentry (@sentry/astro) |
| Media | ImageKit (API + CDN for /photos) |
| Data | Turso (libSQL) for guestbook |
| HTTP client | ky |
| Charts | Chart.js (e.g. Wakatime page) |
| Dates | date-fns |
| E2E | Cypress |
| CI / perf | Lighthouse CI (lhci scripts at repo root) |
nix develop)bun install
bun dev:web # http://localhost:3000 (see apps/web/astro.config.ts for port)
bun build:web # runs Moon task chain for @ikuyo/web
This repo includes a flake.nix to provide a reproducible local toolchain.
nix develop
bun install
bun dev:web
Included tools in the shell:
bun, nodejs_22git, jq, ripgrep, fd| Script | Description |
|---|---|
bun dev:web |
moon run web:dev |
bun build:web / bun build:web:prod |
moon run web:build |
bun test:web |
moon run web:test (Cypress) |
bun lint:biome |
Biome check for apps/web and packages/ui |
bun format:biome |
Biome format (write) for apps/web and packages/ui |
bun lhci:mobile |
Lighthouse CI (mobile preset) |
bun lhci:desktop |
Lighthouse CI (desktop preset) |
apps/webMoon delegates dev, build, check, and test to this package using the shared Astro task definitions. Locally you can also run:
| Script | Description |
|---|---|
bun run dev / start |
Astro dev server |
bun run build |
astro check && astro build |
bun run preview |
Preview production output |
bun run lint:biome |
Biome check |
bun run format:biome |
Biome format (write) |
bun run test |
Cypress run |
bun run lhci:mobile / lhci:desktop |
Lighthouse from app context |
packages/ui| Script | Description |
|---|---|
bun run lint:biome |
Biome check for UI package |
bun run format:biome |
Biome format (write) for UI package |
| Route | Description |
|---|---|
/ |
Home — bio, experience, recent notes/works |
/notes, /notes/[...slug] |
Notes index and posts (MDX) |
/works, /works/[...slug] |
Portfolio index and project pages |
/tags, /tags/[...slug] |
All tags and notes filtered by tag |
/photos |
Gallery (ImageKit API at build time; client grid + lightbox) |
/guestbook |
Guestbook (Turso) |
/now |
Current focus |
/uses |
Tools and setup |
/wakatime |
Coding activity |
/eid-al-fitr |
Eid greeting (ID / EN toggle) |
/og/[...route] |
Dynamic Open Graph images (static paths from content + static pages) |
/rss.xml, /robots.txt |
RSS and robots |
/404, /500 |
Error pages |
Configured in apps/web/src/content/config.ts.
notes — MDX
{ author, title, description, created_at: Date, tags: string[] }
works — MDX
{ id, author, thumbnail /* https */, title, stack, repo?, preview?, description }
apps/web uses .moon/tasks/tag-astro.yml, which extends the official Astro Moon task preset (build depends on check).apps/web build script: astro check then astro build — static output to dist/, sitemap, HTML/asset compression integrations as configured in astro.config.ts.Copy apps/web/.env.example to apps/web/.env and set values as needed:
| Variable | Role |
|---|---|
PUBLIC_PRODUCTION_URL / PUBLIC_DEVELOPMENT_URL |
Site URLs |
TURSO_DATABASE_URL / TURSO_AUTH_TOKEN |
Guestbook database |
IMAGEKIT_PRIVATE_KEY / IMAGEKIT_API_BASE_URL |
List photos for /photos at build time |
SENTRY_DSN / SENTRY_PROJECT / SENTRY_AUTH_TOKEN |
Error reporting and source map upload |
BACKEND_API_URL |
Optional backend base URL |
CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID |
Deployment (e.g. Pages) |
NODE_VERSION |
Optional override for hosted Node version |
LHCI_GITHUB_APP_TOKEN |
Lighthouse CI (if used) |
@ikuyo/typescriptBase TS config: packages/typescript/base.json, extended by apps/web/tsconfig.json.
@ikuyo/biomeShared Biome preset (packages/biome/astro.json), extended by apps/web/biome.json.
@ikuyo/uiShared Svelte UI components used by the web app. Component generator configuration is located at packages/ui/components.json.
MIT