- Demo site :: web.vazen.dev
- Vazen :: velocity + (minimal & simplicity)
- pnpm :: Fast, disk-efficient package manager
- portless :: Clean local hostnames for app development
- commitlint :: Enforces Conventional Commits
- lefthook :: Fast Git hooks (pre-commit, pre-push, etc.)
- fallow :: Dead-code analysis and project cleanup
- oxfmt :: Opinionated code formatter
- oxlint :: Static analysis and linting
- Playwright :: End-to-end testing for browser workflows
- Docker :: Local development via Docker Compose
- t3-oss/env-nextjs :: Validates environment variables at build-time
- Nosecone :: Security headers made simple (Arcjet’s OSS library)
- Next.js v16 :: React framework with app router
- React.js v19 :: Latest React with React compiler enabled
- Typescript :: Type-safe development
- Tailwind CSS v4 :: Utility-first CSS framework
- oRPC :: tRPC alternative with built-in OpenAPI support
- Tanstack Query :: Data fetching and caching
- PostgreSQL :: Primary database
- Upstash :: Severless redis
- Cloudflare R2 :: S3-compatible object storage via
files-sdk - Drizzle ORM :: Sequel (SQL) Statement Builder
- Better-Auth :: Comprehensive authentication framework
- React Email :: React-based email templates
- Statsig :: Feature flags
- PostHog :: Web analytics
- Sentry :: Error monitoring & logging
- Evlog :: Simple logs, wide events, and structured logging
- Infisical :: Centralized secrets and env injection for dev, staging, and production
- Uses portless :: apps run on clean hostnames instead of raw ports.
- Local hosts:
https://local.web.vazen.idandhttps://local.docs.vazen.id - We use
.idinstead of.localhostbecause auth clients and OAuth providers such as Google can reject.localhostredirect URLs during local development. - Dev scripts in
apps/web/package.jsonandapps/docs/package.jsonare wired to portless.
Local hosts:
https://local.web.vazen.idhttps://local.docs.vazen.id
Important
Agentic coding and secrets. AI-assisted workflows can index or include workspace files in context. A .env with real keys may show up in model output, logs, or a shared thread. Assume secrets on disk near source are visible to tooling. Use Infisical for credentials, not long-lived env files in the repo.
Extra steps around secrets (CLI, login, skipping local .env dumps) are intentional. It is always okay to overengineer security.
- Infisical stores secret values per environment (
dev,staging,production). infisical run --(used by dev scripts) fetches the selected environment and injects vars into the process before Next/portless starts.- The web app uses t3-oss/env-nextjs to validate env names and types at build/runtime.
- In git:
.infisical.jsonpoints at the Infisical project;.env.examplelists keys with placeholders only..envand.env.localare gitignored.
- One source of truth: change a key in Infisical, restart dev, the team gets the same value on the next run.
- Keeps real credentials out of the clone so search and agentic coding are less likely to expose them (see callout above).
- Setup (once): run mise in the repo root ·
infisical login· leave.infisical.jsonas committed · start web withpnpm web:dev(root) orpnpm devinapps/web - Daily: use those scripts, or prefix any command with
infisical run --· use Infisical environmentdevlocally (--env=devif the CLI asks) - Change a secret: Infisical dashboard · pick
dev,staging, orproduction· edit the key · restart the dev server - Add a variable: set the value in Infisical for each env that needs it · add to the web app
createEnvschema if required · add a placeholder line to.env.example - Avoid: committing
.env*files that contain real secrets · pasting live values into issues or AI threads
- MIT License :: See the LICENSE file for details.