Getting Started

Manual Installation

Step-by-step guide to installing and configuring Taser manually with Vite, Nitro deployment presets, Next.js, and host pass-through dispatching.

If you have an existing project or prefer configuring dependencies manually without the create-taserjs wizard, this guide provides complete step-by-step instructions.

Taser is Vite-native by design. You can run Taser as a standalone server, pair it with Nitro for multi-cloud deployment presets, or enable Host Pass-Through to dispatch alongside existing frameworks.


1. Core Installation (Vite-Native Backend)

At its foundation, Taser operates as a Vite compiler plugin (@taserjs/router-plugin/vite). It turns your src/routes/ directory into virtual modules with instant Hot Module Replacement (HMR) and ambient TypeScript generation.

Install Core Dependencies

Install @taserjs/router, srvx, @taserjs/router-plugin, vite, and your preferred schema validator (such as zod):

pnpm add @taserjs/router srvx zod
pnpm add -D @taserjs/router-plugin vite

Configure package.json

Configure your project scripts:

package.json
{
  "name": "my-taser-app",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "start": "node dist/serve.mjs",
    "typecheck": "tsc --noEmit -p tsconfig.json"
  }
}

Configure TypeScript (tsconfig.json)

Include the .taser/types/**/*.d.ts directory so your editor receives ambient route autocomplete:

tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "strict": true,
    "skipLibCheck": true,
    "isolatedModules": true,
    "noEmit": true
  },
  "include": ["src", ".taser/types/**/*.d.ts"]
}

Configure vite.config.ts

Attach the taser() plugin to your Vite configuration:

vite.config.ts
import { defineConfig } from "vite";
import { taser } from "@taserjs/router-plugin/vite";

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

Create Router Instance & Context

Create src/context.ts for boot singletons and request-scoped state:

src/context.ts
import { createContext } from "@taserjs/router";

export const context = createContext({
  boot: () => ({
    logger: console,
  }),
  request: () => ({
    requestId: crypto.randomUUID(),
  }),
});

Create src/taser.ts for your app router:

src/taser.ts
import { createTaserApp } from "@taserjs/router";
import { context } from "./context.js";

export default createTaserApp({
  response: { validate: true },
}).context(context);

Add Your First Route

Create src/routes/index.get.ts:

src/routes/index.get.ts
import { json } from "@taserjs/router/reply";
import { t } from "@taserjs/router";

export default t.get("/").handler((ctx) => {
  return json({ message: "Welcome to Taser!", requestId: ctx.requestId });
});

Start the Vite development server:

pnpm dev

2. Adding Nitro for Multi-Cloud Deployment Presets

Nitro acts as the production deployment platform for Taser. By adding nitro() to your vite.config.ts, you can compile your Vite-native Taser application to Cloudflare Workers, Vercel, AWS Lambda, Bun, Deno, Netlify, or containerized Node servers with zero code changes.

Install Nitro

pnpm add -D nitro

Update vite.config.ts and Create nitro.config.ts

Chain nitro() alongside taser() in vite.config.ts:

vite.config.ts
import { defineConfig } from "vite";
import { nitro } from "nitro/vite";
import { taser } from "@taserjs/router-plugin/vite";

export default defineConfig({
  plugins: [taser(), nitro()],
});

Create nitro.config.ts to declare your target platform preset:

nitro.config.ts
import { defineConfig } from "nitro/config";

export default defineConfig({
  preset: "node-server", // or "cloudflare-module", "vercel", "aws-lambda", "bun", "deno-server"
});

Build and Run

pnpm dev                      # Vite dev server with instant HMR
pnpm build                    # Compiles production bundle to .output/
node .output/server/index.mjs # Starts production server

3. Host Pass-Through (Coexisting with Existing Frameworks)

Host Pass-Through is an Architectural Feature

Host Pass-Through is not a separate setup mode. It is a dispatch mechanism that works seamlessly with both Vite Standalone and Vite + Nitro.

If you have existing controllers or routes in a Web Standard framework (Hono, Elysia, HatTip, or custom fetch handlers) or a Node.js framework (Express, Fastify), you can keep them running alongside Taser:

  1. Taser First: Inbound requests are checked against src/routes/.
  2. Host Pass-Through: If no Taser file route matches, the request falls through directly to your exported host application.
  3. 404 Handling: If neither Taser nor the host handles the request, Taser returns a standard 404 response.

Create src/server.ts exporting your Fetch-native host app (e.g. Hono, Elysia, or custom fetch handler):

src/server.ts
import { Hono } from "hono";

const app = new Hono();

// Legacy or host endpoints:
app.get("/host-status", (c) => c.json({ framework: "Hono", status: "online" }));

export default app;

Next Steps