OneApp Docs
Guides

Quick Reference

Quick reference eliminates context-switching and speeds up development — providing instant access to copy-paste examples for all 35+ OneApp packages without reading full documentation.

Why quick reference matters

Without quick reference, developers waste time searching:

  • Context-switching overhead — Open multiple doc pages to find one function signature
  • Documentation overload — Package docs have 100+ lines, need 5 lines of code
  • Copy-paste friction — Can't quickly grab working examples for common tasks
  • Forgotten patterns — Keep forgetting server vs client imports, hooks, tool calling
  • Slow onboarding — New developers spend hours reading docs for simple tasks
  • API inconsistency — Different packages have different conventions, hard to remember

OneApp's quick reference provides concise cheat sheets for 10 most-used packages — covering AI chat (streaming, hooks, tool calling), authentication (sign in/out, RBAC, teams), analytics (event tracking, feature flags), SEO (metadata, structured data), file storage (upload, delete, presigned URLs), observability (logging, error tracking, AI tracing), database (CRUD, transactions), email (templates, batch), and security (rate limiting, bot detection).

Production-ready with copy-paste examples for every common task, server vs client import patterns clearly marked, error handling included in examples, TypeScript types with full IntelliSense, organized by package and task category, and common error fixes with solutions.

Use cases

Reference these cheat sheets to:

  • Implement features quickly — Copy-paste working code for auth, analytics, AI, storage
  • Avoid syntax errors — Get correct imports, function signatures, and patterns
  • Remember package conventions — See server vs client patterns at a glance
  • Debug import issues — Fix "Cannot find module" and "Session is undefined" errors
  • Speed up code reviews — Verify code follows correct patterns
  • Onboard faster — New developers get instant examples instead of reading docs

Quick Start

1. Find your package

Locate the package you need in the reference:

// Need AI chat?
→ See @repo/ai Quick Reference

// Need authentication?
→ See @repo/auth Quick Reference

// Need event tracking?
→ See @repo/analytics Quick Reference

// Need database queries?
→ See @repo/db-prisma Quick Reference

// Need file uploads?
→ See @repo/storage Quick Reference

That's it! Jump directly to the package section you need.

2. Copy the example

Copy-paste the example code and customize:

// From quick reference
import { useAuth } from "@repo/auth/client/next";
const { session } = useAuth();

// Customize for your needs
if (!session) {
  return <LoginPrompt />;
}
return <Dashboard user={session.user} />;

That's it! All examples are production-ready and include proper error handling.

3. Reference patterns

Check server vs client patterns:

// ✅ Server
import { auth } from "@repo/auth/server/next";
const session = await auth.api.getSession();

// ✅ Client
("use client");
import { useAuth } from "@repo/auth/client/next";
const { session } = useAuth();

That's it! You know which import to use in each context.

Complete package reference

All packages by category

AI & Generation

PackageCommon Tasks
@repo/ai →Chat streaming, React hooks, tool calling, model presets

Use when: Building AI chat, implementing tool calling, generating text

Authentication & Authorization

PackageCommon Tasks
@repo/auth →Sign in/out, session management, RBAC, teams, organizations

Use when: Implementing login, protecting routes, managing teams

Analytics & Tracking

PackageCommon Tasks
@repo/analytics →Event tracking, user identification, e-commerce events, feature flags

Use when: Tracking user behavior, implementing feature flags, measuring product metrics

SEO & Metadata

PackageCommon Tasks
@repo/seo →Page metadata, structured data, sitemaps, Open Graph tags

Use when: Optimizing SEO, adding Open Graph images, generating sitemaps

File Storage

PackageCommon Tasks
@repo/storage →File upload, multiple files, delete files, presigned URLs

Use when: Implementing file uploads, managing user assets, generating download links

Observability & Monitoring

PackageCommon Tasks
@repo/observability →Logging, error tracking, AI tracing, performance monitoring

Use when: Debugging issues, tracking errors, monitoring AI operations

Database & Data

PackageCommon Tasks
@repo/db-prisma →CRUD operations, queries, transactions, relations

Use when: Querying database, creating records, running transactions

Email & Communication

PackageCommon Tasks
@repo/email →Send email, batch emails, custom templates

Use when: Sending transactional emails, notifications, marketing campaigns

Security & Safety

PackageCommon Tasks
@repo/security →Bot detection, rate limiting, security headers

Use when: Protecting APIs, preventing abuse, securing endpoints

@repo/ai - AI SDK Quick Reference

Initialize Chat

import { Chat } from "@repo/ai/generation";

const stream = await Chat.stream(messages, {
  model: models.balanced,
  maxTokens: 500
});

for await (const chunk of stream.textStream) {
  console.log(chunk);
}

React Hook

"use client";
import { useChat } from "@repo/ai/ui/react";

const { messages, send, isLoading } = useChat({
  api: "/api/chat"
});

Model Presets

import { models } from "@repo/ai";

models.fast; // Quick responses
models.balanced; // Quality + speed
models.reasoning; // Deep thinking
models.vision; // Image understanding

Tool Calling

const tools = {
  getWeather: {
    description: "Get weather",
    inputSchema: z.object({ location: z.string() }),
    execute: async ({ location }) => {
      /* ... */
    }
  }
};

const result = await generateText({
  model: models.balanced,
  prompt: "What's the weather?",
  tools,
  maxSteps: 5
});

@repo/auth - Authentication Quick Reference

Setup

// app/providers.tsx
import { AuthProvider } from "@repo/auth/client/next";

export function Providers({ children }) {
  return <AuthProvider>{children}</AuthProvider>;
}

Get Session

// Server
import { auth } from "@repo/auth/server/next";
const session = await auth.api.getSession();

// Client
("use client");
import { useAuth } from "@repo/auth/client/next";
const { session } = useAuth();

Sign Up / Sign In

const { signUp } = useAuth();
await signUp({
  email: "user@example.com",
  password: "password",
  name: "John Doe"
});

const { signIn } = useAuth();
await signIn({ email, password });

Sign Out

const { signOut } = useAuth();
await signOut();

Check Permission

if (session.user.role === "admin") {
  // Admin-only content
}

Teams/Organizations

// Get user's organizations
const orgs = await auth.api.getUserOrganizations();

// Create organization
await auth.api.createOrganization({
  name: "My Company",
  slug: "my-company"
});

// Invite member
await auth.api.inviteMember({
  organizationId: "org_123",
  email: "colleague@example.com",
  role: "member"
});

@repo/analytics - Event Tracking Quick Reference

Setup

// app/providers.tsx
import { AnalyticsProvider } from "@repo/analytics/client/next";

export function Providers({ children }) {
  return (
    <AnalyticsProvider
      config={{
        providers: {
          posthog: {
            apiKey: process.env.NEXT_PUBLIC_POSTHOG_KEY!
          }
        }
      }}
    >
      {children}
    </AnalyticsProvider>
  );
}

Track Event

"use client";
import { useAnalytics, track } from "@repo/analytics/client/next";

const analytics = useAnalytics();

// Method 1: Direct
await analytics.track("Button Clicked", { button: "submit" });

// Method 2: Emitter (type-safe)
const event = track("Button Clicked", { button: "submit" });
await analytics.emit(event);

Identify User

analytics.identify(user.id, {
  email: user.email,
  plan: user.plan
});

E-commerce Events

import { productViewed, productAdded, orderCompleted } from "@repo/analytics/shared";

const viewed = productViewed({
  product_id: "123",
  name: "Product",
  price: 99.99,
});

const added = productAdded({
  product_id: "123",
  name: "Product",
  quantity: 1,
});

const order = orderCompleted({
  order_id: "ord_123",
  total: 99.99,
  products: [...],
});

Feature Flags

"use client";
import { useFeatureFlag } from "@repo/feature-flags/client";

const isEnabled = useFeatureFlag("new-feature");
if (isEnabled) {
  return <NewFeature />;
}

@repo/seo - SEO Quick Reference

Metadata

import { createMetadata } from "@repo/seo/server/next";

export const metadata = createMetadata({
  title: "Page Title",
  description: "Page description",
  image: "/og-image.jpg",
  canonical: "https://example.com/page"
});

Dynamic Metadata

export async function generateMetadata({ params }) {
  const product = await getProduct(params.id);

  return createMetadata({
    title: product.name,
    description: product.description,
    image: product.image
  });
}

Structured Data

import { JsonLd } from "@repo/seo/client/next";
import { structuredData } from "@repo/seo/server/next";

const schema = structuredData.product({
  name: "Product",
  price: 99.99,
  offers: {
    price: "99.99",
    priceCurrency: "USD"
  }
});

return <JsonLd data={schema} />;

Sitemap

// app/sitemap.ts
import { generateSitemapObject } from "@repo/seo/server/next";

export default async function sitemap() {
  const products = await getProducts();

  return generateSitemapObject([
    { url: "https://example.com", priority: 1 },
    ...products.map((p) => ({
      url: `https://example.com/products/${p.slug}`,
      priority: 0.8
    }))
  ]);
}

@repo/storage - File Upload Quick Reference

Upload File

"use client";
import { uploadFile } from "@repo/storage/client/next";

const file = new File([...], "image.jpg");
const { url, size } = await uploadFile({
  file,
  bucket: "images",
});

Multiple Files

import { uploadFiles } from "@repo/storage/client/next";

const files = [...fileList];
const results = await uploadFiles({
  files,
  bucket: "uploads"
});

Delete File

import { deleteFile } from "@repo/storage/server/next";

await deleteFile({
  bucket: "images",
  key: "image.jpg"
});

Presigned URL

import { getPresignedUrl } from "@repo/storage/server/next";

const url = await getPresignedUrl({
  bucket: "downloads",
  key: "file.pdf",
  expiresIn: 3600 // 1 hour
});

@repo/shared - Logging Quick Reference

Log Levels

import { logDebug, logInfo, logWarn, logError } from "@repo/shared";

logDebug("Debug message");
logInfo("Info message");
logWarn("Warning message");
logError(error, { context: "..." });
// Note: logFatal doesn't exist - use logError for fatal errors

Error Tracking

import { logError } from "@repo/shared";
import { getObservability } from "@repo/observability/server/next";

try {
  await riskyOperation();
} catch (error) {
  logError(error as Error, {
    context: "checkout"
  });
  const observability = await getObservability();
  observability.captureException(error as Error, {
    tags: { feature: "checkout" },
    extra: { userId: "123" }
  });
}

AI Tracing

import { traceAIOperation } from "@repo/observability/server/next";

const result = await traceAIOperation({ name: "chat-completion", model: "gpt-4" }, async (span) => {
  const response = await generateText({
    /* ... */
  });
  span.setAttributes({
    "ai.tokens.input": response.usage.promptTokens,
    "ai.tokens.output": response.usage.completionTokens
  });
  return response;
});

@repo/db-prisma - Database Quick Reference

Query

import { db } from "@repo/db-prisma";

// Find many
const users = await db.user.findMany();
const active = await db.user.findMany({
  where: { status: "active" },
  take: 10,
  skip: 0
});

// Find one
const user = await db.user.findUnique({
  where: { id: "user_123" }
});

Create

const user = await db.user.create({
  data: {
    email: "user@example.com",
    name: "John Doe"
  }
});

Update

const updated = await db.user.update({
  where: { id: "user_123" },
  data: { name: "Jane Doe" }
});

Delete

await db.user.delete({
  where: { id: "user_123" }
});

Transaction

const [user, post] = await db.$transaction([
  db.user.create({ data: { email: "user@example.com" } }),
  db.post.create({
    data: {
      title: "My Post",
      userId: "user_123"
    }
  })
]);

@repo/email - Email Quick Reference

Send Email

import { sendEmail } from "@repo/email";

await sendEmail({
  to: "user@example.com",
  subject: "Welcome!",
  template: "welcome",
  data: {
    name: "John"
  }
});

Send Batch

const recipients = ["user1@example.com", "user2@example.com"];

for (const email of recipients) {
  await sendEmail({
    to: email,
    subject: "Announcement",
    template: "announcement",
    data: {
      /* ... */
    }
  });
}

Custom Template

import { EmailLayout } from "@repo/email/components";

export default function CustomEmail({ name }) {
  return (
    <EmailLayout>
      <h1>Hello {name}</h1>
      <p>Welcome to our service</p>
    </EmailLayout>
  );
}

@repo/security - Security Quick Reference

Bot Detection

import { detectBot } from "@repo/security/server/next";

const isBot = await detectBot({
  ip: request.headers.get("x-forwarded-for"),
  userAgent: request.headers.get("user-agent")
});

if (isBot) {
  return new Response("Blocked", { status: 403 });
}

Rate Limiting

import { createRateLimiter } from "@repo/security/server/next";

const limiter = createRateLimiter({
  window: 60, // seconds
  limit: 10 // requests
});

const { allowed } = await limiter.check(userId);
if (!allowed) {
  return new Response("Rate limited", { status: 429 });
}

Security Headers

// middleware.ts
import { getSecurityHeaders } from "@repo/security/server/edge";

export async function middleware(request) {
  const response = NextResponse.next();
  const headers = await getSecurityHeaders();

  Object.entries(headers).forEach(([key, value]) => {
    response.headers.set(key, value);
  });

  return response;
}

Server vs Client Patterns

✅ Correct patterns

// ✅ Server
import { auth } from "@repo/auth/server/next";
import { observability } from "@repo/observability/server/next";
const session = await auth.api.getSession();

// ✅ Client
("use client");
import { useAuth } from "@repo/auth/client/next";
const { session } = useAuth();

❌ Common mistakes

// ❌ WRONG: Server import in client
"use client";
import { auth } from "@repo/auth/server/next"; // Error!

// ❌ WRONG: Client hook in server
import { useAuth } from "@repo/auth/client/next"; // Error!

// ❌ WRONG: Missing "use client"
import { useAuth } from "@repo/auth/client/next";
const { session } = useAuth(); // Error: Hooks only in client components

Development Shortcuts

TaskCommand
Quick lintpnpm lint --filter <app>
Type checkpnpm typecheck --filter <app>
Run testspnpm vitest --filter <app> --run
Format codepnpm format
Update packagespnpm update
Dev serverpnpm dev
Buildpnpm build --filter <app>
Prisma generatepnpm exec prisma generate
Add dependencypnpm --filter=<app> add <package>

Next steps

For Developers: Common error fixes and troubleshooting

Common Error Fixes

"Cannot find module"

Error: Error: Cannot find module '@repo/package-name'

Solution:

# 1. Make sure package is installed
pnpm add @repo/package-name

# 2. Clear cache and reinstall
rm -rf node_modules .turbo
pnpm install

# 3. Verify package exists in pnpm-workspace.yaml
cat pnpm-workspace.yaml

Why it happens: Package not in dependencies or pnpm workspace not configured correctly.

"Session is undefined"

Error: TypeError: Cannot read property 'user' of undefined

Solution:

// ✅ Client component with hook
"use client";
import { useAuth } from "@repo/auth/client/next";

export function Component() {
  const { session, isLoading } = useAuth();

  if (isLoading) return <Spinner />;
  if (!session) return <LoginPrompt />;

  return <div>Welcome {session.user.name};
}

// ✅ Server component with API
import { auth } from "@repo/auth/server/next";

export default async function Page() {
  const session = await auth.api.getSession();

  if (!session) redirect("/login");

  return <div>Welcome {session.user.name};
}

Why it happens: Using server import in client component or not checking loading state.

"Prisma client not found"

Error: Error: @prisma/client did not initialize yet

Solution:

# 1. Regenerate Prisma client
pnpm exec prisma generate

# 2. Check schema path (if custom)
pnpm exec prisma generate --schema=./prisma/schema.prisma

# 3. Verify Prisma in dependencies
cat package.json | grep prisma

# 4. Rebuild project
pnpm build

Why it happens: Prisma client not generated or schema path incorrect.

TypeScript errors with analytics

Error: Property 'track' does not exist on type 'Analytics'

Solution:

// ✅ Correct imports
import { track } from "@repo/analytics/shared"; // For type-safe events
import { useAnalytics } from "@repo/analytics/client/next"; // For hooks

// ✅ Usage
const analytics = useAnalytics();
const event = track("Button Clicked", { button: "submit" });
await analytics.emit(event);

Why it happens: Mixing server/client imports or importing from wrong path.

"Hydration mismatch" with auth

Error: Error: Hydration failed because the initial UI does not match what was rendered on the server

Solution:

// ❌ WRONG: useAuth in server component
export default function Page() {
  const { session } = useAuth(); // Error!
  return <div>{session?.user.name};
}

// ✅ CORRECT: Client component
("use client");
export default function Page() {
  const { session, isLoading } = useAuth();

  if (isLoading) return <Spinner />;
  if (!session) return <LoginPrompt />;

  return <div>{session.user.name};
}

Why it happens: Using client hooks in server components or not handling loading states.

"Rate limit exceeded"

Error: Error: Rate limit exceeded. Please try again later.

Solution:

import { createRateLimiter } from "@repo/security/server/next";

const limiter = createRateLimiter({
  window: 60,
  limit: 10
});

const { allowed, remaining, reset } = await limiter.check(userId);

if (!allowed) {
  return Response.json(
    {
      error: "Rate limit exceeded",
      retryAfter: reset,
      remaining: 0
    },
    { status: 429, headers: { "Retry-After": String(reset) } }
  );
}

Why it happens: Too many requests from same user/IP. Use rate limiter with proper headers.

"File upload failed"

Error: Error: Failed to upload file

Solution:

// ✅ Correct implementation
"use client";
import { uploadFile } from "@repo/storage/client/next";

async function handleUpload(file: File) {
  try {
    // 1. Validate file
    if (file.size > 10 * 1024 * 1024) {
      throw new Error("File too large (max 10MB)");
    }

    // 2. Upload with error handling
    const result = await uploadFile({
      file,
      bucket: "uploads"
    });

    // 3. Save URL to database
    await saveFileUrl(result.url);

    return result;
  } catch (error) {
    console.error("Upload failed:", error);
    throw error;
  }
}

Why it happens: File too large, invalid bucket, or network error. Always validate and handle errors.

"AI generation timeout"

Error: Error: Request timeout after 60000ms

Solution:

import { Chat } from "@repo/ai/generation";

const stream = await Chat.stream(messages, {
  model: models.balanced,
  maxTokens: 2000, // Limit tokens
  temperature: 0.7,
  abortSignal: AbortSignal.timeout(120000) // 2 minute timeout
});

for await (const chunk of stream.textStream) {
  console.log(chunk);
}

Why it happens: Request takes too long. Set reasonable timeout and token limits.

Debugging Tips

Enable verbose logging

# Environment variables for debugging
DEBUG=* pnpm dev                    # All debug logs
DEBUG=@repo/* pnpm dev              # Package logs only
LOG_LEVEL=debug pnpm dev            # Debug level logs

Check Prisma queries

// Enable query logging
const prisma = new PrismaClient({
  log: ["query", "info", "warn", "error"]
});

Monitor analytics events

"use client";
import { useAnalytics } from "@repo/analytics/client/next";

const analytics = useAnalytics();

// Log all events
analytics.on("track", (event) => {
  console.log("Tracked:", event);
});

Trace AI operations

import { traceAIOperation } from "@repo/observability/server/next";

const result = await traceAIOperation({ name: "operation", model: "gpt-4" }, async (span) => {
  span.setAttributes({ custom: "value" });
  console.log("Span ID:", span.spanContext().spanId);
  return await operation();
});

On this page

Why quick reference mattersUse casesQuick Start1. Find your package2. Copy the example3. Reference patternsComplete package referenceAI & GenerationAuthentication & AuthorizationAnalytics & TrackingSEO & MetadataFile StorageObservability & MonitoringDatabase & DataEmail & CommunicationSecurity & Safety@repo/ai - AI SDK Quick ReferenceInitialize ChatReact HookModel PresetsTool Calling@repo/auth - Authentication Quick ReferenceSetupGet SessionSign Up / Sign InSign OutCheck PermissionTeams/Organizations@repo/analytics - Event Tracking Quick ReferenceSetupTrack EventIdentify UserE-commerce EventsFeature Flags@repo/seo - SEO Quick ReferenceMetadataDynamic MetadataStructured DataSitemap@repo/storage - File Upload Quick ReferenceUpload FileMultiple FilesDelete FilePresigned URL@repo/shared - Logging Quick ReferenceLog LevelsError TrackingAI Tracing@repo/db-prisma - Database Quick ReferenceQueryCreateUpdateDeleteTransaction@repo/email - Email Quick ReferenceSend EmailSend BatchCustom Template@repo/security - Security Quick ReferenceBot DetectionRate LimitingSecurity HeadersServer vs Client Patterns✅ Correct patterns❌ Common mistakesDevelopment ShortcutsNext stepsCommon Error Fixes"Cannot find module""Session is undefined""Prisma client not found"TypeScript errors with analytics"Hydration mismatch" with auth"Rate limit exceeded""File upload failed""AI generation timeout"Debugging TipsEnable verbose loggingCheck Prisma queriesMonitor analytics eventsTrace AI operationsRelated documentation