{"id":19857453,"url":"https://github.com/qwikdev/astro","last_synced_at":"2026-02-04T22:03:36.662Z","repository":{"id":205139600,"uuid":"713498901","full_name":"QwikDev/astro","owner":"QwikDev","description":"@QwikDev 💜 @withastro integration","archived":false,"fork":false,"pushed_at":"2025-05-03T15:12:53.000Z","size":10855,"stargazers_count":253,"open_issues_count":4,"forks_count":15,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-15T12:02:03.350Z","etag":null,"topics":["astro","astro-integration","astro-template","cli-app","create-qwikdev-astro","javascript","jsx","qwik","qwikdev","qwikdev-astro","tsx","typescript","withastro"],"latest_commit_sha":null,"homepage":"https://qwik.dev/docs/integrations/astro/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/QwikDev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"contributing.md","funding":null,"license":null,"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}},"created_at":"2023-11-02T16:34:40.000Z","updated_at":"2025-05-14T22:15:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"1715c1f9-02ac-477d-af93-8d02952af8b3","html_url":"https://github.com/QwikDev/astro","commit_stats":{"total_commits":373,"total_committers":17,"mean_commits":"21.941176470588236","dds":"0.44772117962466484","last_synced_commit":"a44ad88c575051a8c78ea4ef516fbe5d603744dd"},"previous_names":["qwikdev/astro"],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QwikDev%2Fastro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QwikDev%2Fastro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QwikDev%2Fastro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QwikDev%2Fastro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/QwikDev","download_url":"https://codeload.github.com/QwikDev/astro/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254337612,"owners_count":22054253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["astro","astro-integration","astro-template","cli-app","create-qwikdev-astro","javascript","jsx","qwik","qwikdev","qwikdev-astro","tsx","typescript","withastro"],"created_at":"2024-11-12T14:18:42.945Z","updated_at":"2026-02-04T22:03:31.628Z","avatar_url":"https://github.com/QwikDev.png","language":"TypeScript","readme":"# @qwikdev/astro 💜\n\nThe Qwik Astro integration automatically optimizes your project thanks to [JavaScript Streaming](https://github.com/QwikDev/astro/blob/main/README.md#what-is-javascript-streaming).\n\nThis project is a result of a year-long effort by some [dedicated Astronauts](https://github.com/QwikDev/astro/issues/82) so that you can focus on the thing that matters: building your amazing website or app.\n\n## Installation\n\n### The `@qwikdev/astro` CLI 🦾\n\nTo start a new Qwik Astro project, you can run the following command:\n\n  - **With `NPM`**:\n\n    ```bash\n    npm create @qwikdev/astro@latest\n    ```\n\n  - **With `Yarn`**:\n\n    ```bash\n    yarn create @qwikdev/astro@latest\n    ```\n\n  - **With `PNPM`**:\n\n    ```bash\n    pnpm create @qwikdev/astro@latest\n    ```\n\n  - **With `Bun`**:\n\n    ```bash\n    bun create @qwikdev/astro@latest\n    ```\n\n  For more advanced CLI configuration options, see the [@qwikdev/astro CLI documentation](https://github.com/QwikDev/astro/blob/main/libs/create-qwikdev-astro/README.md).\n\n  \u003e The CLI is still in beta, if you encounter any problems, please [open an issue](https://github.com/QwikDev/astro/issues) and try one of the other methods below.\n\n### Have an existing project?\n\nTo install `@qwikdev/astro` in an existing project, run the following from your project directory and follow the prompts:\n\n```sh\n# Using NPM\nnpx astro add @qwikdev/astro\n\n# Using Yarn\nyarn astro add @qwikdev/astro\n\n# Using PNPM\npnpm astro add @qwikdev/astro\n```\n\n### Setting up the TypeScript Config (Existing or Manual)\n\nThe integration needs the following in `tsconfig.json` for typescript to recognize Qwik's JSX types.\n\n```ts\n\"compilerOptions\": {\n  \"jsx\": \"react-jsx\",\n  \"jsxImportSource\": \"@builder.io/qwik\"\n}\n```\n\n#### When Qwik isn't the primary jsxImportSource\n\nIf you don't intend to use Qwik as your primary `jsxImportSource`, add:\n\n```\n/** @jsxImportSource @builder.io/qwik */\n```\n\nat the top of each Qwik component file.\n\nThis is when you may not have that many Qwik components compared to other JSX frameworks on the page.\n\nIf you face any issues, [post them on Github](https://github.com/QwikDev/astro/issues) and attempt the manual installation below.\n\n### Manual Installation\n\nFirst, install the `@qwikdev/astro` integration like so:\n\n```sh\nnpm install @qwikdev/astro\n```\n\nTypically, package managers install peer dependencies. However, if you get a `Cannot find package '@builder.io/qwik'` warning when starting Astro, install Qwik.\n\n```sh\nnpm install @builder.io/qwik\n```\n\nNow, add the integration to your `astro.config.*` file using the `integrations` property:\n\n```diff lang=\"js\" \"qwikdev()\"\n  // astro.config.mjs\n  import { defineConfig } from 'astro/config';\n+ import qwikdev from '@qwikdev/astro';\n\n  export default defineConfig({\n    // ...\n    integrations: [qwikdev()],\n    //             ^^^^^\n  });\n```\n\n## Key differences\n\nBefore deep diving in, there are quite a few differences than other UI frameworks.\n\n## Qwik does not hydrate, it is **fundamentally different**\n\nAstro is popular for its partial hydration approach, whereas Qwik [does not require hydration](https://www.builder.io/blog/hydration-tree-resumability-map#resumability-is-fundamentally-a-different-algorithm).\n\n### Qwik components **do not need hydration directives**\n\nIn other UI frameworks, a hydration directive would be needed for interactivity, such as `client:only` or `client:load`. These are not needed with Qwik, because there is no hydration!\n\nWhen using Qwik inside a meta framework like Astro or Qwik City, components are loaded on the server, prefetched in a separate thread, and \"resumed\" on the client.\n\nFor example here's how to create a counter component in Qwik (e.g. at `src/components/counter.tsx`).\n\n```tsx\nimport { component$, useSignal } from \"@builder.io/qwik\";\n\nexport const Counter = component$(() =\u003e {\n  const counter = useSignal(0);\n\n  return \u003cbutton onClick$={() =\u003e counter.value++}\u003e{counter.value}\u003c/button\u003e;\n});\n```\n\nIt can be consumed in an `index.astro` page like so:\n\n```astro\n    ---\n    import { Counter } from \"../components/counter\";\n    ---\n\n    \u003chtml lang=\"en\"\u003e\n        \u003chead\u003e\n            \u003cmeta charset=\"utf-8\" /\u003e\n            \u003clink rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" /\u003e\n            \u003cmeta name=\"viewport\" content=\"width=device-width\" /\u003e\n            \u003cmeta name=\"generator\" content={Astro.generator} /\u003e\n            \u003ctitle\u003eAstro\u003c/title\u003e\n        \u003c/head\u003e\n        \u003cbody\u003e\n            \u003ch1\u003eAstro.js - Qwik\u003c/h1\u003e\n            /* no hydration directive! */\n            \u003cCounter /\u003e\n        \u003c/body\u003e\n    \u003c/html\u003e\n```\n\n![A gif showing a button clicked and the onClick$ resumed](https://i.imgur.com/unp1MRN.gif)\n\nThe above example refreshes the page, and notice nothing was executed until the button was clicked. Without resumability, the `\u003cCounter /\u003e` would have been executed on page load.\n\nThe 402 byte q-chunk is our Counter's `onClick$` handler.\n\n#### What's in that 17.61kb chunk?\n\nThe framework! It is not executed until needed. In this case it is gzipped using SSG.\n\n## Starts fast, stays fast\n\nOne of Astro's key features is **Zero JS, by default**. Unfortunately, after adding a JavaScript framework, and any subsequent components this is usually not the case.\n\nWhen introducing interactivity with a framework such as React, Vue, Svelte, etc., the framework runtime is then introduced. The number of components added to the page also increases linearly O(n) with the amount of JavaScript.\n\n### Astro + Qwik\n\nQwik builds on top of Astro's **Zero JS, by defaut** principle and then some. Thanks to resumability, the components are not executed unless resumed. Even with interactivity, the framework is also not executed until it needs to be. It is O(1) constant, and zero effort on the developer.\n\n![Resumability vs. Hydration chart](https://i.gyazo.com/3996e249ae856e12a1918ea389b399e6.webp)\n\nInstead, upon page load, a tiny 1kb minified piece of JavaScript, known as the [Qwikloader](https://qwik.builder.io/docs/advanced/qwikloader/), downloads the rest of the application as needed.\n\n### Fine-grained lazy loading\n\nHydration forces your hand [to eagerly execute code](https://www.builder.io/blog/hydration-sabotages-lazy-loading). It's not a problem with components that are outside of the tree, such as modals, but it must exhaustively check each component in the render tree just in case.\n\nQwik works well in Astro due to Resumability and its ability to lazy load code in a fine-grained manner. The moment JavaScript interactivity is involved, use Qwik. Some examples include marketing sites, blogs, content oriented sites, e-commerce applications, and even full-blown web-apps at scale.\n\n### Instant interactivity\n\nAs of `@qwikdev/astro` v0.4, there is support for [Speculative Module Fetching](https://qwik.builder.io/docs/advanced/speculative-module-fetching/) in Astro.\n\nThis enables instant interactivity for your Qwik components. Speculative module fetching will prefetch the application bundles in the background of a service worker, so that when needed, the code is already present in the browser cache.\n\n\u003e You should be able to use [Qwik insights](https://qwik.builder.io/docs/labs/insights/) out of the box!\n\n## Containers vs. Islands\n\nWhile Astro generally adopts an islands architecture with other frameworks, Qwik uses a different strategy known as [Qwik containers](https://qwik.builder.io/docs/advanced/containers/). Despite the differences in approach, both share similar limitations.\n\n![An example of a Qwik container](https://i.imgur.com/hJJtRHj.jpeg)\n\nIn the DOM, notice there aren't any `\u003castro-island\u003e` custom elements, this is because to Astro, Qwik looks like static data.\n\n\u003e In Qwik, the handlers themselves are the roots / entrypoints of the application.\n\n### Communicating across containers\n\nOne common limitation is trying to pass state into another island or container.\n\nSharing state is crucial in modern web development. The question is, how can we achieve this when state needs to be shared across different containers or islands?\n\n#### Why not use global signals or nanostores?\n\nOther frameworks with Astro address this by using [nano stores](https://github.com/nanostores/nanostores), or [global signals](https://www.solidjs.com/tutorial/stores_nocontext).\n\nWhile you may see all of your tests passing, and the application working as expected, we do not recommend using nanostores or global signals. They can lead to some unexpected behavior in an SSR context.\n\nFor example, in Solid's tutorial the following is mentioned:\n\n\u003e While it is possible to use global state and computations, Context is sometimes a better solution. Additionally, it is important to note that global state should not be used in SSR (server side rendering) solutions, such as Solid Start. On the server, global state is shared across requests, and the lack of data isolation can (and will) lead to bugs, memory leaks and has security implications. It is recommended that application state should always be provided via context instead of relying on global.\n\n#### Custom Events\n\nIn Qwik, it was a design decision to not include global signal state.\n\nInstead, use **custom events**, which offer several advantages:\n\n- Performance (avoid unnecessary state synchronization)\n- Does not wake up the framework on page load\n- Micro Frontend (MFE) Support\n- Different versions can exist on the page\n- Event Driven\n- Decoupled\n\n[This example](https://github.com/thejackshelton/astro-qwik-global-state-example/blob/main/src/components/counter.tsx) shows how custom events can be used throughout your application. Pay attention to `counter.tsx`, `random-island.tsx`, and the `index.astro` page.\n\n## Using multiple JSX frameworks\n\nTo use multiple JSX frameworks like Qwik, React, Preact, or Solid in Astro, you need to set up rules for which files each framework should handle.\n\nFor example, you can place all Qwik components in a folder named `qwik`. Then, configure Astro to process any file within this folder using the Qwik integration.\n\n```tsx\nimport { defineConfig } from \"astro/config\";\nimport qwik from \"@qwikdev/astro\";\nimport react from \"@astrojs/react\";\n\nexport default defineConfig({\n  integrations: [\n    qwik({ include: \"**/qwik/*\" }),\n    react({ include: \"**/react/*\" }),\n    solid({ include: \"**/solid/*\" }),\n  ],\n});\n```\n\nAbove the code snippet uses the Qwik, React, and Solid integrations in the same Astro project.\n\nThe first integration in the snippet above, looks for any file in the `qwik` folder and uses Qwik for any file in this folder.\n\nFor simplicity, consider grouping common framework components in the same folder (like `/components/react/` and `/components/qwik/`). However, this is optional.\n\n### Qwik React\n\nIf you're using React, use the [Qwik-React integration](https://qwik.dev/docs/integrations/react/). It's a drop-in replacement for `@astrojs/react`, and allows a seamless transition to Qwik.\n\n```tsx\nimport { defineConfig } from \"astro/config\";\n\nimport qwikdev from \"@qwikdev/astro\";\nimport { qwikReact } from \"@builder.io/qwik-react/vite\";\n\n// https://astro.build/config\nexport default defineConfig({\n  integrations: [qwikdev()],\n  vite: {\n    plugins: [qwikReact()],\n  },\n});\n```\n\nThe Qwik-React integration allows you to use React components directly in Qwik.\n\n\u003e You do not need to specify an include property with Qwik-React.\n\n[Here's an example](https://github.com/thejackshelton/qwik-react-astro-template) of a React component with the `qwik-react` integration.\n\n```tsx\n/** @jsxImportSource react */\nimport { qwikify$ } from \"@builder.io/qwik-react\";\nimport { useState } from \"react\";\n\nconst ReactCounter = () =\u003e {\n  const [count, setCount] = useState(0);\n\n  return \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003eReact {count}\u003c/button\u003e;\n};\n\n// \"Qwikified\" React component\nexport const QReactCounter = qwikify$(ReactCounter);\n```\n\nAfter creating our counter, it can be consumed in the [index.astro](https://github.com/thejackshelton/qwik-react-astro-template/blob/main/src/pages/index.astro) file.\n\n```tsx\n\u003cQReactCounter qwik:visible /\u003e\n```\n\nNotice that in `.astro` files there is a `qwik:` hydration directive prefix, this is to prevent a conflict with Astro's hydration directives that are provided out of the box.\n\nYou can also use the `client:*` prefix, but only in tsx files. You can find a list of directives in the Qwik-React [Adding Interactivity](https://qwik.builder.io/docs/integrations/react/#adding-interactivity) section of the Qwik docs.\n\n\u003e Qwik React components still have hydration. It is recommended to use Qwik-React as a migration strategy to resumable components.\n\n### jsxImportSource\n\nUnfortunately, TypeScript can only have one `jsxImportSource` default. If you're using React, Solid, or Preact's Astro integration in your Astro app alongside, please override each component's import source.\n\n\u003e If you're using [@astrojs/react](https://www.npmjs.com/package/@astrojs/react), you can use [qwik-react](https://qwik.builder.io/docs/integrations/react/#qwik-react-%EF%B8%8F) instead. The proper configuration will be supported out of the box.\n\n```tsx\n/** @jsxImportSource react */\nimport { useState } from \"react\";\n\nexport const ReactCounter = () =\u003e {\n  const [count, setCount] = useState(0);\n  return \u003cbutton onClick={() =\u003e setCount(count + 1)}\u003e{count}\u003c/button\u003e;\n};\n```\n\nSolid JS for example, is:\n\n```\n/** @jsxImportSource solid-js */\n```\n\nPreact for example, is:\n\n```\n/** @jsxImportSource preact */\n```\n\n## Named Slots\n\nFor named slots within Astro, instead of adding `q:slot` on the markup, add `slot` instead.\n\n**my-slot-comp.tsx**\n\n```tsx\nimport { Slot, component$, useSignal } from \"@builder.io/qwik\";\n\nexport const MySlotComp = component$\u003c{ initial: number }\u003e((props) =\u003e {\n  return (\n    \u003c\u003e\n      \u003cSlot name=\"test\" /\u003e\n    \u003c/\u003e\n  );\n});\n```\n\n**index.astro**\n\n```astro\n  \u003cMySlotComp\u003e\n    \u003cdiv slot=\"test\"\u003eContent inside the slot named test!\u003c/div\u003e\n  \u003c/MySlotComp\u003e\n```\n\n## Community Guides\n\n- [Embed Stackblitz in a performant way](https://thenewstack.io/how-to-build-embed-components-with-astro-qwik-and-stackblitz/)\n\n- [Build a Site Search with Astro, Qwik and Fuse.js](https://thenewstack.io/how-to-build-site-search-with-astro-qwik-and-fuse-js/)\n\n- [Qwik as a React alternative](https://thenewstack.io/take-a-qwik-break-from-react-with-astro/) in Astro.\n\n- [Deploy Qwik Astro with the Vercel SSR Adapter](https://dev.to/reeshee/qwik-look-at-resumability-with-astro-on-vercel-44fj).\n\n- [Netlify's Guide to starting a Qwik Astro project](https://developers.netlify.com/guides/adding-resumability-to-astro-with-qwik/)\n\n- [Using Qwik in Astro over React and Vanilla JS](https://thenewstack.io/how-quiks-astro-integration-beats-both-react-and-vanilla-js/).\n\n- [Initial @qwikdev/astro Alpha Post](https://www.builder.io/blog/astro-qwik)\n\n## Videos\n\n- Steve's [Qwik Astro announcement video](https://www.youtube.com/watch?v=LIKxkSzHqeo)\n\n- [Awesome's Qwik + Astro video](https://www.youtube.com/watch?v=wKvkYUNBa5k) goes into how Astro just got even faster.\n\n- Watch Jason \u0026 Steve [discuss the Qwik Astro integration](https://www.youtube.com/watch?v=W-j2HH1GdjU\u0026t=0s) on the [LWJ show](https://www.youtube.com/@learnwithjason).\n\n- [JLarky's insights on Qwik and potentially RSC in Astro](https://www.youtube.com/shorts/aaJuBrgQQDk)\n\n## Talks\n\n- [Astro and Qwik - a match made in performance heaven! - DevWorld 2024](https://www.youtube.com/watch?v=OSIjoqVK51o)\n- [Astro: A New Era of Effective Lazy Loading (fr)](https://www.youtube.com/watch?v=OgRfNfCMvvQ)\n\n## Contributing\n\nStart by reading our [Contributing Guide](https://github.com/QwikDev/astro/blob/main/contributing.md). It includes how to get involved, and an in-depth section on how the integration works under the hood.\n\n## Help\n\nIf you're stuck, reach out in the Astro discord or the [Qwik discord](https://discord.gg/p7E6mgXGgF), which has a dedicated [qwik-astro](https://discord.com/channels/842438759945601056/1150941080355881080) channel. Problems directly related to the integration can be created [as an issue](https://github.com/QwikDev/astro/issues).\n\n## Credits\n\n### Maintainers\n\n- [Jack Shelton](https://twitter.com/TheJackShelton)\n- [Sigui Kessé Emmanuel](https://twitter.com/siguici)\n\n### Astro Core Team\n\nSpecial thanks to Matthew and Nate from the Astro core team! This integration would not be possible without their help.\n\nMatthew's handles:\n- [Twitter](https://x.com/matthewcp)\n- [GitHub](https://github.com/matthewp)\n\nNate's handles:\n\n- [Twitter](https://twitter.com/n_moore)\n- [GitHub](https://github.com/natemoo-re)\n\n## FAQ \n\n### What is resumability?\n\nResumability is \"Lazy execution\", it's the ability to build the \"framework state\" (component boundaries, etc) on the server, and have it exist on the client without re-executing the framework again. \n\n\u003e This is in contrast to most frameworks, which will run the framework twice. Once on the server, and once on the client. (Hydration)\n\nHydration forces everything to be executed as the user visits the page. By avoiding hydration, we can execute code only when an interaction occurs. When combined with JavaScript Streaming, this results in a massive improvement in user experience.\n\n### What is JavaScript Streaming?\n\nJavaScript streaming is Resumability plus the ability to stream the functions into the browser and to buffer them in the cache.\n\nFunctions and Closures are automatically extracted by the Qwik Optimizer. You can think of it like uploading a video to Youtube. They are in charge of the video streaming and chunking that video into tiny packets for you automatically.\n\n### Where can I find Qwik UI components?\n\n[Jack](https://twitter.com/thejackshelton) also works on a UI library called [Qwik UI](https://github.com/Qwikifiers/qwik-ui).\n\n#### Headless\n\nIt has a headless library - similar to Radix UI, React Aria, Kobalte, Melt UI.\n\n#### Styled\n\nIt has a styled library using Tailwind CSS - which is inspired by Shadcn UI.\n\nThe philosophy is simple, the components are html until your users decide it's not, building on top of Astro's opt-in design principle.\n\n### Can I use it with React?\n\nYes! You can use it with React, but keep in mind those components will not get the benefits of JavaScript Streaming.\n\n### Can I use it with Qwik City?\n\nNo, Qwik City is an alternative meta-framework for Qwik.\n\n\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqwikdev%2Fastro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqwikdev%2Fastro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqwikdev%2Fastro/lists"}