---
title: Quickstart
sidebar:
  icon: rocket
description: Install the plugin, write a server, and run a production build with Vite or Rsbuild.
---

## Install

```package-install
npm i -D oxidejs
```

Extend the TypeScript config:

```json tsconfig.json
{ "extends": "oxidejs/tsconfig" }
```

## Add the plugin

Use [Vite](https://vite.dev/) or [Rsbuild](https://rsbuild.rs/). Same plugin, same output.

**Vite**

```ts twoslash vite.config.ts
import { defineConfig } from "vite";
import oxide from "oxidejs/vite";

export default defineConfig({
  plugins: [oxide()],
});
```

Add scripts to `package.json`:

```json package.json
{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  }
}
```

**Rsbuild**

```ts twoslash rsbuild.config.ts
// @noErrors
import { defineConfig } from "@rsbuild/core";
import oxide from "oxidejs/rsbuild";

export default defineConfig({
  plugins: [oxide()],
});
```

Add scripts to `package.json`:

```json package.json
{
  "scripts": {
    "dev": "rsbuild dev",
    "build": "rsbuild build",
    "preview": "rsbuild preview"
  }
}
```

## Write a server entry

```ts twoslash src/server.ts
export default {
  fetch(request: Request) {
    if (new URL(request.url).pathname === "/api/ok") {
      return new Response("ok");
    }
  },
};
```

Return `undefined` to fall through to static files. Missing files fall back to `index.html` only for navigations.

## Build and run

```sh
vite build
node dist/server.js
```

No `index.html` → only `dist/server.js`. With `index.html` → client assets in `dist/client/`. Files in `public/` land next to those assets.

## Common workflows

### celld

celld is a self-hosted alternative to Cloudflare Workers. It is not Cloudflare.

```ts twoslash
import oxide from "oxidejs/vite";

oxide({
  preset: "celld",
  wrangler: { name: "my-app", compatibility_date: "2026-01-01" },
});
```

[`preset: "celld"`](/oxide/configuration#preset) writes `dist/wrangler.jsonc` and skips asset serving (`ASSETS` does that). See [`wrangler`](/oxide/configuration#wrangler).

### Server only

Leave out `index.html`. The plugin emits `dist/server.js` and does not build a client.

## Next steps

- [Server entry](/oxide/server-entry) - `src/server.ts` and fallback
- [Server actions](/oxide/server-actions) - `*.server.ts` and tacho
- [Configuration](/oxide/configuration) - [`preset`](/oxide/configuration#preset), paths, [`wrangler`](/oxide/configuration#wrangler) keys
