{"id":50463845,"url":"https://github.com/ubugeeei-prod/vuerend","last_synced_at":"2026-06-01T06:03:50.783Z","repository":{"id":349608297,"uuid":"1199503364","full_name":"ubugeeei-prod/vuerend","owner":"ubugeeei-prod","description":"Vue.js Server Renderer (or Island, Server Component)","archived":false,"fork":false,"pushed_at":"2026-05-18T06:38:59.000Z","size":260,"stargazers_count":9,"open_issues_count":4,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-29T05:24:13.071Z","etag":null,"topics":["island-architecture","servercomponent","ssg","vue"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ubugeeei-prod.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-02T12:16:53.000Z","updated_at":"2026-05-29T03:10:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ubugeeei-prod/vuerend","commit_stats":null,"previous_names":["ubugeeei/vuerend","ubugeeei-prod/vuerend"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/ubugeeei-prod/vuerend","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubugeeei-prod%2Fvuerend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubugeeei-prod%2Fvuerend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubugeeei-prod%2Fvuerend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubugeeei-prod%2Fvuerend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ubugeeei-prod","download_url":"https://codeload.github.com/ubugeeei-prod/vuerend/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ubugeeei-prod%2Fvuerend/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33762215,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["island-architecture","servercomponent","ssg","vue"],"created_at":"2026-06-01T06:03:46.165Z","updated_at":"2026-06-01T06:03:50.757Z","avatar_url":"https://github.com/ubugeeei-prod.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vuerend Monorepo\n\nVuerend is a Zero JavaScript-first way to build Vue applications for MPAs. It treats server-rendered documents as the default unit, supports SSR and SSG out of the box, and keeps client JavaScript opt-in through explicit islands while the same fetch handler can run on Node, Bun, Deno, Cloudflare Workers, or service workers.\n\n## Why This Exists\n\n- Many Vue stacks assume a client router, route-level hydration, and a large baseline JavaScript payload even when the app mostly wants HTML documents.\n- Some teams want Vue as a rendering language for content sites, dashboards, documentation, storefronts, or internal tools without buying into an SPA-first architecture.\n- Some teams want an MPA-first model where SSR and SSG feel like the default, not like side modes hanging off a client app shell.\n- Runtime portability is usually bolted on later. Vuerend starts from a fetch-compatible handler so the app model stays the same across runtimes.\n- Interactivity still matters, but it should be narrow and intentional. Vuerend uses explicit islands so only the parts that need JavaScript hydrate.\n\n## Mental Model\n\n- Zero JavaScript is the baseline until you opt into an island.\n- Route components are server components by default.\n- There is no filesystem router and no client router included.\n- The default navigation model is MPA-style documents and links.\n- Add interactivity by rendering `defineIsland()` components inside a server-rendered page.\n- Start with `ssr` or `ssg`, then add `isr` only where freshness needs it.\n- Keep browser-only behavior explicit by importing client utilities from `@vuerend/core/client`.\n- Dynamic OG images can be authored as Vue SFCs and rendered through headless Chromium.\n\n## Workspace Layout\n\n- `packages/core`: the Vite plugin, runtime, islands implementation, middleware, document metadata, and client utilities\n- `packages/node`: Node adapter powered by `srvx/node`\n- `packages/bun`: Bun adapter\n- `packages/deno`: Deno adapter\n- `packages/cloudflare`: Cloudflare Worker adapter\n- `packages/service-worker`: service worker adapter\n\n## Example Tour\n\nRead the examples in this order if you want the clearest picture of the project motivation.\n\nEvery example now follows the same clean-room layout:\n\n- `README.md`: motivation and route map\n- `src/app.ts`: app contract and route table\n- `src/data/*`: scenario content\n- `src/routes/*`: route components\n- `src/islands/*`: optional client boundaries\n\n| Example                      | What Question It Answers                                                         | What It Demonstrates                                                                                     |\n| ---------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |\n| `examples/explicit-routes`   | What if I want a handbook or docs hub with Zero JavaScript by default?           | explicit route tables, server-only pages, shared metadata, social cards, `ssg` routes                    |\n| `examples/secure-islands`    | How do I ship a launch page that stays mostly static but still has live widgets? | explicit islands, targeted hydration, client-only forms, static sections living next to interactive ones |\n| `examples/mixed-sfc-jsx`     | Can a buying guide mix SFC pages, JSX islands, and MPA-friendly browser state?   | SFC + JSX together, `useClientState()`, page-to-page shared shortlist state                              |\n| `examples/isr-cache`         | How do I keep a release-notes home fresh while older entries stay static?        | `isr`, prerendered long-tail entries, route-level metadata                                               |\n| `examples/node-srvx`         | How does this fit into an existing Node support or admin process?                | middleware, request-scoped state, Node adapter entry                                                     |\n| `examples/cloudflare-worker` | Can the same app model ship cleanly to Cloudflare Workers?                       | Cloudflare Worker adapter, fetch-first deployment model, runtime portability                             |\n| `examples/social-cards`      | How do I generate dynamic social cards from Vue SFCs?                            | `defineImageRoute()`, Chromium-backed image rendering, route-owned OG metadata                           |\n\n## Commands\n\nFrom the repo root, use `vp` for the packages:\n\n```bash\nvp check\nvp test\nvp pack\nnode ./scripts/build-examples.mjs\nvp run release patch\n```\n\nRun any example from its own directory:\n\n```bash\ncd examples/explicit-routes\npnpm exec vite dev\n```\n\nExamples alias the workspace source directly, so they always exercise the in-repo implementation.\n\nThere is also a scenario-first index at [examples/README.md](examples/README.md).\n\n## Dynamic OG Images\n\nVuerend can render explicit image routes through Chromium, which makes it possible to author Open Graph cards as normal Vue SFC templates.\n\nAt the app level, pass an `imageRenderer` into `createRequestHandler()`. In Vite-powered apps, export `requestHandlerOptions` from the app module so the virtual server entry can pick it up automatically.\n\n```ts\n// src/app.ts\nimport HomeRoute from \"./routes/HomeRoute\";\nimport OgCardRoute from \"./routes/OgCardRoute.vue\";\nimport {\n  defineApp,\n  defineImageRoute,\n  defineRequestHandlerOptions,\n  defineRoute,\n} from \"@vuerend/core\";\nimport { createChromiumImageRenderer } from \"@vuerend/node\";\n\nexport const requestHandlerOptions = defineRequestHandlerOptions(() =\u003e ({\n  imageRenderer: createChromiumImageRenderer(),\n}));\n\nexport default defineApp({\n  routes: [\n    defineRoute({\n      path: \"/\",\n      component: HomeRoute,\n      head(context) {\n        const imageUrl = new URL(\"/og/home.png\", context.url).href;\n\n        return {\n          meta: [{ property: \"og:image\", content: imageUrl }],\n        };\n      },\n    }),\n    defineImageRoute({\n      path: \"/og/home.png\",\n      component: OgCardRoute,\n      getProps() {\n        return {\n          title: \"Hello from Vue SFC\",\n        };\n      },\n      head: {\n        stylesheets: [\"/styles/og.css\"],\n      },\n      image: {\n        width: 1200,\n        height: 630,\n      },\n    }),\n  ],\n});\n```\n\n```vue\n\u003c!-- src/routes/OgCardRoute.vue --\u003e\n\u003cscript setup lang=\"ts\"\u003e\ndefineProps\u003c{ title: string }\u003e();\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cmain class=\"og-card\"\u003e\n    \u003ch1\u003e{{ title }}\u003c/h1\u003e\n  \u003c/main\u003e\n\u003c/template\u003e\n```\n\nInstall Playwright in the app that renders the images, then download Chromium once:\n\n```bash\npnpm add -D playwright\npnpm exec playwright install chromium\n```\n\nThe explicit-routes example includes this pattern at [examples/explicit-routes/src/app.ts](examples/explicit-routes/src/app.ts).\n\n## Releases\n\nTag releases are driven by `vp run release ...`. Stable releases use `major`, `minor`, or `patch`. Pre-releases use `alpha`, `beta`, `rc`, and `allpha` is accepted as an alias for `alpha`.\n\n```bash\nvp run release patch\nvp run release alpha\n```\n\nThe command does this in one go:\n\n- runs release-file formatting checks, `vp test`, and `vp pack`\n- bumps every published package to the next shared version\n- creates `chore(release): vX.Y.Z`\n- creates and pushes the `vX.Y.Z` tag\n- lets GitHub Actions publish from that tag\n\nFor the very first publish, use local npm auth once and publish from your machine:\n\n```bash\nnpm login\nvp run release patch --publish=local\n```\n\nIf your npm account requires 2FA for publish, pass the OTP as well:\n\n```bash\nvp run release patch --publish=local --otp 123456\n```\n\nAfter that first publish succeeds, configure npm Trusted Publishing for each package on npm:\n\n- `@vuerend/core`\n- `@vuerend/node`\n- `@vuerend/bun`\n- `@vuerend/deno`\n- `@vuerend/cloudflare`\n- `@vuerend/service-worker`\n\nUse this GitHub repository and workflow file:\n\n- repository: `ubugeeei/vuerend`\n- workflow: `.github/workflows/publish.yml`\n\nOnce those trusted publishers are saved, future releases only need:\n\n```bash\nvp run release patch\n```\n\n## Where To Start\n\n- Start with `examples/explicit-routes` if the main appeal is “Zero JavaScript-first Vue for MPAs.”\n- Move to `examples/secure-islands` if the main appeal is “mostly static pages with tiny interactive pockets.”\n- Open `examples/mixed-sfc-jsx` if the sticking point is “I still need MPA-friendly client state for a few interactive islands.”\n- Read `examples/social-cards` if the main draw is “Chromium-backed OG cards authored as Vue.”\n- Read `packages/core/README.md` when you want the API surface rather than the motivation.\n\n## Documentation\n\nThe core package README lives at [packages/core/README.md](packages/core/README.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fubugeeei-prod%2Fvuerend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fubugeeei-prod%2Fvuerend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fubugeeei-prod%2Fvuerend/lists"}