Skip to main content

Overview

The monorepo uses Turborepo with pnpm workspaces. Each app in apps/ is independently deployable.

Step 1: Create App Directory

mkdir -p apps/new-app
cd apps/new-app

Step 2: Initialize Next.js

# Using create-next-app
pnpm create next-app . --typescript --tailwind --eslint --app --src-dir=false
Or manually create package.json:
{
  "name": "@trendingsociety/new-app",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "dev": "next dev -p 3003",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "typecheck": "tsc --noEmit"
  },
  "dependencies": {
    "@trendingsociety/db": "workspace:*",
    "@trendingsociety/ui": "workspace:*",
    "next": "14.x",
    "react": "18.x",
    "react-dom": "18.x"
  },
  "devDependencies": {
    "@trendingsociety/eslint-config": "workspace:*",
    "@trendingsociety/typescript-config": "workspace:*",
    "@types/node": "^20",
    "@types/react": "^18",
    "typescript": "^5"
  }
}

Step 3: Configure TypeScript

Create tsconfig.json:
{
  "extends": "@trendingsociety/typescript-config/nextjs.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}

Step 4: Configure ESLint

Create .eslintrc.js:
module.exports = {
  extends: ["@trendingsociety/eslint-config/next"],
};

Step 5: Create Basic Structure

apps/new-app/
├── app/
│   ├── layout.tsx
│   ├── page.tsx
│   └── globals.css
├── components/
├── lib/
├── package.json
├── tsconfig.json
├── next.config.js
└── tailwind.config.js

app/layout.tsx

import { Inter } from 'next/font/google'
import './globals.css'

const inter = Inter({ subsets: ['latin'] })

export const metadata = {
  title: 'New App | Trending Society',
  description: 'Description of new app',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
  )
}

app/page.tsx

import { supabase } from '@trendingsociety/db'

export default async function Home() {
  // Example: Fetch data from shared database
  const { data: users } = await supabase.from('users').select('count')
  
  return (
    <main className="min-h-screen p-8">
      <h1 className="text-4xl font-bold">New App</h1>
      <p>User count: {users?.[0]?.count ?? 0}</p>
    </main>
  )
}

Step 6: Configure Next.js

Create next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['@trendingsociety/ui', '@trendingsociety/db'],
}

module.exports = nextConfig

Step 7: Configure Tailwind

Create tailwind.config.js:
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
    '../../packages/ui/src/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Step 8: Add to Turborepo

Update root turbo.json if needed:
{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

Step 9: Install Dependencies

From repo root:
pnpm install

Step 10: Run Development

# From repo root
pnpm dev --filter=new-app

# Or run all apps
pnpm dev

Using Shared Packages

Database Access

import { supabase, type Database } from '@trendingsociety/db'

// Fully typed queries
const { data } = await supabase
  .from('publisher_posts')
  .select('*')
  .eq('status', 'published')

UI Components

import { Button, Card, Input } from '@trendingsociety/ui'

export function MyComponent() {
  return (
    <Card>
      <Input placeholder="Enter text" />
      <Button>Submit</Button>
    </Card>
  )
}

Adding App-Specific Tables

If your app needs new tables:
  1. Use domain prefix: newapp_table_name
  2. Create migration in supabase/migrations/
  3. Update SCHEMA.md
  4. Regenerate types
See Adding Tables for details.

Environment Variables

Create .env.local in app directory or use root .env.local:
# Shared variables are inherited from root
# App-specific variables go here
NEW_APP_SPECIFIC_KEY=value

Deployment

See Deployments for Vercel configuration.