No description
- CSS 53.6%
- HTML 24.8%
- Zig 14.9%
- JavaScript 6.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| public | ||
| src | ||
| .gitignore | ||
| .prettierignore | ||
| .prettierrc | ||
| build.zig | ||
| build.zig.zon | ||
| LICENSE | ||
| package.json | ||
| README.md | ||
Maran — Freelance Portfolio
Portfolio site with Zig backend serving static frontend + contact API.
Stack
| Layer | Choice | Notes |
|---|---|---|
| Language | Zig 0.16.0 | |
| HTTP server | zap (master) | serves static files + POST /api/contact |
| CSS | TailwindCSS v4 (standalone CLI) | auto-downloaded on first build |
| Theme | Catppuccin Mocha/Latte | JS toggle, persisted to localStorage |
| Font | Inter (self-hosted, 4 WOFF2) | no Google Fonts |
| Map | Leaflet + OpenStreetMap | centered on 's-Hertogenbosch |
| Contact form | POST /api/contact → JSON file | rate-limited: 2 req / 60 min window |
Build
zig build
- Compiles Zig binary (
zig-out/bin/maran-site) - Runs Tailwind CLI (
input.css → style.css) - Auto-downloads Tailwind CLI for Linux x64 (glibc or musl) if missing
- Also available:
zig build css(Tailwind only),zig build test
Run
zig build run # serves on http://localhost:8080
Server defaults: port 8080, 2 threads, 1 worker.
TLS
TLS requires OpenSSL at build time. In build.zig, set openssl = true and install libssl-dev:
const zap = b.dependency("zap", .{
.openssl = true,
// ...
});
Then configure cert in src/main.zig:
const tls = try zap.Tls.init(.{
.server_name = "example.com",
.public_certificate_file = "/path/to/cert.pem",
.private_key_file = "/path/to/key.pem",
});
var listener = zap.HttpListener.init(.{
.port = 443,
.tls = tls,
// ...
});
Ports < 1024 need root or setcap cap_net_bind_service=+ep zig-out/bin/maran-site.
Contact form submissions
Stored as JSON files in data/contact-submissions/{timestamp}-{name}.json.
Dev tooling
LSPs installed via npm (dev only, not for build):
npm install
Provides typescript-language-server, tailwindcss-language-server, vscode-{html,css,json}-language-server, eslint.
All npm artifacts (node_modules/, package-lock.json) are gitignored.
Project layout
├── data/
│ └── contact-submissions/ contact form submissions (gitignored, created at runtime)
├── public/
│ ├── fonts/inter/ self-hosted Inter WOFF2
│ ├── js/main.js theme toggle, map, contact form
│ ├── index.html portfolio page
│ ├── input.css Tailwind source + Catppuccin vars
│ ├── style.css generated by Tailwind (gitignored)
│ └── maran.png logo + favicon
├── src/
│ └── main.zig zap server
├── tailwindcss standalone CLI binary (gitignored)
├── build.zig
├── build.zig.zon
├── .forgejo/
│ └── workflows/ci.yml CI (fmt, prettier, build)
├── package.json dev tools manifest
└── LICENSE BSD 3-Clause
Coming soon
- Email delivery – send contact form submissions via transactional email API (Resend, Mailgun) or local MTA (maddy)
- Deployment – systemd unit, reverse proxy setup, or direct TLS via zap
- Optionally environment config – env vars for port, TLS paths, SMTP credentials
License
BSD 3-Clause. See LICENSE.