Dev • Twitch lurker • Musician • Marxist
A glitch-forward portfolio and content platform for onnwee. The repo ships a static React site today and a Go API that is ready for future dynamic integrations (analytics, search, CRUD authoring tools).
🚀 New here? Check out CONTRIBUTING.md for a complete guide to setting up your local environment in under 15 minutes.
- Frontend: Vite + React + TypeScript (
client/) - Styling: Tailwind CSS with custom design tokens (
client/src/index.css) - Content: MDX blog posts, project metadata in TypeScript
- Backend: Go HTTP API with Gorilla Mux, sqlc-generated data layer (
backend/) - Observability: OpenTelemetry + Prometheus metrics at
/metrics - Deploy: GitHub Pages via Actions (frontend), Docker Compose for local backend infra
client/is a single-page app served from GitHub Pages. Routing (react-router-dom) renders sections like/projects,/blog, and/projects/:slug.backend/contains a Go service exposing REST endpoints for posts, projects, users, logs, events, sessions, and page views. sqlc keeps SQL ininternal/queries/*.sqland generates strongly typed accessors ininternal/db.- Middleware stack (
backend/pkg/middleware) adds logging, panic recovery, permissive CORS, rate limiting, and real client IP detection.api.NewRoutercomposes everything under OpenTelemetry'sotelhttpwrapper. - Prometheus is enabled out of the box:
backend/cmd/server/main.gomounts/metricsanddocker-compose.ymlprovisions Prometheus + Grafana dashboards pointed at the Go app. - Frontend embeds and error handling rely on shared utilities:
renderEmbed,SafeEmbedRenderer,ErrorBoundary, and a singletonerrorMonitorthat drives the dev error overlay.
- Node.js 20+ and npm 10+
- Go 1.24+
- Docker and Docker Compose
- sqlc:
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
cd client
npm install # install dependencies
npm run dev # start Vite dev server with hot reloadVisit http://localhost:5173 to see the frontend.
cd backend
# Start infrastructure (PostgreSQL, Prometheus, Grafana)
make up
# Wait for PostgreSQL to be ready (~10 seconds)
sleep 10
# Initialize database schema
make reset-db
# Generate Go code from SQL
sqlc generate
# Seed with sample data
make seed
# Run API server
go run cmd/server/main.goVisit http://localhost:8000/users to verify the API is running.
For detailed setup instructions, troubleshooting, and contribution guidelines, see CONTRIBUTING.md.
cd client
npm install # install dependencies
cp .env.example .env # configure environment variables (optional)
npm run dev # start Vite dev server with hot reload
npm run build # production build (emits to dist/)
npm run preview # serve built assets locally- Environment Setup (Optional): Copy
client/.env.exampletoclient/.envto configure optional environment variables likeVITE_API_BASE_URL,VITE_ADMIN_TOKEN, or feature flags. All Vite environment variables must be prefixed withVITE_to be exposed to the browser. - Theme + glitch controls live in
src/context/ThemeContext.tsx; wrap new UI in<ThemeProvider>and use theuseTheme()hook. - The blog uses
vite-plugin-mdxplus a frontmatter transformer (vite.config.ts). Every MDX file undersrc/blog/needs at leasttitle,tags, and optionalsummary/datefrontmatter to appear in the index. LazyGrid+useResponsiveItemsPerPagecoordinate virtualized grids. Prefer these utilities for paginated/animated lists (projects, blog index, future galleries).- Embed external media through
renderEmbedorSafeEmbedRendererso URL validation, sandboxing, loading states, and glitch styling stay consistent.
cd backend
go mod tidy # sync go.mod
cp .env.example .env # configure environment variables (edit DATABASE_URL)
make up # postgres + prometheus + grafana via docker-compose
sqlc generate # regenerate internal/db after editing SQL
go run cmd/server/main.go # run API locally (loads .env automatically)
make seed # populate fake data via gofakeit (respects SEED_* envs)
make reset-db # drop/recreate tables using scripts/reset_db.sh
make logs # tail Docker service logs
make down # stop Docker services- Environment Setup: Copy
backend/.env.exampletobackend/.envand configure yourDATABASE_URL. See the backend README for all available environment variables. - Define schema changes in
internal/schema.sqland queries ininternal/queries/*.sql. Regenerate Go code withsqlc generate; never hand-editinternal/db. cmd/server/main.goloads.envautomatically viagodotenv, builds the mux router, and exposes Prometheus metrics alongside the API.- Middleware instrumentation plus
otelhttpwrappers ensure request metrics surface in Prometheus/Grafana. - Seed script (
cmd/seed/seed.go) respects env overrides:SEED_NUM_USERS,SEED_NUM_POSTS,SEED_DELAY, etc. The Docker compose service seeds large datasets by default—tweak envs to keep local inserts manageable.
client/
src/
components/ // shared UI (ErrorBoundary, LazyGrid, embeds, nav)
context/ // ThemeProvider + glitch toggles
data/ // static project metadata
hooks/ // responsive + intersection observer helpers
pages/ // route-level components
blog/ // MDX posts with frontmatter
backend/
cmd/server/ // API entrypoint exposing /metrics + mux router
cmd/seed/ // gofakeit-powered data seeding
internal/api/ // handler registrations per resource
internal/db/ // sqlc generated queries/models
internal/queries/ // SQL source of truth
pkg/middleware/ // logging, recovery, cors, rate limiting, real IP
scripts/reset_db.sh // docker exec helper for wiping local DB
- Launch
make upto spin up Postgres + Prometheus + Grafana. Grafana listens onlocalhost:3000(admin/admin). - API metrics live at
/metricsand are scraped by Prometheus (prometheus.ymltargetsgo_app:8000). - Client-side errors in development surface through
ErrorOverlaypolling theerrorMonitorqueue. CallerrorMonitor.logReactErrorinside newErrorBoundarywrappers when adding risky UI.
Both client/ and backend/ use environment files for configuration:
- Example files (
.env.example) are committed to the repository and contain all available configuration options with safe default values - Actual files (
.env,.env.local,.env.*) are ignored by git and should never be committed - Copy the example file and update with your actual credentials:
cp .env.example .env
- ✅ DO use
.env.examplefiles to document required configuration - ✅ DO use strong, unique passwords and tokens in production
- ✅ DO rotate credentials regularly
- ❌ DON'T commit
.envfiles or any files containing secrets - ❌ DON'T hardcode credentials in source code
- ❌ DON'T share
.envfiles via insecure channels (email, chat, etc.)
Vite exposes environment variables prefixed with VITE_ to the client bundle. Be careful not to expose sensitive credentials:
- ✅
VITE_API_BASE_URL- safe to expose (public API endpoint) - ❌
VITE_ADMIN_SECRET_KEY- would be exposed in browser, insecure
For admin operations, use backend authentication instead of client-side tokens.
The frontend is deployed to GitHub Pages automatically. To deploy manually:
cd client
# Build production bundle
npm run build
# Deploy to GitHub Pages (requires gh-pages package)
npm install -D gh-pages
npx gh-pages -d distAutomated Deployment:
- GitHub Actions can be configured to deploy on push to
main - The workflow should run
npm run buildin theclient/directory - Deploy the
client/dist/directory to thegh-pagesbranch
Custom Domain:
- Add a
CNAMEfile toclient/public/with your domain - Configure DNS to point to GitHub Pages
Backend services are currently local-only, but Docker Compose provides a ready stack for future deployment targets:
- Development: Use
make upto run locally - Production: Deploy Docker containers to a cloud provider (AWS, GCP, DigitalOcean)
- Environment Variables: Set
DATABASE_URL,PORT, and telemetry variables in production - Metrics: Prometheus metrics are exposed at
/metricsfor monitoring
For production deployment, consider:
- Using managed PostgreSQL (AWS RDS, DigitalOcean Databases)
- Setting up proper secrets management
- Configuring CORS for your frontend domain
- Enabling rate limiting and authentication middleware
We welcome contributions! Please read CONTRIBUTING.md for:
- Development setup and workflows
- Branching strategy and commit conventions
- Pull request process
- Code style guidelines
- Testing requirements
Quick Links:
- Expand MDX library components in
client/src/components/mdx/for richer blog formatting. - Wire the frontend to the Go API once auth/editor flows are ready.
- Add analytics (Umami) and search (Meilisearch) when infrastructure is in place.
- Add automated testing (Vitest for frontend, Go tests for backend)
- Implement CI/CD pipelines for automated deployment
Port 5173 already in use:
# Kill the process using the port
lsof -ti:5173 | xargs kill -9
# Or specify a different port
npm run dev -- --port 3000Build errors after updating dependencies:
cd client
rm -rf node_modules package-lock.json
npm install
npm run buildHot reload not working:
- Clear browser cache
- Restart Vite dev server
- Check for syntax errors in browser console
Database connection refused:
# Check if PostgreSQL is running
docker ps | grep postgres
# Restart database
cd backend
make down
make up
sleep 10
make reset-dbPort 8000 already in use:
# Find and kill the process
lsof -ti:8000 | xargs kill -9
# Or set a different port in .env
echo "PORT=8080" >> backend/.envsqlc generate fails:
# Reinstall sqlc
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
# Verify sqlc.yaml configuration
cat backend/sqlc.yaml
# Check SQL syntax in queries/Docker container name conflicts:
# Remove old containers
docker rm -f backend-db-1 prometheus grafana
# Restart services
cd backend
make upPermission denied errors:
# Make scripts executable
chmod +x backend/scripts/*.sh
# Fix Docker socket permissions (Linux)
sudo usermod -aG docker $USER
# Log out and back inOut of disk space:
# Clean Docker volumes
docker system prune -a --volumes
# Clean npm cache
npm cache clean --forceNeed help? Open an issue on GitHub or check CONTRIBUTING.md for more troubleshooting tips.