This repository powers ethotechnics.org, a content-driven site exploring ethical technology, human-centered design, and the sociotechnical systems that shape them. The project favors lean, fast-loading pages and clear storytelling.
Live site: https://ethotechnics.org
- Highlights
- Requirements
- Contributor quick start
- Quick start
- Common scripts
- Testing
- Security headers
- Deployment to Cloudflare Workers
- Documentation map
- Project structure
- Contributing
- License
- Built with Astro 5 and TypeScript for fast, accessible content delivery.
- Cloudflare Workers deployment with a dedicated
wrangler.tomlconfiguration. - Hardened security headers set in
src/middleware.ts. - Playwright end-to-end tests plus Bun unit/component coverage.
- ⭐ Star the repo to help others discover ethical technology and human-centered design resources.
- Share the live site with teammates or students who care about responsible technology practice.
- Subscribe to Field Notes via RSS: https://ethotechnics.org/field-notes/rss.xml.
- Follow updates on GitHub to track new essays, research notes, and design references.
Ethical technology, human-centered design, sociotechnical systems, Astro, Cloudflare Workers, accessible web performance, content strategy, digital ethics, UX research, responsible innovation.
- Node.js 20.x (use
nvm useto match the pinned toolchain). - Bun 1.3+ (see
.nvmrcfor the Node version andbun.lockfor dependencies).
- Align toolchains:
nvm use - Install dependencies:
bun install - Run the default PR check suite:
bun run check - Run the full release/nightly checks when needed:
bun run check:full
For a one-shot bootstrap (great for Codex and fresh clones), run:
bun run setup:codex- Install dependencies:
bun install - Run the dev server:
bun dev - Build the Worker bundle:
bun run build - Preview the build:
bun run preview(Astro) orbun run preview:cf(Wrangler Worker) - For deeper setup and troubleshooting tips, see
docs/local-development.md.
| Command | Purpose |
|---|---|
bun dev |
Run the Astro development server. |
bun run build |
Validate content JSON and build the Worker bundle (dist/_worker.js). |
bun run build:search |
Generate the Pagefind search index in dist/pagefind. |
bun run preview |
Preview the Worker build locally. |
bun run preview:cf |
Preview the Worker build via Wrangler with local bindings. |
bun run check |
Run default PR checks: lint, type checks, Astro checks, JSON validation, and unit tests. |
bun run check:full |
Run deep checks: default PR checks plus SEO audit and coverage unit tests. |
bun run clean |
Remove generated local build/test artifacts while keeping dependencies installed. |
bun run clean:all |
Remove all generated artifacts plus local dependencies and Playwright caches. |
bun run lint |
Lint Astro and TypeScript sources under src/. |
bun run lint:fix |
Lint and auto-fix Astro and TypeScript sources under src/. |
bun run format |
Format Markdown and source files with Prettier. |
bun run format:check |
Check formatting with Prettier (CI-friendly). |
bun test |
Run unit and component tests with Bun. |
bun run test:e2e |
Build and run Playwright against the preview server (Chromium, Firefox, WebKit). |
bun run test:e2e:smoke |
Build and run a Chromium-only Playwright smoke suite. |
bun run deploy |
Build and deploy the Worker to Cloudflare using Wrangler. |
The following paths are generated and safe to delete locally when you want to reclaim disk space:
dist/,.astro/,.vercel/,coverage/test-results/,playwright-report/,blob-report/,playwright/.cache/,playwright/.auth/astro_check_log.txtnode_modules/(recreated withbun install)
Use bun run clean for standard output cleanup and bun run clean:all when you also want to
remove dependencies and Playwright caches.
- After installing dependencies, run
bunx playwright install --with-depsto install browser binaries and system packages. bun run test:e2ebuilds the Worker bundle and runs Playwright againstbun run previewacross Chromium, Firefox, and WebKit.bun run test:e2e:smokeruns the same flow on Chromium only for faster PR validation.- Use
bun run preview:cfwhen you need to validate Worker runtime behavior (Durable Objects, bindings, or Workers KV) locally. - Override the preview target with
PLAYWRIGHT_BASE_URL(defaults tohttp://127.0.0.1:4321). - Cloudflare Pages can run the suite using
CF_PAGES_URL; enable testing in the dashboard to run Playwright after the Worker build. - If Playwright browser downloads fail:
- Reuse cached downloads with
PLAYWRIGHT_BROWSERS_PATH=~/.cache/playwright. - Confirm proxies or firewalls are not blocking
https://playwright.azureedge.net. - Use a mirror via
PLAYWRIGHT_DOWNLOAD_HOST=https://your-mirror.example.com.
- Reuse cached downloads with
bun testruns the test suite.- Component rendering tests use the experimental Astro container (
src/test/astro-container.ts) and run under Bun with happy-dom helpers. - CI uses
bun run test:unit:cito execute once with coverage.
- Copy
.env.exampleto.env.localfor local development. Astro automatically loads.env,.env.local, and environment-specific files (such as.env.development). - No environment variables are required today, but add new entries to
.env.exampleif the project adopts external services.
Requests pass through src/middleware.ts, which normalizes legacy ethotechnics.com hosts and
appends a hardened header set to every response:
- HSTS (
Strict-Transport-Security): one-year max age with subdomains and preload to enforce HTTPS everywhere. - Content-Security-Policy: locks content to
self, blocks frames and plug-ins, restricts styles to the site origin, and permits images from the site,https:origins, ordata:URLs. - Referrer-Policy:
no-referrerto avoid leaking navigation history. - X-Content-Type-Options:
nosniffto disable MIME-type sniffing. - Permissions-Policy: disables camera, geolocation, microphone, and payment features.
The site uses the official Cloudflare adapter for Astro to produce a Worker-compatible server
build. wrangler.toml captures the Worker name, compatibility date, and entrypoint (dist/_worker.js).
Session storage is not enabled by default; if you add it later, define the KV binding in
wrangler.toml before deploying.
- Ensure the adapter is installed (
@astrojs/cloudflare) and configured inastro.config.mjswithoutput: "server". - The adapter is configured to use Cloudflare's image service and to exclude static assets
(
/_astro/*,/assets/*) from the server function so they can be served directly via the assets binding. - Build the Worker bundle with
bun run buildwhen you need to preview or inspect the output. The generated Worker entry is emitted todist/_worker.js. - Deploy with Wrangler using the repo defaults:
bun run deploy.- The deploy script runs Wrangler via
bunx, so no global installation is required. - The deploy script runs
bun run buildfirst so the upload always reflects the latest bundle. - The deploy command uses
--no-bundleto skip Wrangler's bundling step since Astro already emits the Worker bundle, reducing deploy time. - The build copies
.assetsignorefrompublic/todist/so Wrangler skips_worker.jsand_routes.jsonwhen uploading static assets.
- The deploy script runs Wrangler via
- Configure DNS for
ethotechnics.orgto point to the Cloudflare Worker route you set in Wrangler.
- Start with
docs/README.mdfor how the docs folder is organized, when to add a new guide, and formatting expectations. docs/contributor-workflow.mdoutlines the change loop, required checks, and formatting conventions for day-to-day work.docs/architecture.mdcovers the rendering model, middleware, and Cloudflare Worker deployment. Update it when routing, layouts, or adapters change.docs/specifications.mdprovides a high-level snapshot of site goals, routing, and delivery defaults.docs/adding-pages.mdwalks through creating new Astro routes without breaking shared navigation and metadata. Use it as the checklist for new content.docs/page-specifications.mdlists route-by-route expectations for data, layout, and accessibility.docs/content-data.mddocuments JSON-backed content sources, schemas, and validation steps.docs/content-components.mdcatalogs the page intro, section blocks, cards, and other building blocks reused across routes. Extend it when adding shared UI.docs/local-development.mdcaptures local setup, previews, and troubleshooting tips.docs/cloudflare-playwright.mdcaptures how to run the Playwright suite on Cloudflare Pages after the Worker build completes and how to surface test results in that environment.docs/testing-todos.mdtracks current test coverage and outstanding gaps to prioritize.docs/glossary.mddefines shared terminology used across the site and docs.docs/diagnostics-outputs.mdanddocs/usability-audit.mdcollect diagnostics output references and UX review findings.
src/pages: Astro routes, starting withsrc/pages/index.astrofor the homepage content.src/layouts: Shared layouts such assrc/layouts/BaseLayout.astro, which wires global SEO, fonts, and the navigation shell.src/components: Interactive islands and shared UI components such as the navigation insrc/components/Navigation.astro.src/styles: Global styles and theme tokens defined insrc/styles/global.css.
- Start with
CONTRIBUTING.mdfor the canonical contribution workflow. - Keep changes focused and easy to review; align with existing naming and formatting.
- Use Bun (not npm or yarn) and format Markdown/code with
bunx prettier --write. - Run
bun run checkfor code or mixed changes; runbun run check:fullfor release prep or periodic deep validation. Docs-only updates can skip both. - CI mirrors
bun run checkon pull requests via the Site checks workflow. - Read
AGENTS.md,docs/README.md, andCODE_OF_CONDUCT.mdbefore making larger updates.
This project is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license (CC BY-SA 4.0). Unless otherwise noted, you may share and adapt the content with proper attribution and under the same license terms. See https://creativecommons.org/licenses/by-sa/4.0/ for details.
