Skip to content

Repository files navigation

Tractorbeam Quickstart

A React starter for building polished demos quickly. It uses TanStack Start, React 19, TanStack Router and Query, shadcn/ui, Tailwind CSS v4, Drizzle ORM, Neon Postgres, a TanStack Form example, and an optional streaming AI chat example.

Features

  • React 19 with TypeScript
  • TanStack Start with file-based routing
  • TanStack Query for data fetching and caching
  • Server functions for type-safe server logic
  • Drizzle ORM, drizzle-zod, and Neon Postgres
  • Vite Plus with shared Tractorbeam Oxlint and Oxfmt configuration
  • Tailwind CSS v4 and shadcn/ui
  • TanStack Form with shadcn/ui fields and Zod validation
  • Optional AI SDK chat example using Anthropic Claude and Streamdown

Quick start

Requirements

  • Node.js 22.12 or newer
  • pnpm 10.18 or newer
  • A Neon database
  • An Anthropic API key if you want to run the chat example

Install and run

git clone https://github.com/tractorbeamai/quickstart.git
cd quickstart
pnpm install

Create .env.local with your database connection. Add the Anthropic key if you want to use the chat example:

DATABASE_URL=your_neon_connection_string
ANTHROPIC_API_KEY=your_key_here

Initialize the database and start the app:

pnpm db:push
pnpm dev

Open http://localhost:3000.

Deploy with Vercel

Deploy with Vercel

The deployment flow creates a Vercel project, clones the repository, and can provision a Neon database. Add ANTHROPIC_API_KEY when prompted if you are keeping the chat example.

Project structure

src/
├── components/
│   ├── ui/                # shadcn/ui components managed by the CLI
│   └── header.tsx         # Example navigation
├── db/                    # Drizzle client, schema, and seed data
├── lib/                   # Environment validation and utilities
├── routes/
│   ├── __root.tsx         # Root route
│   ├── index.tsx          # Home page
│   └── example/           # Chat, form, posts, and REST examples
├── server/                # Server functions
├── routeTree.gen.ts       # Generated route tree; do not edit
└── styles.css             # Global styles and Tailwind configuration

Commands

pnpm dev              # start the development server
pnpm build            # create a production build
pnpm check            # run formatting, lint, and type checks
pnpm format           # format the repository with Oxfmt
pnpm lint             # lint the repository with Oxlint
pnpm typecheck        # run TypeScript checks
pnpm lint:knip        # find unused code and dependencies
pnpm db:push          # sync the schema directly in development
pnpm db:generate      # generate database migrations
pnpm db:migrate       # apply database migrations
pnpm db:seed          # seed example data
pnpm db:studio        # open Drizzle Studio

Removing the AI chat features

The chat example is isolated from the posts, REST, database, and routing examples.

  1. Delete the chat routes and first-party shadcn chat components:

    rm src/routes/example/chat.tsx src/routes/example/api.chat.ts
    rm src/components/ui/bubble.tsx
    rm src/components/ui/message.tsx
    rm src/components/ui/message-scroller.tsx
  2. Remove the Chat navigation item from src/components/header.tsx.

  3. Remove ANTHROPIC_API_KEY from src/lib/env-server.ts and from your local and deployed environment variables.

  4. Delete the Streamdown @source line from src/styles.css and remove streamdown from ssr.noExternal in vite.config.ts. If the array is then empty, remove the entire ssr block.

  5. Remove the chat packages:

    pnpm remove @ai-sdk/anthropic @ai-sdk/react @shadcn/react ai streamdown
  6. Regenerate the route tree and verify the result:

    pnpm build
    pnpm check

src/routeTree.gen.ts is generated automatically during the build and should not be edited by hand.

Adding a route

Create a file in src/routes/ and export a file route:

import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/about")({
  component: AboutPage,
});

function AboutPage() {
  return <div>About</div>;
}

Styling

Use Tailwind classes and cn() for conditional class merging:

import { cn } from "@/lib/utils";

<div className={cn("rounded-lg border p-4", isActive && "border-primary")} />;

About

React starter template with TanStack Start, shadcn/ui, Drizzle, and Neon

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages