---
title: Contributing
label: Community
description: How to contribute to the Qwik Astro integration.
order: 7
---

## Quick start

Clone the repository and install dependencies:

```bash
git clone https://github.com/QwikDev/astro.git
cd astro
pnpm install
```

Note that we only use pnpm. Please don't make any PR's that introduce lock files of other package managers.

**dev:**

```bash
pnpm dev
```

**build:**

```bash
pnpm build
```

**preview:**

```bash
pnpm preview
```

## Project structure

This project is a pnpm workspace monorepo:

```
.
├── apps/
│   ├── demo/              # Standard Astro demo app
│   ├── deno-demo/         # Deno runtime demo
│   ├── node-demo/         # Node.js runtime demo
│   └── website/           # Documentation site
└── libs/
    └── qwikdev-astro/
        ├── src/
        │   ├── index.ts       # Integration entrypoint
        │   ├── constants.ts   # Configuration constants
        │   ├── plugins.ts     # Vite plugin helpers
        │   ├── scan.ts        # Entrypoint scanning
        │   └── types.ts       # TypeScript types
        ├── server.ts          # SSR renderer
        └── package.json
```

There are two major files to be aware of: `index.ts` and `server.ts`.

## index.ts

The integration entrypoint. It registers Qwik as an Astro renderer and configures the Vite plugins.

### Astro hooks

- **`astro:config:setup`** — Registers the Qwik renderer via `addRenderer()`, defines the `virtual:qwikdev-astro` virtual module for runtime render options, resolves source/build paths, and configures `qwikVite()` with file filters, entry points, and output directories. In build mode, it strips `outputOptions` from qwikVite so Astro controls output directories.

- **`astro:build:setup`** — Overrides Astro's `buildApp` to run the Qwik client build **before** prerender. Scans for Qwik entrypoints using `scanQwikEntrypoints()`, runs `runQwikClientBuild()` to produce the manifest, then calls the original Astro build.

### Why a separate build step?

Unlike other integrations, Qwik needs the client build manifest available during SSR. The `astro:build:setup` hook intercepts Astro's build pipeline to run `runQwikClientBuild()` first, which produces symbol-to-chunk mappings that the server renderer needs.

### Entrypoint discovery

`scanQwikEntrypoints()` in `scan.ts` uses `grep` to find files containing Qwik imports (matching `@qwik.dev/core`, `@qwik.dev/react`, or `.qwik.` patterns). It respects the `include`/`exclude` filter options.

## plugins.ts

### `createQwikManifestPlugin`

Virtual module plugin for `@qwik-client-manifest` that provides the manifest JSON from the standalone client build. Pre-enforced to override qwikVite's built-in manifest.

### `runQwikClientBuild`

Standalone Vite build just for Qwik client code. Runs before Astro's prerender in `astro:build:setup`. Takes scanned entrypoints, generates client bundles with symbols split, and captures the manifest via callback.

### `createAstroQwikPostPlugin`

Post-enforced plugin that undoes qwikVite's output directory overrides so Astro retains control of the final output structure.

## server.ts

The SSR renderer implementing Astro's renderer interface.

### `check`

Determines if a component is renderable by Qwik using `isQwikComponent()`.

### `renderToStaticMarkup`

Main rendering function called by Astro. Handles two component types:

- **Inline components** — Plain functions using Qwik JSX (detected by `_jsxSorted`, `_jsxSplit`, `_jsxQ`, `_jsxC`, `_jsxS` identifiers). Called directly with props.
- **Regular components** — `component$` wrapped components with serializable state. Converts Astro slots to Qwik format, creates element tree via `jsx()`, and calls `renderToStream()` with the manifest.

Uses `containerAttributes: { style: "display: contents" }` and `containerTagName: "div"`.

### Client Router support

Injects a script that handles Astro view transitions — resets Qwik state on `before-swap` and re-dispatches lifecycle events (`qinit`, `qidle`, `qvisible`) on `after-swap`.

## Code style

This project uses [Biome](https://biomejs.dev/) to lint and format all code.

- Run `pnpm run check` to verify code style
- Run `pnpm run fix` to auto-fix safe issues

When committing, an automatic git hook (via `lefthook`) checks staged files for linting and formatting errors. If there's an error, the commit will be aborted.

## Reporting issues

If you find a bug or have a feature request, please [open an issue](https://github.com/QwikDev/astro/issues) on GitHub.
