{"id":51580398,"url":"https://github.com/madojs/mado","last_synced_at":"2026-07-11T06:00:25.995Z","repository":{"id":363196907,"uuid":"1261985042","full_name":"madojs/mado","owner":"madojs","description":"A calm native-first web framework for sites and apps.","archived":false,"fork":false,"pushed_at":"2026-07-11T01:29:36.000Z","size":3260,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-11T03:12:47.644Z","etag":null,"topics":["admin-dashboard","crud","custom-elements","esm","forms","frontend-framework","html-templates","madojs","native-web","no-build","prerender","router","signals","spa","state-management","static-site-generation","typescript","vanilla-js","web-components","zero-dependencies"],"latest_commit_sha":null,"homepage":"https://madojs.dev","language":"JavaScript","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/madojs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-07T12:23:30.000Z","updated_at":"2026-07-11T01:29:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/madojs/mado","commit_stats":null,"previous_names":["madojs/mado"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/madojs/mado","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madojs%2Fmado","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madojs%2Fmado/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madojs%2Fmado/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madojs%2Fmado/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/madojs","download_url":"https://codeload.github.com/madojs/mado/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madojs%2Fmado/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35352623,"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-07-11T02:00:05.354Z","response_time":104,"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":["admin-dashboard","crud","custom-elements","esm","forms","frontend-framework","html-templates","madojs","native-web","no-build","prerender","router","signals","spa","state-management","static-site-generation","typescript","vanilla-js","web-components","zero-dependencies"],"created_at":"2026-07-11T06:00:17.233Z","updated_at":"2026-07-11T06:00:25.954Z","avatar_url":"https://github.com/madojs.png","language":"JavaScript","funding_links":["https://www.paypal.com/paypalme/tsekhmister"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg\n    src=\"./docs/assets/brand/mado-logo-light.png\"\n    alt=\"MadoJS\"\n    width=\"560\"\n  /\u003e\n\n  \u003cp\u003e\n    \u003cstrong\u003eA calm native-first web framework for sites and apps.\u003c/strong\u003e\n  \u003c/p\u003e\n\n  \u003cp\u003e\n    Web Components · Signals · Browser-rendered static snapshots · Zero runtime dependencies\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\n# Mado\n\n\u003e A calm native-first web framework for sites and apps.\n\n[![npm](https://img.shields.io/npm/v/@madojs/mado.svg)](https://www.npmjs.com/package/@madojs/mado)\n[![CI](https://github.com/madojs/mado/actions/workflows/ci.yml/badge.svg)](https://github.com/madojs/mado/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE)\n[![Donate: PayPal](https://img.shields.io/badge/Donate-PayPal-ff3f59.svg)](https://www.paypal.com/paypalme/tsekhmister)\n\nBuild with real Web Components, signals, routing, data and forms.\nShip live SPAs and browser-rendered static documents from one\ncomponent model.\n\n**One component model. One page model. One release command.**\n\nMado (`窓`) means *window* in Japanese: a calm window into your app,\nwithout dragging a whole frontend factory into the room.\n\n## What you get\n\n```txt\nMado component = Custom Element + open Shadow DOM\nMado page      = route + load + head + view + optional static declaration\nMado release   = Vite build\n               + browser-rendered static documents\n               + Declarative Shadow DOM\n               + SPA fallback\n               + deployment artifact\n\nClient activation = atomic takeover\n                  ≠ hydration\n                  ≠ SSR reconciliation\n```\n\nBrowser-native source, with Vite as the development and delivery\ntransport. No framework-specific compiler and zero runtime\ndependencies.\n\n## Use cases\n\n- Public landing pages\n- Documentation sites\n- Product / catalog pages\n- SaaS applications\n- Business applications\n- Admin panels and internal tools\n- Dashboards\n- Embedded widgets\n\n## Quick start\n\n```bash\nnpm exec --package @madojs/mado -- mado init my-app\ncd my-app\nnpm install\nnpm run dev\n```\n\nThe default starter is the universal starter: ~15 source files,\nrunnable without a backend, demonstrating one Shadow Component shared\nbetween a static landing page and a live SPA route.\n\nNeed the modular reference architecture (auth shell, guarded zones,\nbilling module, HTTP client, module boundaries)?\n\n```bash\nmado init my-app --starter modular\n```\n\n## The Mado way\n\n### Signals — reactive state\n\n```ts\nimport { signal, computed, effect } from \"@madojs/mado\";\n\nconst count = signal(0);\nconst doubled = computed(() =\u003e count() * 2);\neffect(() =\u003e console.log(count()));\n\ncount.set(1);\n```\n\n### Templates — tagged template html\n\n```ts\nhtml`\u003cbutton @click=${fn} ?disabled=${loading} class=${cls}\u003e${label}\u003c/button\u003e`;\n```\n\n- `${value}` — child content (text, nodes, arrays, nested `html`, `each`)\n- `@event=${fn}` — event listener\n- `attr=${v}` — attribute\n- `.prop=${v}` — DOM property\n- `?attr=${flag}` — boolean attribute\n- Functions and signals are tracked reactively\n\n### Components — real Web Components\n\n```ts\nimport { component, css, html } from \"@madojs/mado\";\n\ncomponent(\n  \"x-card\",\n  () =\u003e () =\u003e html`\u003csection\u003e\u003cslot\u003e\u003c/slot\u003e\u003c/section\u003e`,\n  {\n    styles: css`:host { display: block; padding: 1rem; }`,\n  },\n);\n```\n\nOpen shadow root, scoped styles, slots, attribute reactivity, a real\ncustom element under the hood. The same component renders inside the\nstatic snapshot via Declarative Shadow DOM and inside the live SPA via\ndirect DOM attachment.\n\n### Pages — `route + load + head + view`\n\n```ts\nimport { html, page } from \"@madojs/mado\";\n\nexport default page({\n  static: true,                                  // capture as HTML at release\n  title: \"Mado Keyboard\",\n  head: () =\u003e ({ description: \"A canonical product page.\" }),\n  view: () =\u003e html`\u003ch1\u003eWelcome\u003c/h1\u003e`,\n});\n```\n\n### Routing — explicit, code-split\n\n```ts\nimport { routes, routeUrl } from \"@madojs/mado\";\n\nexport default routes({\n  \"/\":            () =\u003e import(\"./pages/home.page\"),\n  \"/users/:id\":   () =\u003e import(\"./pages/user.page\"),\n  \"*\":            () =\u003e import(\"./pages/not-found.page\"),\n});\n\n// Internal links must be base-aware.\nhtml`\u003ca data-link href=${routeUrl(\"/users/42\")}\u003eUser\u003c/a\u003e`;\n```\n\nLazy loading, layout groups, query params, guards, hover prefetch,\nscroll restoration, error boundary, View Transitions, base-path\nawareness (Vite `base` → runtime `import.meta.env.BASE_URL`).\n\n### Data — resource + mutation\n\n```ts\nimport { resource, mutation, jsonFetcher } from \"@madojs/mado\";\n\nconst user = resource(\n  () =\u003e `/api/users/${userId()}`,\n  jsonFetcher\u003cUser\u003e(),\n  { staleTime: 60_000 },\n);\n\nconst save = mutation(api.saveUser, {\n  invalidates: [\"/api/users*\"],\n});\n```\n\nCache, loading/error state, abort, refresh, optimistic `mutate()`,\nglob-based invalidation. Lifecycle-aware inside components.\n\n### Forms — browser constraint validation\n\n```ts\nimport { useForm, html } from \"@madojs/mado\";\n\nconst form = useForm({\n  initial: { email: \"\", age: \"\" as number | \"\" },\n});\n\nhtml`\u003cform @submit=${form.onSubmit(save)}\u003e\n  \u003cinput name=\"email\" type=\"email\" required @input=${form.onInput} /\u003e\n  \u003cinput name=\"age\" type=\"number\" min=\"18\" @input=${form.onInput} /\u003e\n  \u003cbutton type=\"submit\"\u003eSave\u003c/button\u003e\n\u003c/form\u003e`;\n```\n\nHTML owns constraints and keyboard/form semantics; Mado supplies typed values,\nerrors, touched/dirty state and abortable async validation.\n\n### Static snapshots — SEO without SSR\n\n```bash\nmado release\n```\n\n`mado release` runs your app in a real Chromium and freezes the\nrendered HTML — including the Shadow DOM via Declarative Shadow DOM —\ninto one file per route. On first paint Mado atomically replaces the\nstatic tree with the live tree: no hydration protocol, no node\nreconciliation, no per-attribute diffing.\n\n- Real search engines see a fully rendered document.\n- Social preview bots see the canonical / og tags inside the raw HTML.\n- JS-disabled browsers see meaningful content.\n- The live app boots from the same snapshot without re-fetching seeded\n  data.\n\n## CLI\n\n```bash\nmado init my-app                  # scaffold universal starter\nmado init my-app --starter modular  # scaffold modular reference architecture\nmado dev                          # Vite dev server\nmado build                        # Vite production SPA build\nmado typecheck                    # tsc --noEmit\nmado static [--base-url …]        # low-level snapshot only\nmado release                      # vite build + snapshots + deployment files\nmado preview                      # serve out/ like a real static host\nmado new \u003ckind\u003e \u003cpath\u003e            # scaffold canonical files\n```\n\nAll CLI records share `level`, `scope`, `code`, `message`, `data` and a\ntimestamp. Use `--log-level`, `--log-format=pretty|plain|json`,\n`MADO_LOG_LEVEL`, `MADO_LOG_FORMAT` or `NO_COLOR` for automation.\n\n## Devtools\n\n```ts\nimport { devtools } from \"@madojs/mado/devtools.js\";\ndevtools.open();\n```\n\nThe development-only Shadow DOM overlay is toggled with `Alt+Shift+M` and\ninspects reactivity, components, routing, data and structured diagnostics.\n\n## Honest boundaries\n\n- No server renderer.\n- No hydration protocol.\n- No framework compiler.\n- No runtime dependencies.\n- No built-in backend.\n- No UI-kit marketplace.\n- Modern evergreen browsers only.\n- A compatible Chromium is required at release time for static routes.\n- Static `paths()` and `initialData()` callbacks must be browser-safe\n  and secret-free (they run during discovery AND ship in the client\n  bundle).\n\n## Why teams pick Mado\n\n| What matters to you | Best choice |\n|---|---|\n| Largest ecosystem, most hires available | React or Vue |\n| Reusable design-system components across host frameworks | Lit |\n| Maximum rendering performance, JSX workflow | Solid or Svelte 5 |\n| Progressive enhancement of server-rendered pages | htmx + your backend |\n| One component model for sites and apps with calm maintenance | **Mado** |\n\n## Production\n\n```bash\nmado release    # typecheck + vite build + static snapshots + deployment files\nmado preview    # serve out/ like a real static host\n```\n\nOne command, one artifact (`out/`). Upload anywhere: VPS, Cloudflare\nPages, GitHub Pages (with base), any static CDN.\n\n## Documentation\n\nCanonical docs (English) live in [`docs/en/`](./docs/en/README.md).\n\nAI-agent entrypoints: [AGENTS.md](./AGENTS.md) · [llms.txt](./llms.txt)\n\n## Tests\n\n```bash\nnpm run typecheck\nnpm run build\nnpm test\nnpm run size\nnpm run package:smoke\n```\n\nThe full snapshot + takeover round-trip and the base-path contract\nare required CI gates (`.github/workflows/ci.yml → static-snapshot`),\nrun under a pinned Playwright-managed Chromium with\n`MADO_REQUIRE_BROWSER=1` so they never silently skip on PRs.\n\n## Contributing\n\nRead [CONTRIBUTING.md](./CONTRIBUTING.md). Bug fixes with tests, docs\nimprovements, examples and carefully discussed core changes are\nwelcome. Runtime dependencies are not.\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadojs%2Fmado","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmadojs%2Fmado","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadojs%2Fmado/lists"}