Development
Prerequisites
- Node 20+
- pnpm (corepack handles this)
Setup
git clone https://github.com/stephansama/jabolcd jabolpnpm installpnpm install builds the native better-sqlite3 module, so the first
install pulls a small compile toolchain on macOS / Linux (already
present on most dev boxes).
Dev server
JABOL_CONFIG_PATH=./examples/categorized.json \ JABOL_DATA_DIR=./.data \ JABOL_AUTH_SECRET=dev-secret-at-least-32-characters \ pnpm devpnpm dev starts two processes concurrently:
- Hono server on
:8080(viatsx watch) — owns/api/*, better-auth, the file watcher, and the SSE event stream. - Vite SPA on
:5173— proxies/api/*to the Hono server, hot module reload for the React SPA.
Open http://localhost:5173 for the dev experience.
Repo layout
jabol/├── server/ # Hono backend (TypeScript, ESM)│ ├── enrich/ # links.json normalization + favicon/OG scraping│ ├── routes/ # API route handlers│ ├── state/ # canonical store + SSE + file watcher│ ├── middleware/ # requireAdmin│ └── index.ts # entrypoint├── src/ # React 18 SPA (Vite)│ ├── routes/ # /, /login, /signup, /admin│ ├── components/ # LinkCard, Icon, TopBar, AdminMenu, …│ ├── hooks/ # useLinks, useLinksSSE, useFuzzySearch, …│ └── lib/ # api client, types, helpers├── schema/ # generated JSON Schema (committed)├── examples/ # starter links.json files├── docs/ # this Starlight docs site└── scripts/ # generate-schema.tsSchema generation
The JSON Schema at schema/links.schema.json
is generated from server/enrich/schema.ts (the Zod source).
pnpm schema:generate # regenerate after editing the Zod sourcepnpm schema:check # CI guard — fails if the committed schema is out of dateCI runs schema:check on every PR.
Typecheck
pnpm typecheck # tsc --noEmit on both SPA and serverBuild for production
pnpm build # vite build + tsc on the serverpnpm start # node server-dist/index.jsDocs site
cd docs && pnpm install && pnpm dev # http://localhost:4321Or from the repo root: pnpm docs:dev / pnpm docs:build.
Releases
Pushes to main trigger Intuit Auto via .github/workflows/release.yml.
Auto reads PR labels (major, minor, patch, skip-release) to
bump the version, then triggers a Docker multi-arch build that pushes
to stephanrandle/jabol on Docker Hub.