packages/web/src/routes/docs/contributors/website/+page.md
This page describes how to develop writewithharper.com locally. If you are comfortable with JavaScript or TypeScript but new to Svelte, start with Prerequisites and Running the Site, then skim Where Code Lives.
Make sure you read the introduction to contributing and committing guides before opening a pull request.
packages/web.src/routes/docs/)./editor route use workspace packages harper.js, lint-framework, harper-editor, and components. just dev-web builds them for you.justfile to see exactly what the just recipes below do.Build Web workflow (Docker image from the root Dockerfile).node, pnpm, and just in your $PATH. You do not need a full Rust toolchain unless you are changing harper-wasm or harper-core.just setup once (or at least just build-web) so workspace dependencies and WASM artifacts are built.package.json engines field).| Path | Purpose |
|---|---|
packages/web/src/routes/ | Site routes: marketing pages (.svelte), docs (.md), and API handlers (+server.ts) |
packages/web/src/routes/docs/ | Contributor and user documentation (this page is contributors/website/+page.md) |
packages/web/src/lib/ | Shared Svelte components, marketing sections, and small utilities |
packages/web/vite.config.ts | Vite config, SveltePress theme, and documentation sidebar |
packages/lint-framework/ | Browser linting UI (underlines, popups) reused by the site and extensions |
packages/harper-editor/ | Embeddable Harper editor used on the homepage and /editor |
packages/components/ | Shared UI primitives consumed by the site and other packages |
packages/harper.js/ | JavaScript API over harper-wasm |
Documentation sidebar entries are defined in packages/web/vite.config.ts. When you add a new doc page, register it there so it appears in the left nav.
The recommended way to start a dev server:
just dev-web
This builds harper.js, lint-framework, components, and harper-editor, then runs pnpm dev in packages/web.
Open http://localhost:3000. Vite hot-reloads most edits to .svelte, .ts, and .md files automatically.
just build-webonly produces a production build; it does not start a dev server. Usejust dev-webwhen you want to preview changes interactively.
packages/web usually reload without restarting.packages/components, packages/harper-editor, or packages/lint-framework, rebuild that package (or re-run just dev-web).harper-wasm / harper-core, re-run just dev-web (or just build-harperjs) so the site picks up a new WASM build.From the repo root:
just build-harperjs build-lint-framework build-components build-harper-editor
cd packages/web
pnpm install
pnpm dev
| What you changed | Where to look |
|---|---|
| A documentation page | http://localhost:3000/docs/... (path mirrors src/routes/docs/...) |
| Homepage or marketing UI | http://localhost:3000/ |
| Live grammar demo / editor | http://localhost:3000/ (demo) or http://localhost:3000/editor |
| Rule catalog | http://localhost:3000/docs/rules |
| Weir studio | http://localhost:3000/weir/studio |
SveltePress doc pages support standard Markdown plus SveltePress features (admonitions, embedded code, etc.). Use an existing page under src/routes/docs/ as a template.
Each doc page has an Edit this page link (configured in vite.config.ts) that opens the matching file on GitHub.
You do not need deep Svelte expertise for many contributions.
src/routes/ map to URLs. +page.svelte is a page component; +page.md is a SveltePress doc page; +server.ts is a server endpoint.src/lib/. Import with $lib/... (SvelteKit alias).<script lang="ts"> holds component logic. Harper uses Svelte 5 (runes like $state appear in newer components).@tailwindcss/vite in vite.config.ts. Component-scoped <style> blocks are also used.Official references: Svelte tutorial, SvelteKit docs.
Before opening a pull request:
just format
just precommit
For website-focused checks:
cd packages/web
pnpm check
pnpm check runs svelte-check (TypeScript and Svelte diagnostics). The root just check recipe also runs pnpm check for the whole workspace and includes just build-web.
There is no dedicated website unit-test package today; rely on pnpm check, a manual click-through in the browser, and CI.
just build-web
cd packages/web
pnpm preview
Then open the URL printed by vite preview (defaults differ from dev; confirm in the terminal output).
Reviewers sometimes test grammar changes via the site demo using Docker (see also the review guide):
docker build . -q
docker run -p 3000:3000 -it <image-id>
You do not need Docker for everyday website UI or documentation work.
A few routes persist data with MariaDB via Drizzle ORM (for example uninstall feedback and problematic-lint reports). Local API work is optional:
docker compose -f docker-compose.dev.yml up from the repo root.DATABASE_URL for packages/web (see packages/web/drizzle.config.ts).src/hooks.server.ts).Most contributors never need this to change docs, marketing pages, or the public demo.
Merges to master trigger the Build Web workflow, which builds the root Dockerfile and publishes the site image. You do not need to deploy manually to test a pull request; maintainers handle production releases.
harper-core, harper.js, and integrations fit togetherharper.js documentation — if you are wiring lint behavior on the site