Monorepo playground for comparing five UI approaches against one shared API, and for demonstrating a shared dev‑experience + CI/CD ecosystem:
/react/svelte/angular/htmx/vanilla-jsAll five frontends talk to the same Elysia + Bun backend and Notes data model, and they all share:
@josh803316/shared-configjosh803316/shared-ci-workflows@josh803316/semantic-release-helperflowchart LR
S[Server]
R[react app]
Sv[svelte app]
A[angular app]
H[htmx app]
VJ[vanilla-js app]
SC["@josh803316/shared-config"]
SRH["@josh803316/semantic-release-helper"]
ST["shared-test-automation"]
SCI["josh803316/shared-ci-workflows"]
VC[Vercel]
CL[Clerk]
GH[GitHub Actions]
S --> R
S --> Sv
S --> A
S --> H
S --> VJ
GH -. uses .-> SCI
SCI -. deploys .-> VC
SCI -. releases .-> GH
SRH -. config .-> GH
S --> CL
R --> CL
Sv --> CL
A --> CL
H --> CL
VJ --> CL
ST -. e2e tests .-> VC
At a glance:
uses:‑style reusable workflows in .github/workflows/*.yml.server/ - Elysia API, data access, auth/guards, HTMX routesreact/ - React + Vite clientsvelte/ - SvelteKit clientangular/ - Angular clienthtmx/ - HTMX frontend assets/templates (served by server)vanilla-js/ - Vanilla JS frontend (static HTML/CSS/ES modules, served by server)e2e-tests/ - Playwright e2e tests that treat the deployed app as a black boxEach SPA client has its own Storybook, wired to Chromatic and the
@github-ui/storybook-addon-performance-panel:
react/.storybook/* using @storybook/react-vitevue/.storybook/* using @storybook/vue3-vitesvelte/.storybook/* using @storybook/sveltekitangular/.storybook/*)From the repo root (after bun run install:all):
# React
cd react && bun run storybook
# Vue
cd ../vue && bun run storybook
# Svelte
cd ../svelte && bun run storybook
# Angular — disabled (see above)
# cd ../angular && bun run storybook
Each Storybook includes the ⚡ Performance panel via
@github-ui/storybook-addon-performance-panel (React) or the /universal
entry for the other frameworks.
For each framework, create a Chromatic project and configure the tokens as:
CHROMATIC_TOKEN_REACTCHROMATIC_TOKEN_VUECHROMATIC_TOKEN_SVELTECHROMATIC_TOKEN_ANGULARThese are consumed:
react/package.json → bun run chromatic).github/workflows/vercel-preview.yml, which runs Chromatic
for any app whose token is present after the Vercel preview build.Root helpers:
bun run chromatic:react
bun run chromatic:vue
bun run chromatic:svelte
# chromatic:angular — disabled
Each frontend exposes a route that embeds the Chromatic-hosted Storybook in an iframe:
/storybook/react (uses VITE_STORYBOOK_REACT_URL)/storybook/vue (uses VITE_STORYBOOK_VUE_URL)/storybook/react/storybook/vue/storybook/svelte/storybook/angular
(uses the corresponding VITE_STORYBOOK_*_URL vars)/storybook (expects window.ANGULAR_STORYBOOK_URL; Angular Storybook is currently disabled)When the environment value or global URL is missing, the route renders a hint explaining which variable to set.
@josh803316/shared-configeslint.config.js extends the shared ESLint setup.tsconfig.json extends the shared TypeScript config..husky/* scripts delegate to Husky hooks provided by @josh803316/shared-config.prettier.config.js imports the shared Prettier config.@josh803316/shared-config on GitHub Packages / npm (private GitHub-hosted package).josh803316/shared-ci-workflows.github/workflows/vercel-preview.ymlpreview job uses josh803316/shared-ci-workflows/.github/workflows/vercel-preview.yml@main to:bun run build.VERCEL_PROJECT_ID, VERCEL_ORG_ID via vars).linear job uses linear-pr-handler.yml@main to:.github/workflows/handle-pr-events.ymllinear-pr-handler.yml@main to:.github/workflows/release.ymldeploy job uses vercel-production.yml@main for production deploys to Vercel on pushes to main.uses: these shared definitions.josh803316/shared-ci-workflows on GitHub.@josh803316/semantic-release-helper.releaserc simply contains:"extends": "@josh803316/semantic-release-helper".github/workflows/release.yml:@josh803316/semantic-release-helper, @josh803316/shared-ci-workflows, and semantic-release via bun add in CI.bunx semantic-release with:SEMANTIC_RELEASE_PACKAGE=elysia-playground@josh803316/semantic-release-helper on GitHub Packages / npm.shared-test-automatione2e-tests/ exercises this app the same way other repos in the ecosystem are tested.e2e-tests/ align with what shared-test-automation provides.shared-test-automation on GitHub.Commits follow Conventional Commits. Linear ticket refs ([ELY-N]) are always optional — both forms are valid:
fix: [ELY-5] Fix the bug # with ticket
feat: Add new feature # without ticket
feat(scope): [ELY-12] New thing # with scope and ticket
When a commit or PR title contains an [ELY-N] ref, the CI automation handles Linear state transitions automatically:
| GitHub event | Linear ticket action |
|---|---|
| PR opened → Vercel preview deployed | → In Progress + preview URL posted as comment |
| PR converted to draft | → In Progress |
| PR marked ready for review | → In Review |
| PR review: changes requested | → In Progress |
Merged to main + release published |
→ Done |
Commits without ticket refs pass through all steps unchanged.
When running locally, the backend serves a root landing page at / linking to:
/react/svelte/angular/htmx/vanilla-js# Install root + workspace dependencies
bun run install:all
Create env files and fill values:
server/.envreact/.env (if needed for local overrides)svelte/.env (if needed for local overrides)angular/.env (if needed for local overrides)Typical required server values:
CLERK_SECRET_KEYCLERK_PUBLISHABLE_KEYCLERK_FRONTEND_API (e.g. ample-garfish-72.clerk.accounts.dev)ADMIN_API_KEYFor frontend Clerk usage:
VITE_CLERK_PUBLISHABLE_KEY (React/Svelte as needed)CLERK_PUBLISHABLE_KEY and CLERK_FRONTEND_API indirectly from server/.env via a small /vanilla-js/env.js helper and does not hardcode any keys in the static assets.# Run multiple apps (default)
bun run dev
# Targeted combinations
bun run dev:react
bun run dev:svelte
bun run dev:angular
bun run dev:htmx
bun run dev:vanilla-js
bun run dev:server
# Run all workspace tests
bun run test
# Run server-only tests
bun run test:server
# Build all workspaces
bun run build
# Build specific workspaces
bun run build:react
bun run build:svelte
bun run build:angular
bun run build:server
GET /api/public-notes - list public notesPOST /api/public-notes - create anonymous public noteGET /api/notes - list signed-in user notesPOST /api/notes - create user notePUT /api/private-notes - create private noteGET /api/private-notes - list private notes for signed-in userGET /api/notes/all - admin list all notes (X-API-Key)MIT